Search code examples
androidachartengine

Data set in graph is not showing correctly


I have created a graph with one x-axis and two y-axis. The problem is that when I plot the graph with the same set of data set in the y-axis it doesn't overlap. For example if I plot a graph using left y-axis and x-axis with values x(1,2,3,4,5) and y(10,20,30,40,50) it plots a graph along x and y-axis. Similarly when I plot a graph using right y-axis and x-axis with the same value, then instead of overlapping it plots a graph in different places. Why does this happen? (Please see the screenshots and the code I have used for plotting this graph)

Code for plotting graph

public class ChartEngineActivity extends Activity 
{
private GraphicalView mChartView;
private XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(2);
private XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.chart_activity);                
        
    List<double[]> x = new ArrayList<double[]>();
    x.add(new double[] {1, 2, 3, 4, 5});

    List<double[]> values = new ArrayList<double[]>();
    values.add(new double[] {10, 20, 30, 40, 50});
    
    int[] colors = new int[] { Color.BLUE,Color.YELLOW};
    PointStyle[] styles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND};
    
    renderer = new XYMultipleSeriesRenderer(2);
    setRenderer(renderer, colors, styles);
    
    int length = renderer.getSeriesRendererCount();
    for (int i = 0; i < length; i++) 
    {
      ((XYSeriesRenderer) renderer.getSeriesRendererAt(i)).setFillPoints(true);
    }       
    
    renderer.setChartTitle("Weight / Temperature");
    renderer.setXLabels(12);
    renderer.setXTitle("Month");        
    renderer.setXAxisMin(1);
    renderer.setXAxisMax(12);
    renderer.setXLabelsAlign(Align.CENTER);
        
    
    renderer.setYLabels(12);  
    renderer.setYTitle("Weight", 0);
    renderer.setYTitle("Temperature", 1);
    renderer.setYAxisMin(10, 0);
    renderer.setYAxisMax(60,0);
    renderer.setYAxisMin(10, 1);
    renderer.setYAxisMax(60,1);
    renderer.setYAxisAlign(Align.LEFT, 0);
    renderer.setYAxisAlign(Align.RIGHT, 1);
    renderer.setYLabelsAlign(Align.LEFT, 0);
    renderer.setYLabelsAlign(Align.RIGHT, 1);
    
    renderer.setAxesColor(Color.LTGRAY);
    renderer.setLabelsColor(Color.LTGRAY);         
    renderer.setShowGrid(true);
    renderer.setGridColor(Color.GRAY);
    renderer.setZoomButtonsVisible(true);
    renderer.setPanLimits(new double[] { 0, 12, 0, 12 });
    
    dataset = buildDataset(new String[] {"Body Weight"}, x, values);
    values.clear();     
    values.add(new double[] {10, 20, 30, 40, 50});
    addXYSeries(dataset, new String[] {"Body Temperature"}, x, values, 1);
}

protected void setRenderer(XYMultipleSeriesRenderer renderer, int[] colors, PointStyle[] styles) 
{
    renderer.setAxisTitleTextSize(16);
    renderer.setChartTitleTextSize(20);
    renderer.setLabelsTextSize(15);
    renderer.setLegendTextSize(15);
    renderer.setPointSize(5f);
    renderer.setMargins(new int[] { 20, 30, 15, 20 });
    int length = colors.length;
    
    for (int i = 0; i < length; i++) 
    {
        XYSeriesRenderer r = new XYSeriesRenderer();
        r.setColor(colors[i]);
        r.setPointStyle(styles[i]);
        renderer.addSeriesRenderer(r);
    }
}

protected XYMultipleSeriesDataset buildDataset(String[] titles, List<double[]> xValues,
        List<double[]> yValues) 
{
    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
    addXYSeries(dataset, titles, xValues, yValues, 0);
    return dataset;
}

public void addXYSeries(XYMultipleSeriesDataset dataset, String[] titles, List<double[]> xValues,
        List<double[]> yValues, int scale) 
{
    int length = titles.length;
    for (int i = 0; i < length; i++) 
    {
        XYSeries series = new XYSeries(titles[i], scale);
        double[] xV = xValues.get(i);
        double[] yV = yValues.get(i);
        int seriesLength = xV.length;
        for (int k = 0; k < seriesLength; k++) 
        {
            series.add(xV[k], yV[k]);
        }
        dataset.addSeries(series);
    }
}   

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
  super.onConfigurationChanged(newConfig);
  Intent intentNotes = new Intent(this, MainActivity.class);
  this.startActivity(intentNotes);  
  finish();
}

@Override
protected void onResume() 
{
    super.onResume();
    if (mChartView == null) 
    {
        LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
        mChartView = ChartFactory.getLineChartView(this, dataset, renderer);
        renderer.setClickEnabled(true);
        renderer.setSelectableBuffer(100);
        
        mChartView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mChartView.getCurrentSeriesAndPoint();              
            }
        });
             
         
        layout.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.FILL_PARENT));
    } 
    else 
    {
        mChartView.repaint();
    }
}
}

Screenshot for thats graph that appears

enter image description here


Solution

  • It looks like it's a bug in the achartengine. This happens in the demo of their app too. It looks like points plotted to the right don't adhere to all of the renderer's styles.

    If your chart is static you could try tweaking with the x axis max and min. This seems to move it around a bit.

    renderer.setXAxisMax(0);
    renderer.setXAxisMin(0);
    

    edit:

    Try this

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
        setContentView(R.layout.chart_activity);                
    
        List<double[]> x = new ArrayList<double[]>();
        x.add(new double[] {1, 2, 3, 4, 5});
    
        List<double[]> values = new ArrayList<double[]>();
        values.add(new double[] {10, 20, 30, 40, 50});
    
        int[] colors = new int[] { Color.BLUE,Color.YELLOW,Color.YELLOW};
            PointStyle[] styles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND,
        PointStyle.TRIANGLE, PointStyle.SQUARE };
    
        renderer = new XYMultipleSeriesRenderer(3);
        setRenderer(renderer, colors, styles);
    
        int length = renderer.getSeriesRendererCount();
        for (int i = 0; i < length; i++) 
        {
          ((XYSeriesRenderer) renderer.getSeriesRendererAt(i)).setFillPoints(true);
        }       
    
        renderer.setChartTitle("Weight / Temperature");
        renderer.setXLabels(12);
        renderer.setXTitle("Month");        
        renderer.setXAxisMin(1);
        renderer.setXAxisMax(12);
        renderer.setXLabelsAlign(Align.CENTER);
    
    
        renderer.setYLabels(12);  
        renderer.setYTitle("Weight", 0);
        renderer.setYTitle("Temperature", 1);
        renderer.setYAxisMin(10, 0);
        renderer.setYAxisMax(60,0);
        renderer.setYAxisMin(10, 1);
        renderer.setYAxisMax(60,1);
        renderer.setYAxisAlign(Align.LEFT, 0);
        renderer.setYAxisAlign(Align.RIGHT, 1);
        renderer.setYLabelsAlign(Align.LEFT, 0);
        renderer.setYLabelsAlign(Align.RIGHT, 1);
    
        renderer.setAxesColor(Color.LTGRAY);
        renderer.setLabelsColor(Color.LTGRAY);         
        renderer.setShowGrid(true);
        renderer.setGridColor(Color.GRAY);
        renderer.setZoomButtonsVisible(true);
        renderer.setPanLimits(new double[] { 0, 12, 0, 12 });
    
        dataset = buildDataset(new String[] {"Body Weight"}, x, values);
        values.clear();
        values.add(new double[] {10, 20, 30, 40, 50});  //whatever values you want to set 
        addXYSeries(dataset, new String[] { "Body Temperature" }, x, values, 0);
        values.clear();     
        values.add(new double[1]);
        addXYSeries(dataset, new String[] {"Body Temperature"}, x, values, 1);
     }
    

    This is my code from the demo that works

    public Intent execute(Context context) {
        String[] titles = new String[] { "Crete" };
        List<double[]> x = new ArrayList<double[]>();
        for (int i = 0; i < titles.length; i++) {
            x.add(new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 });
        }
        List<double[]> values = new ArrayList<double[]>();
        values.add(new double[] { 12.3, 12.5, 13.8, 16.8, 20.4, 24.4, 26.4, 26.1, 23.6, 20.3, 17.2,
        13.9 });
        int[] colors = new int[] { Color.BLUE, Color.YELLOW,  Color.YELLOW,};
        PointStyle[] styles = new PointStyle[] { PointStyle.CIRCLE, PointStyle.DIAMOND, PointStyle.TRIANGLE, PointStyle.SQUARE };
        XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(3);
        setRenderer(renderer, colors, styles);
        int length = renderer.getSeriesRendererCount();
        for (int i = 0; i < length; i++) {
          ((XYSeriesRenderer) renderer.getSeriesRendererAt(i)).setFillPoints(true);
        }
        setChartSettings(renderer, "Average temperature", "Month", "Temperature", 0.5, 12.5, 0, 32, Color.LTGRAY, Color.LTGRAY);
        renderer.setXLabels(12);
        renderer.setYLabels(10);
        renderer.setShowGrid(true);
        renderer.setYLabelsAlign(Align.RIGHT);
        renderer.setZoomButtonsVisible(true);
        renderer.setPanLimits(new double[] { -10, 20, -10, 40 });
        renderer.setZoomLimits(new double[] { -10, 20, -10, 40 });
    
        renderer.setYTitle("Hours", 1);
        renderer.setYAxisAlign(Align.RIGHT, 1);
        renderer.setYLabelsAlign(Align.LEFT, 1);
        renderer.setXLabelsAlign(Align.RIGHT);
        XYMultipleSeriesDataset dataset = buildDataset(titles, x, values);
        values.clear();
        values.add(new double[] { 12.3, 4.9, 5.9, 8.8, 10.8, 11.9, 13.6, 12.8, 11.4, 9.5, 7.5, 5.5 });
        addXYSeries(dataset, new String[] { "Sunshine hours" }, x, values, 0);
        x.clear();
        x.add(new double[1]);
        addXYSeries(dataset, new String[] { "Sunshine hours" }, x, values, 1);
        Intent intent = ChartFactory.getLineChartIntent(context, dataset, renderer, "Average temperature");
        return intent;
    }