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},而是创建 Xvalues1
和 Xvalues2
的并集及其各自的 Yvalue
s & 反之亦然。
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));
}
}
我正在使用 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},而是创建 Xvalues1
和 Xvalues2
的并集及其各自的 Yvalue
s & 反之亦然。
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));
}
}