Reputation: 13733
I want to integrate a simple XY line chart in my Activity. While looking for free charting with customization (customizable backgrounds, colors, axis labels), I found two candidates: Achartengine and Adnroidplot. There were some other libraries, but they were not customizable or available only as separate Intents.
I need also support for older Android API (at least 1.6 must be supported).
I tried Achartengine but it failed when I integrated it in a ScrollView. When I was scrolling, the chart became somehow corrupted, it got squeezed and some background elements seemed to drift away.
Then I tried Adnroidplot. At first it did not start on 1.6 because of a Pair class. But I found a fix for the problem on Adnroidplot forum. Everything seemed to work fine, also dynamic updates though custom Observers worked fine. It was a bit hard to customize X axis labels (I needed custom Strings there and not numbers), but with a custom formatter I finally did it.
But then I tried it with real data from a client's database. There were some series of points with equal values. And I was shocked to see that Adnroidplot is not able to draw a horizontal line, it hangs or completely messes up the chart!
Here is the test case, I borrowed it from Adnroidplot Quickstart and did a small modification to make one series with equal values:
pricesPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// Create array of y-values to plot:
Number[] series1Numbers = {7, 7}; // horizontal line expected, got nothing or hang
// Turn the above arrays into XYSeries:
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), // SimpleXYSeries takes a List so turn our array into a List
ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
"Series1"); // Set the display title of the series
// Create a formatter to use for drawing a series using LineAndPointRenderer:
LineAndPointFormatter series1Format = new LineAndPointFormatter(
Color.rgb(0, 200, 0), // line color
Color.rgb(0, 100, 0), // point color
null); // fill color (optional) <- my app hangs if I add it for a horizontal line
// Add series1 to the xyplot:
pricesPlot.addSeries(series1, series1Format);
// Reduce the number of range labels
pricesPlot.setTicksPerRangeLabel(3);
// By default, AndroidPlot displays developer guides to aid in laying out your plot.
// To get rid of them call disableAllMarkup():
pricesPlot.disableAllMarkup();
I already posted on Adnroidplot forums, but I am not sure how fast they will answer and when the issue will be fixed.
So I hope maybe someone at StackOverflow might know some workaround for it?
Upvotes: 3
Views: 2728
Reputation: 537
For those who googled for chart squeezing problems inside ScrollView with AChartEngine this is solution to your problem:
renderer.setInScroll(true);
Upvotes: 1
Reputation: 5246
I came up with an easy workaround to make sure horizontal lines are shown.
Basically, just graph a 3 point clear Y_VALS_ONLY series before you load your first real plot.
Assuming you have a colors.xml res file, you can create a clear series like this:
Declare this:
Number[] yClear = {0, 1, 0};
LineAndPointFormatter clearFormat;
SimpleXYSeries clear= null;
In your onCreate() or onViewCreated():
clearFormat = new LineAndPointFormatter(getResources().getColor(R.color.transparent), getResources().getColor(R.color.transparent), 0, null);
Then after you set up your plot, just add the clear plot to the graph;
clear = new SimpleXYSeries( Arrays.asList(yClear), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Clear");
yourPlot.addSeries(clear, clearFormat);
I spent hours trying to debug this issue, and it came down to just making life easy and doing it this way.
Upvotes: 1
Reputation: 13733
Thanks to the developers on Androidplot forums, I now got the solution. The following code is a fragment of my Activity.java file. Unfortunately the final code was later refactored and some pieces moved to a custom datasource and custom XYSeries which I don't have permissions to publish here.
This code worked for Androidplot-core-0.4.4-release.jar, and I'm not sure if it will work with later versions.
// for chart
private XYPlot pricesPlot;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... other initialisation code omitted for brevity ...
pricesPlot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// the following code was added as a debug code to test that it works.
// later many things were changed, so take it "as is" - this was the core of the solution
PriceDatesFormat ppf = new PriceDatesFormat();
ppf.Labels = new String[]{
"2011-01",
"2011-05",
"2011-07",
"2011-11",
"2011-07",
"2011-07"
};
pricesPlot.getGraphWidget().setDomainValueFormat(ppf);
// Create two arrays of y-values to plot:
Float [] seriesNumbers = new Float[]{118f, 185f};
Float min = Collections.min(Arrays.asList(seriesNumbers));
Float max = Collections.max(Arrays.asList(seriesNumbers));
pricesPlot.setRangeBoundaries(min - 0.1*min, max + 0.1*max, BoundaryMode.AUTO);// make them a bit wider out of min/max values
Upvotes: 3