-9

I'm trying to make a BarChart using achartengine, but so far, I haven't been able to get rid of the following effect : bar width is only correctly displayed when values are on the edge of the screen, but at startup, bars are much bigger and sometimes even hide the bar's value. Could this have something to do with my data set not being a continued serie of x values ? I have one point at x=17 then then next value is at x=24, and it seems the changing bar width happens between these 2 values. Can someone assist in making this graph look good ?

Thanks in advance for your help !

[The graph being shown on fragment's start] The graph being shown on fragment's start

[The graph being shown when scrolling to the left] The graph being shown when scrolling to the left

CODE TO MAKE THE GRAPH :

    XYSeries xySerie = new XYSeries("Climb Level Statistics");
    XYSeriesRenderer serieRenderer;
    XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
    XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();

    //Adding data to XYSerie and adding XYSerie to mDataset
    //stats is an int[] containing level id, value for the level, level id, ...
    //example of dataset used for image shown above: {17, 4, 24, 3, 25, 7, 26, 10, 27, 4}
    int statsSize = stats.size();
    double routeLevel;
    double climbsQuantity;
    for (int counter = 0; counter<statsSize; counter++){
        routeLevel = stats.get(counter);
        counter++;
        climbsQuantity = stats.get(counter);
        xySerie.add(routeLevel, climbsQuantity);
    }
    mDataset.addSeries(xySerie);

    //Setting series renderer properties and adding it to the mRenderer
    serieRenderer = new XYSeriesRenderer();
    serieRenderer.setChartValuesTextSize(28);
    serieRenderer.setDisplayChartValues(true);
    mRenderer.addSeriesRenderer(serieRenderer);

    //Setting main renderer properties
    mRenderer.setApplyBackgroundColor(true);
    mRenderer.setMarginsColor(Color.argb(0x00, 0x01, 0x01, 0x01));
    mRenderer.setBackgroundColor(Color.TRANSPARENT);
    mRenderer.setLabelsTextSize(15);
    mRenderer.setMargins(new int[] { 30, 30, 30, 30 });
    mRenderer.setZoomButtonsVisible(false);
    mRenderer.setPanLimits(new double[]{0,48, 0, 5000});
    mRenderer.setBarSpacing(1.5);
    mRenderer.setLabelsTextSize(28);
    mRenderer.setLabelsColor(Color.BLACK);
    mRenderer.setXLabels(0);
    mRenderer.setXLabelsColor(Color.BLACK);
    String[] routeLevels = context.getResources().getStringArray(R.array.route_levels);
    int routeLevelsSize = routeLevels.length;
    for (int x=1;x<routeLevelsSize+1;x++){
        mRenderer.addXTextLabel(x, routeLevels[x-1]);
    }
    mRenderer.setYLabels(0);
    mRenderer.setYAxisMin(0);
    mRenderer.setShowLegend(false);
    mRenderer.setZoomEnabled(false);
    mRenderer.setZoomEnabled(false, false);
    mRenderer.setPanEnabled(true, false);


    GraphicalView graphView = ChartFactory.getBarChartView(context, mDataset, mRenderer, BarChart.Type.STACKED);
    graphView.setBackgroundColor(Color.argb(255, 247, 247, 247));
2Dee
  • 8,609
  • 7
  • 42
  • 53

2 Answers2

3

I was able to resolve the changing bar width issue by ensuring the serie was a "perfect" suite for x values, changing

this : {17, 4, 24, 3, 25, 7, 26, 10, 27, 4}

to this : {17, 4, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 3, 25, 7, 26, 10, 27, 4}

To achieve that, I modified my first for loop to check for missing x values :

for (int x = 0; x<statsSize; x++){
        routeLevel = currentLevel;
        x++;
        currentLevel++;
        climbsQuantity = stats.get(x);
        xySerie.add(routeLevel, climbsQuantity);

        //if not at the last x/y couple of the array, fill the blanks in the serie
        if (x<statsSize-1){ 
            while (stats.get(x+1)>currentLevel){
                routeLevel = currentLevel;
                climbsQuantity = 0;
                xySerie.add(routeLevel, climbsQuantity);
                currentLevel++;
            }
        }
}

Now the bar width doesn't change at all when I scroll. This is more a workaround, though, because now the "filling" couples I added are all showing 0 as value, which I find a bit odd. If I find a way to hide these 0 values, I'll edit my answer...

CURRENT APPEARANCE OF THE GRAPH enter image description here

2Dee
  • 8,609
  • 7
  • 42
  • 53
  • Replace the zeros with MathHelper.NULL_VALUE – Dan D. Jun 20 '13 at 10:43
  • I just tried climbsQuantity = MathHelper.NULL_VALUE, the 0's are gone, but it made all bars disappear, only leaving y values right above their respective x label (I made a screen capture, http://tinyurl.com/q8fe7ga). – 2Dee Jun 21 '13 at 11:32
1

First of all, you can set the visible area by changing the X axis min and max:

renderer.setXAxisMin(min);
renderer.setXAxisMax(max);

For changing the bars width, you have a few options.

If your dataset contain more than one element per series then I suggest you use renderer.setBarSpacing().

If there is only one element in your series then you can use renderer.setBarWidth().

Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • Thank you for your answer. Unfortunately, just by setting XAxisMin and XAxisMax or BarSpacing, I was not able to get rid of the changing Bar width effect when scrolling the graph. Very useful methods nevertheless ... – 2Dee Jun 20 '13 at 09:55
  • As I understand it, you're one of the devs for Achartengine. First, thanks A MILLION for the lib, awesome tool ! May I ask you to kindly review the answer I propose and give your opinion on the possibility of hiding y=0 values and the need for "perfect" suite of x values in the charts ? Thanks again ! – 2Dee Jun 20 '13 at 10:17