I have searching a lot on Internet but I have not found a solution to my problem.
The issue is the following: I'm trying to make a Combined chart, in which there is a LineChart and a BarChart.
When I have, for example, these values, it works fine:
double[] valuesXaxisGraph1 = new double[]{1,2,3,4,5};
double[] dataGraph1 = new double[]{5,5,5,5,5};
double[] valuesXaxisGraph2 = new double[]{1,2,3,4,5}
double[] dataGraph2 = new double[]{6,6,6,6,6};
The graph created is the following:
However, if I use these values:
double[] valuesXaxisGraph1 = new double[]{1,2,3,4,5,6,7,8,9,10};
double[] dataGraph1 = new double[]{5,5,5,5,5,5,5,5,5,5};
double[] valuesXaxisGraph2 = new double[]{1,2,3,4,5};
double[] dataGraph2 = new double[]{6,6,6,6,6};
The graph shown is the following:
As you can see, the bars appears from 1 to 10, instead from 1 to 5. Because of that, these bars aren't positioned where they should be (1, 2, 3, 4...).
Why is happening this? What should I do to fix it?
Thanks in advance.
You can set the range for the second scale to be the same for the first scale. For instance, for setting the X axis maximum value, you would do:
renderer.setXAxisMax(renderer.getXAxisMax(0), 1);
Related
I am facing some weird problems with my (Line) GraphView!
To explain it a bit better I'll add a pic that shows what happens when I start scrolling horizontal (vertical scrolling is not needed).
The thing is:
The DataPoints are displayed correctly, but not my labels! I wrote the correct label in red color into the pictures above!
Whenever I start scrolling the labels start to "jump" around weirdly.
The DataPoints are received from a SharedPreference file with String/Integer pairs [Strings are always MMMyyyy (f.e. "Mar2020")]
I get the pairs out of my SP-file, put the Strings as static labels into my graph use the DataPoints in this way "logical" way (not the actual code!)
DataPoint[0] = (0, valueOfKey0)
DataPoint[1] = (1, valueOfKey1)
Here is the code how the graph is called for / drawn in the Activity
private void setupGraph(final GraphView graph, String subName){
GraphDataHelper graphDataHelper = new GraphDataHelper(mContext);
LineGraphSeries<DataPoint> series;
/*Have to call .removeAllSeries to draw each graph individually
* Otherwise they will be drawn over another!*/
graph.removeAllSeries();
/*Gets Values from each Sub
* --> Gets values form each key/value pair of specific SharedPreference-file
* --> sets values in order (0, 1, 2,... n)*/
series = new LineGraphSeries<DataPoint>(graphDataHelper.generateGraphData(subName));
series.setDrawDataPoints(true);
series.setColor(getResources().getColor(R.color.casualWhite));
series.setAnimated(true);
graph.addSeries(series);
/*Fill Labels for X-Axis:
* Get the specific Monthly-Keys for the choosen Sub
* In special cases extra rules are declared in .getSpecificSubMonthKeys() method
* Put all entries of ArrayList in Array (StaticLabelsFormatter only works with "normal" Array)*/
ArrayList<String> array_paths = graphDataHelper.getSpecificSubMonthKeys(subName);
int size = array_paths.size();
String[] paths = new String[size];
for (int i=0; i<size; i++){
paths[i] = array_paths.get(i);
}
StaticLabelsFormatter staticLabelsFormatter = new StaticLabelsFormatter(graph);
staticLabelsFormatter.setHorizontalLabels(paths);
graph.getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter);
graph.getViewport().setXAxisBoundsManual(true);
if(size == 5 || size > 5){
graph.getViewport().setMinX(0.0);
graph.getViewport().setMaxX(4.0);
graph.getGridLabelRenderer().setNumHorizontalLabels(5);
} else if(size == 4){
graph.getViewport().setMinX(0.0);
graph.getViewport().setMaxX(3.0);
graph.getGridLabelRenderer().setNumHorizontalLabels(4);
} else if(size == 3){
graph.getViewport().setMinX(0.0);
graph.getViewport().setMaxX(2.0);
graph.getGridLabelRenderer().setNumHorizontalLabels(3);
} else if(size == 2){
graph.getViewport().setMinX(0.0);
graph.getViewport().setMaxX(1.0);
graph.getGridLabelRenderer().setNumHorizontalLabels(2);
}
graph.getViewport().setScrollable(true);
graph.getGridLabelRenderer().setHorizontalLabelsColor(getResources().getColor(R.color.midBlue));
graph.getGridLabelRenderer().setVerticalLabelsColor(getResources().getColor(R.color.midBlue));
graph.getGridLabelRenderer().setGridColor(getResources().getColor(R.color.darkBlue));
graph.getGridLabelRenderer().setPadding(50);
graph.getGridLabelRenderer().setLabelsSpace(30);
I call for .removeAllSeries because the User is able to call for another graph via a dropdown-Spinner.
Also I set different MinX & MaxX Points because there can be the case that an entry doesn't have 5 DataPoints yet and so I change the Viewport in regard of that (didn't find a better solution for that so I am also open for some better code here, but it does work this way). My SharedPreference-file always has a minimun of 2 key/value pairs
Also little extra question: Is there a way to give ONLY the horizontal labels some extra labelspace. If I use setLabelSpace it will also apply on the vertical labels and I do not want that. But the horizontal labels are just so close to the axis.
Also sorry for ugly code. It was my first time using GraphView!
Thanks ahead!
I’m using the MPAndroidChart for my project and I have the problem with that.
It’s look like, every time, when I set new data on BarChart View, even if i use clear() method, some of the reason, created left padding. plz, how can i fixed that?
We also have the same problems. Obviously, method clear() dosen’t zero array of values YAxis. Also, method computeAxisValues(float min, float max) dosen’t check when length old array of values the YAxis is bigger then count of new values.
In your case, when you switch from Chart3 to Chart1, in first:
yAxis.mEntries = [0, 2000, 4000, 6000, 8000, 10000, 12000, 14000, 16000, 18000]
In second case:
yAxis.mEntries = [0, 30, 60, 90, 120, 150, 180, 210, 240, 18000]
That’s why BarChart View need padding from left, for bigger values, than actually need.
You can use that hack, for checking your case:
YAxis yAxis = barChart.getAxisLeft();
if (yAxis.mEntries.length > yAxis.mEntryCount){
float[] arr = yAxis.mEntries;
yAxis.mEntries = new float[yAxis.mEntryCount];
System.arraycopy(arr, 0, yAxis.mEntries, 0, yAxis.mEntryCount);
}
See picture below, trying to figure out why they it is skipping the '1', '3', and so forth.
Where i set the series and graph:
DataPoint[] dataPoints = new DataPoint[rankList.size()]; // declare an array of DataPoint objects with the same size as your list
for (int i = 0; i < rankList.size(); i++) {
dataPoints[i] = new DataPoint(i, Double.parseDouble(rankList.get(i))); // not sure but I think the second argument should be of type double
}
BarGraphSeries<DataPoint> series2 = new BarGraphSeries<DataPoint>(dataPoints); // This one should be obvious right? :)
series2.setAnimated(true);
series2.setTitle("Random Curve 1");
series2.setColor(Color.GREEN);
series2.setSpacing(30);
series2.setDataWidth(1);
graph2.getViewport().setMinX(-1);
graph2.getViewport().setMaxX(12);
graph2.addSeries(series2);
The right info is being plotted, but i've tried a bunch of stuff from the docs and get get it to work.
Sorry I misunderstood your question...
This will help:
yourGraph.getGridLabelRenderer().setNumHorizontalLabels(numberOfBars);
It actually shows all bars. You've set series2.setSpacing(30);.
Instead do series2.setSpacing(0);.
I'm using TeeChart for drawing incoming data points that are received via BLE.
I created an TeeChart that has three costum axes to divide the Y-Axis in three equally sized parts. In addition, I initialized three FastLines and assigned each line to one custom axis.
//LINES
line1 = new Line(chart1.getChart());
line1.setColor(Color.black);
line1.getLinePen().setWidth(3);
line2 = new Line(chart1.getChart());
line2.setColor(Color.black);
line2.getLinePen().setWidth(3);
line3 = new Line(chart1.getChart());
line3.setColor(Color.black);
line3.getLinePen().setWidth(3);
//AXES
Axis axis0 = new Axis(false, false, chart1.getChart());
axis0.setVisible(true);
axis0.getLabels().setVisible(false);
axis0.getMinorTicks().setVisible(true);
axis0.getTicksInner().setVisible(false);
axis0.getTicks().setVisible(true);
chart1.getAxes().getCustom().add(axis0);
line1.setCustomVertAxis(axis0);
axis0.getTitle().getFont().setSize(textSizeY);
axis0.getTitle().getFont().setBold(true);
axis0.getTitle().setText("1 mV");
axis0.getTitle().setAngle(90);
axis0.setStartPosition(0);
axis0.setEndPosition(33);
axis0.setRelativePosition(0);
axis0.setAutomatic(false);
axis0.setIncrement(100);
axis0.setMinimum(-350);
axis0.setMaximum(+350);
Axis axis1 = new Axis(false, false, chart1.getChart());
axis1.setVisible(true);
axis1.getLabels().setVisible(false);
axis1.getMinorTicks().setVisible(true);
axis1.getTicksInner().setVisible(false);
axis1.getTicks().setVisible(true);
chart1.getAxes().getCustom().add(axis1);
line2.setCustomVertAxis(axis1);
axis1.getTitle().getFont().setSize(textSizeY);
axis1.getTitle().getFont().setBold(true);
axis1.getTitle().setText("1 mV");
axis1.getTitle().setAngle(90);
axis1.setStartPosition(33);
axis1.setEndPosition(66);
axis1.setRelativePosition(0);
axis1.setAutomatic(false);
axis1.setIncrement(100);
axis1.setMinimum(-350);
axis1.setMaximum(+350);
Axis axis2 = new Axis(false, false, chart1.getChart());
axis2.setVisible(true);
axis2.getLabels().setVisible(false);
axis2.getMinorTicks().setVisible(true);
axis2.getTicksInner().setVisible(false);
axis2.getTicks().setVisible(true);
chart1.getAxes().getCustom().add(axis2);
line3.setCustomVertAxis(axis2);
axis2.getTitle().getFont().setSize(textSizeY);
axis2.getTitle().getFont().setBold(true);
axis2.getTitle().setText("1 mV");
axis2.getTitle().setAngle(90);
axis2.setStartPosition(66);
axis2.setEndPosition(100);
axis2.setRelativePosition(0);
axis2.setAutomatic(false);
axis2.setIncrement(100);
axis2.setMinimum(-350);
axis2.setMaximum(+350);
As soon as there is data coming via BLE, the data points are plotted in the TeeChart as follows:
public static void addDataToTeeChart(short i){
if(numberOfPlottablePoints >= 3*MAX_X_POINTS) {
numberOfPlottablePoints = 0;
line1.clear();
line2.clear();
line3.clear();
}
if (numberOfPlottablePoints < MAX_X_POINTS){
line1.add(i);
}
else if (numberOfPlottablePoints < 2*MAX_X_POINTS){
line2.add(i);
}
else if (numberOfPlottablePoints < 3*MAX_X_POINTS){
line3.add(i);
}
numberOfPlottablePoints++;
}
The problem now is that while adding data to line1, everything is working just fine. But adding data to line2 becomes slower and the drawing gets some kind of juddery. And it's even worse for line3.
After clearing and back to adding points to line1, the plotting is fine again.
I was thinking that maybe there is too much data coming in.
To rule that out, I added all incoming data to line1 (leaving line2 and line3 empty). That worked fine again!
I then tried to plot all data in line2 (leaving Line1 and Line3 empty) but there was no data plotted at all!
Also reducing MAX_X_POINTS to reduce the amout of plotted points, didn't do it for me.
For me it seems that the problem is with toggling between line1, line2 and line3 because when I just use one line (independet of which custom axis was used) the drawing is smooth!
I have no idea what else to try.
I hope that maybe someone can even tell me what exactly might be the problem or even has an suggestion what to do.
Thank you in advance!
I did a rapid test with your code (with a few changes), and it seems to work fine for me here:
The changes I did are basically:
Disable manual configuration of the 3 custom axes scales.
Set the chart to 2D.
Fill the series with sample values instead of using your addDataToTeeChart function.
Find the code here:
//LINES
Line line1 = new Line(tChart1.getChart());
line1.setColor(Color.black);
line1.getLinePen().setWidth(3);
Line line2 = new Line(tChart1.getChart());
line2.setColor(Color.black);
line2.getLinePen().setWidth(3);
Line line3 = new Line(tChart1.getChart());
line3.setColor(Color.black);
line3.getLinePen().setWidth(3);
//AXES
Axis axis0 = new Axis(false, false, tChart1.getChart());
axis0.setVisible(true);
axis0.getLabels().setVisible(false);
axis0.getMinorTicks().setVisible(true);
axis0.getTicksInner().setVisible(false);
axis0.getTicks().setVisible(true);
tChart1.getAxes().getCustom().add(axis0);
line1.setCustomVertAxis(axis0);
//axis0.getTitle().getFont().setSize(textSizeY);
axis0.getTitle().getFont().setBold(true);
axis0.getTitle().setText("1 mV");
axis0.getTitle().setAngle(90);
axis0.setStartPosition(0);
axis0.setEndPosition(33);
axis0.setRelativePosition(0);
/*axis0.setAutomatic(false);
axis0.setIncrement(100);
axis0.setMinimum(-350);
axis0.setMaximum(+350);*/
Axis axis1 = new Axis(false, false, tChart1.getChart());
axis1.setVisible(true);
axis1.getLabels().setVisible(false);
axis1.getMinorTicks().setVisible(true);
axis1.getTicksInner().setVisible(false);
axis1.getTicks().setVisible(true);
tChart1.getAxes().getCustom().add(axis1);
line2.setCustomVertAxis(axis1);
//axis1.getTitle().getFont().setSize(textSizeY);
axis1.getTitle().getFont().setBold(true);
axis1.getTitle().setText("1 mV");
axis1.getTitle().setAngle(90);
axis1.setStartPosition(33);
axis1.setEndPosition(66);
axis1.setRelativePosition(0);
/*axis1.setAutomatic(false);
axis1.setIncrement(100);
axis1.setMinimum(-350);
axis1.setMaximum(+350);*/
Axis axis2 = new Axis(false, false, tChart1.getChart());
axis2.setVisible(true);
axis2.getLabels().setVisible(false);
axis2.getMinorTicks().setVisible(true);
axis2.getTicksInner().setVisible(false);
axis2.getTicks().setVisible(true);
tChart1.getAxes().getCustom().add(axis2);
line3.setCustomVertAxis(axis2);
//axis2.getTitle().getFont().setSize(textSizeY);
axis2.getTitle().getFont().setBold(true);
axis2.getTitle().setText("1 mV");
axis2.getTitle().setAngle(90);
axis2.setStartPosition(66);
axis2.setEndPosition(100);
axis2.setRelativePosition(0);
/*axis2.setAutomatic(false);
axis2.setIncrement(100);
axis2.setMinimum(-350);
axis2.setMaximum(+350);*/
tChart1.getAspect().setView3D(false);
line1.fillSampleValues(100);
line2.fillSampleValues(100);
line3.fillSampleValues(100);
To increment the fonts depending on the screen resolution I also use this:
private void proportionalFonts() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float myDensity = metrics.density;
tChart1.getAspect().setFontZoom(tChart1.getAspect().getFontZoom()*myDensity*1.5);
}
If you still find problems with it, please try to arrange an sscce.
I have a problem with the visualization of a line graph, as you can see in the chart the x poins don't match exactly with the y point, they are slighty righter.
On Apr 12, 2012 the x value must be exactly 2
On Apr 13, 2012 the x value must be exactly 3
On Apr 16, 2012 the x value must be exactly 6
Has anyone else met my same proplem?
Can someone help me?
My code is very simple, I have a list of object, each element of which contains both data value and int value and I put these value in the two different arrays that will be used to draw the chart. I'm using achartengine-07 library.
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
XYMultipleSeriesRenderer aRenderer = new XYMultipleSeriesRenderer();
Date[] x = new Date[list.size()];
for(int j=0;j<list.size();j++){
x[j] = list.get(j).getData();
}
int[] y = new int[list.size()];
for(int j=0;j<list.size();j++){
y[j] =Integer.parseInt(list.get(j).getRank());
}
TimeSeries series = new TimeSeries(h[i]);
for(int k = 0; k <x.length; k++)
series.add(x[k], y[k]);
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setPointStyle(PointStyle.SQUARE);
renderer.setFillPoints(true);
dataset.addSeries(series);
aRenderer.setXLabels(x.length);
aRenderer.setYLabels(y.length);
aRenderer.addSeriesRenderer(renderer);
The time chart in AChartEngine tries to compute the best "rounded" labels like everyday midnight or so.
If you don't like this approach, you could build a regular line chart with custom labels:
renderer.addXTextLabel();
I builded a regular line chart, like suggested by Dan, with custom labels and to remove the previous label I put setXLabels(0):
aRenderer.addXTextLabel();
// To remove the previous label put
aRenderer.setXLabels(0);