在 MPAndroidChart 中显示单个 x 的多个 y 值
Displaying multiple y values for a single x in MPAndroidChart
对于折线图,我发现如果单个 x 有多个 y 值,只要它不是最终的 x,它就可以正常工作。如果它是最后一个 x,它只显示第一个条目。是否有已知的解决方法?
示例:
//firstTimestamp is earlier than secondTimestamp
data.add(new Entry(firstTimestamp, 10));
data.add(new Entry(firstTimestamp, 20)); //won't show unless you uncomment below
data.add(new Entry(firstTimestamp, 30)); //won't show unless you uncomment below
//data.add(new Entry(secondTimestamp, 40));
第二个时间戳被注释掉时的图表:
第二个时间戳未注释的图表(请注意,现在包括 20 和 30,而之前不包括):
编辑:
我相信我已经找到了这个问题的原因并且可以通过以下方式解决它,方法是更改
public abstract class BarLineScatterCandleBubbleRenderer extends DataRenderer {
// ... lines removed ... //
public void set(BarLineScatterCandleBubbleDataProvider chart, IBarLineScatterCandleBubbleDataSet dataSet) {
float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
float low = chart.getLowestVisibleX();
float high = chart.getHighestVisibleX();
Entry entryFrom = dataSet.getEntryForXValue(low, Float.NaN, DataSet.Rounding.DOWN);
Entry entryTo = dataSet.getEntryForXValue(high, Float.NaN, DataSet.Rounding.UP);
min = entryFrom == null ? 0 : dataSet.getEntryIndex(entryFrom);
max = entryTo == null ? 0 : dataSet.getEntryIndex(entryTo);
range = (int) ((max - min) * phaseX);
}
// ... lines removed ... //
}
至此,我相信这将解决问题:
public abstract class BarLineScatterCandleBubbleRenderer extends DataRenderer {
// ... lines removed ... //
public void set(BarLineScatterCandleBubbleDataProvider chart, IBarLineScatterCandleBubbleDataSet dataSet) {
float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
float low = chart.getLowestVisibleX();
float high = chart.getHighestVisibleX();
Entry entryFrom = dataSet.getEntryForXValue(low, Float.NaN, DataSet.Rounding.DOWN);
//my edits here
int indexTo = dataset.getEntryIndex(high, Float.NaN, DataSet.Rounding.UP);
List<Entry> values = dataset.getValues();
while (indexTo + 1 < values.size() && values.get(indexTo + 1).getX() == high) {
indexTo++;
}
Entry entryTo = values.get(indexTo);
//my edits end here
min = entryFrom == null ? 0 : dataSet.getEntryIndex(entryFrom);
max = entryTo == null ? 0 : dataSet.getEntryIndex(entryTo);
range = (int) ((max - min) * phaseX);
}
// ... lines removed ... //
}
如何子类化/使用这些编辑?
请注意,LineChart
个条目唯一支持的用例是添加它们按顺序升序。这记录在 the wiki:
Please be aware that this library does not officially support drawing LineChart data from an Entry list not sorted by the x-position of the entries in ascending manner.
这是因为渲染器针对独特的升序条目进行了优化。
如果您想解决这个问题,我建议您查看 LineChartRenderer
的源代码。您将必须放置断点并找到导致它以您演示的方式呈现的问题。然后您可以考虑将渲染器子类化以满足您的要求。本质上,您将删除优化以支持额外的用例(non-unique 值)。
编辑:如果您不愿意操纵现有的对象图来获得您想要的行为,您可能需要考虑通过更改来分叉库。然后你可以构建一个 .jar
你的分支并将它包含在你的 Android 项目中。请参阅以下答案中的说明:
How to make a .jar from an Android Studio project
How to add a .jar as a library in Android Studio
对于折线图,我发现如果单个 x 有多个 y 值,只要它不是最终的 x,它就可以正常工作。如果它是最后一个 x,它只显示第一个条目。是否有已知的解决方法?
示例:
//firstTimestamp is earlier than secondTimestamp
data.add(new Entry(firstTimestamp, 10));
data.add(new Entry(firstTimestamp, 20)); //won't show unless you uncomment below
data.add(new Entry(firstTimestamp, 30)); //won't show unless you uncomment below
//data.add(new Entry(secondTimestamp, 40));
第二个时间戳被注释掉时的图表:
第二个时间戳未注释的图表(请注意,现在包括 20 和 30,而之前不包括):
编辑:
我相信我已经找到了这个问题的原因并且可以通过以下方式解决它,方法是更改
public abstract class BarLineScatterCandleBubbleRenderer extends DataRenderer {
// ... lines removed ... //
public void set(BarLineScatterCandleBubbleDataProvider chart, IBarLineScatterCandleBubbleDataSet dataSet) {
float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
float low = chart.getLowestVisibleX();
float high = chart.getHighestVisibleX();
Entry entryFrom = dataSet.getEntryForXValue(low, Float.NaN, DataSet.Rounding.DOWN);
Entry entryTo = dataSet.getEntryForXValue(high, Float.NaN, DataSet.Rounding.UP);
min = entryFrom == null ? 0 : dataSet.getEntryIndex(entryFrom);
max = entryTo == null ? 0 : dataSet.getEntryIndex(entryTo);
range = (int) ((max - min) * phaseX);
}
// ... lines removed ... //
}
至此,我相信这将解决问题:
public abstract class BarLineScatterCandleBubbleRenderer extends DataRenderer {
// ... lines removed ... //
public void set(BarLineScatterCandleBubbleDataProvider chart, IBarLineScatterCandleBubbleDataSet dataSet) {
float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
float low = chart.getLowestVisibleX();
float high = chart.getHighestVisibleX();
Entry entryFrom = dataSet.getEntryForXValue(low, Float.NaN, DataSet.Rounding.DOWN);
//my edits here
int indexTo = dataset.getEntryIndex(high, Float.NaN, DataSet.Rounding.UP);
List<Entry> values = dataset.getValues();
while (indexTo + 1 < values.size() && values.get(indexTo + 1).getX() == high) {
indexTo++;
}
Entry entryTo = values.get(indexTo);
//my edits end here
min = entryFrom == null ? 0 : dataSet.getEntryIndex(entryFrom);
max = entryTo == null ? 0 : dataSet.getEntryIndex(entryTo);
range = (int) ((max - min) * phaseX);
}
// ... lines removed ... //
}
如何子类化/使用这些编辑?
请注意,LineChart
个条目唯一支持的用例是添加它们按顺序升序。这记录在 the wiki:
Please be aware that this library does not officially support drawing LineChart data from an Entry list not sorted by the x-position of the entries in ascending manner.
这是因为渲染器针对独特的升序条目进行了优化。
如果您想解决这个问题,我建议您查看 LineChartRenderer
的源代码。您将必须放置断点并找到导致它以您演示的方式呈现的问题。然后您可以考虑将渲染器子类化以满足您的要求。本质上,您将删除优化以支持额外的用例(non-unique 值)。
编辑:如果您不愿意操纵现有的对象图来获得您想要的行为,您可能需要考虑通过更改来分叉库。然后你可以构建一个 .jar
你的分支并将它包含在你的 Android 项目中。请参阅以下答案中的说明:
How to make a .jar from an Android Studio project
How to add a .jar as a library in Android Studio