MPAndroidChart 如何在同一图表行中表示具有不同点数的多个数据集对象

MPAndroidChart How to represent multiple dataset object with different number of points in the same chart line

我正在使用 MPAndroidChart 制作图表。我正在构建一个包含多个数据集对象的折线图。

从 MPAndroidChart 提供的示例中,我可以观察到可以在同一个折线图中绘制多个数据集对象,但具有相同数量的点(y 值)并且这些 y 值引用相同的 x 值.如果我想在同一个折线图中绘制多个数据集对象,每个对象的不同点数(y 值)引用不同的 x 值,会发生什么情况?我怎样才能摆脱这个?我做不到。

例如:

Dataset object 1 Y-values: 0, 12, 23, 34, 50, 100, 130
                 X-values: 0, 10, 15, 20, 25,  30,  35

Dataset object 2 Y-values: 1,  5, 10, 15, 20,  30,  40,  70, 75, 80
                 X-values: 0,  1,  2,  3,  4,   5,   6,   7,  8,  9

解决方法很简单。

创建一个范围从 0 到 36 的 x 值数组:

ArrayList<String> xvals = new ArrayList<String>();

for(int i = 0; i <= 35; i++) {
   xvals.add("Label"+i);
}

// create your entries...

// add the data...

通过这种方式,您可以显示 x 索引范围为 0 到 35 的条目。 确保为要显示的每个条目设置正确的 x-index。

不是创建 0 到 36 {min - max},而是创建 Xvalues1Xvalues2 的并集及其各自的 Yvalues & 反之亦然

int[] Xvalues1 = { 0, 10, 15, 20, 25, 30, 35 };
int[] Yvalues1 = { 5, 112, 23, 34, 50, 100, 130 };

int[] Xvalues2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10 };
int[] Yvalues2 = { 1, 5, 20, 15, 10, 30, 40, 70, 75, 100 };

// X = X1 ⋃ X2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20, 25, 30, 35]
// Y1 ⋃ Y2 (w.r.t X) = [5, null, null, null, null, null, null, null, null, 112, 23, 34, 50, 100, 130]

绘制 X 对 Y1、Y2、Y3 ...,

As far as I know MPAndroidChart doesn't plot null values & safely skips to next value.

public void startMerging() throws ArrayIndexOutOfBoundsException {

    List<Integer> x1 = new ArrayList<Integer>();
    List<Integer> y1 = new ArrayList<Integer>();

    List<Integer> x2 = new ArrayList<Integer>();
    List<Integer> y2 = new ArrayList<Integer>();

    List<XYMerger> mergedData = getMergedData(Xvalues1, Yvalues1, Xvalues2);

    for (XYMerger xy : mergedData) {
        x1.add(xy.getX());
        y1.add(xy.getY());
    }

    mergedData = getMergedData(Xvalues2, Yvalues2, Xvalues1);

    for (XYMerger xy : mergedData) {
        x2.add(xy.getX());
        y2.add(xy.getY());
    }

    mergedData.clear();

    System.out.println(x1); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20, 25, 30, 35]
    System.out.println(y1); // [5, null, null, null, null, null, null, null, null, 112, 23, 34, 50, 100, 130]

    System.out.println("\n");

    System.out.println(x2); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20, 25, 30, 35] // X = X1 = X2
    System.out.println(y2); // [1, 5, 20, 15, 10, 30, 40, 70, 75, 100, null, null, null, null, null]


}

/**
 * @param orgXvals : Original X Values
 * @param orgYvals : Original Y Values
 * @param extdXvals : Extended X values to be merged
 * @return Sorted mergedData
 */
private List<XYMerger> getMergedData(int[] orgXvals , int[] orgYvals , int[] extdXvals) {

    HashSet<Integer> tempSet = new HashSet<Integer>();
    List<XYMerger> tempMerger = new ArrayList<XYMerger>();

    tempSet.clear();
    tempMerger.clear();

    for (int i = 0; i < orgXvals.length; i++) {
        tempSet.add(orgXvals[i]);
        XYMerger xy = new XYMerger();
        xy.setX(orgXvals[i]);
        xy.setY(orgYvals[i]);
        tempMerger.add(xy);
    }

    for (int i = 0; i < extdXvals.length; i++) {
        if (tempSet.add(extdXvals[i])) {
            XYMerger xy = new XYMerger();
            xy.setX(extdXvals[i]);
            xy.setY(null);
            tempMerger.add(xy);
        }
    }
    Collections.sort(tempMerger, new IntegerComparator(true));
    return tempMerger;
}

XYMerger

public class XYMerger {

    int x;
    Integer y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public Integer getY() {
        return y;
    }

    public void setY(Integer y) {
        this.y = y;
    }

}

整数比较器

public class IntegerComparator implements java.util.Comparator<XYMerger> {

    boolean ascending;

    public IntegerComparator(boolean isAscending) {
        this.ascending = isAscending;
    }

    @Override
    public int compare(XYMerger obj1 , XYMerger obj2) {
        if (ascending) {
            return (obj1.getX() < obj2.getX() ? -1 : (obj1.getX() == obj2.getX() ? 0 : 1));
        }
        return (obj1.getX() > obj2.getX() ? -1 : (obj1.getX() == obj2.getX() ? 0 : 1));
    }

}