2017-01-04 122 views
1

我一直在玩官方CombinedChartActivity example来显示2条折线图,1条形图和一些泡泡数据。MpAndroidChart CombinedChart - 如何防止LineData圈被绘制在Bubble数据上?

尽管已经改变了DrawOrder ...

mChart.setDrawOrder(new DrawOrder[]{ 
     DrawOrder.BAR, DrawOrder.CANDLE, DrawOrder.LINE, DrawOrder.SCATTER, DrawOrder.BUBBLE 
}); 

...我的泡沫仍然得到由线圆圈画出了。正如您在此屏幕截图中看到的那样,正确显示在气泡后面;这只是行那些出现在泡沫面前:

enter image description here

如何使圈的行为和线条,让它们也出现泡沫的背后?

这里是我的全部活动代码:

import android.app.Activity; 
import android.os.Bundle; 
import android.support.v7.widget.Toolbar; 
import com.github.mikephil.charting.charts.CombinedChart; 
import android.graphics.Color; 
import android.view.Menu; 
import android.view.MenuItem; 
import com.github.mikephil.charting.charts.CombinedChart.DrawOrder; 
import com.github.mikephil.charting.components.AxisBase; 
import com.github.mikephil.charting.components.Legend; 
import com.github.mikephil.charting.components.XAxis; 
import com.github.mikephil.charting.components.XAxis.XAxisPosition; 
import com.github.mikephil.charting.components.YAxis; 
import com.github.mikephil.charting.data.BarData; 
import com.github.mikephil.charting.data.BarDataSet; 
import com.github.mikephil.charting.data.BarEntry; 
import com.github.mikephil.charting.data.BubbleData; 
import com.github.mikephil.charting.data.BubbleDataSet; 
import com.github.mikephil.charting.data.BubbleEntry; 
import com.github.mikephil.charting.data.CandleData; 
import com.github.mikephil.charting.data.CandleDataSet; 
import com.github.mikephil.charting.data.CandleEntry; 
import com.github.mikephil.charting.data.CombinedData; 
import com.github.mikephil.charting.data.Entry; 
import com.github.mikephil.charting.data.LineData; 
import com.github.mikephil.charting.data.LineDataSet; 
import com.github.mikephil.charting.data.ScatterData; 
import com.github.mikephil.charting.data.ScatterDataSet; 
import com.github.mikephil.charting.formatter.IAxisValueFormatter; 
import com.github.mikephil.charting.interfaces.datasets.IDataSet; 
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; 
import com.github.mikephil.charting.utils.ColorTemplate; 
import java.util.ArrayList; 
import java.util.List; 

import android.graphics.Typeface; 

public class MpAndroidChartCombinedActivity extends Activity { 

    private CombinedChart mChart; 
    private final int itemcount = 12; 

    protected String[] mMonths = new String[] { 
      "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec" 
    }; 

    protected String[] mParties = new String[] { 
      "Party A", "Party B", "Party C", "Party D", "Party E", "Party F", "Party G", "Party H", 
      "Party I", "Party J", "Party K", "Party L", "Party M", "Party N", "Party O", "Party P", 
      "Party Q", "Party R", "Party S", "Party T", "Party U", "Party V", "Party W", "Party X", 
      "Party Y", "Party Z" 
    }; 

    protected Typeface mTfRegular; 
    protected Typeface mTfLight; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_mp_android_chart_combined); 

     //Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     //setSupportActionBar(toolbar); 

     mTfRegular = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf"); 
     mTfLight = Typeface.createFromAsset(getAssets(), "OpenSans-Light.ttf"); 

     /** 
     * Get chart reference. 
     */ 
     CombinedChart mChart = (CombinedChart)findViewById(R.id.mpAndroidChart); 

     mChart.getDescription().setEnabled(false); 
     mChart.setBackgroundColor(Color.WHITE); 
     mChart.setDrawGridBackground(false); 
     mChart.setDrawBarShadow(false); 
     mChart.setHighlightFullBarEnabled(false); 

     // draw bars behind lines 
     mChart.setDrawOrder(new DrawOrder[]{ 
       DrawOrder.BAR, DrawOrder.CANDLE, DrawOrder.LINE, DrawOrder.SCATTER, DrawOrder.BUBBLE 
     }); 

     Legend l = mChart.getLegend(); 
     l.setWordWrapEnabled(true); 
     l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); 
     l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); 
     l.setOrientation(Legend.LegendOrientation.HORIZONTAL); 
     l.setDrawInside(false); 

     YAxis rightAxis = mChart.getAxisRight(); 
     rightAxis.setDrawGridLines(false); 
     rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) 

     YAxis leftAxis = mChart.getAxisLeft(); 
     leftAxis.setDrawGridLines(false); 
     leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) 

     XAxis xAxis = mChart.getXAxis(); 
     xAxis.setPosition(XAxisPosition.BOTTOM); 
     xAxis.setAxisMinimum(0f); 
     xAxis.setGranularity(1f); 
     xAxis.setValueFormatter(new IAxisValueFormatter() { 
      @Override 
      public String getFormattedValue(float value, AxisBase axis) { 
       return mMonths[(int) value % mMonths.length]; 
      } 
     }); 

     CombinedData data = new CombinedData(); 

     data.setData(generateLineData()); 
     //data.setData(generateLineData("Line DataSet 2", Color.rgb(255, 0, 0))); 
     //data.setData(generateLineData("Line DataSet 3", Color.rgb(0, 255, 0))); 
     data.setData(generateBarData()); 
     data.setData(generateBubbleData()); 
     data.setData(generateScatterData()); 
     //data.setData(generateCandleData()); 
     data.setValueTypeface(mTfLight); 

     xAxis.setAxisMaximum(data.getXMax() + 0.25f); 

     mChart.setData(data); 
     mChart.invalidate(); 

    } 

    private LineData generateLineData() { 

     LineData lineData = new LineData(); 

     ArrayList<Entry> entries1 = new ArrayList<Entry>(); 
     for (int index = 0; index < itemcount; index++) { 
      entries1.add(new Entry(index + 0.5f, getRandom(15, 5))); 
     } 
     int color1 = Color.rgb(240, 238, 70); 
     String dataSetLabel1 = "Line Data 1"; 
     LineDataSet lineDataSet1 = new LineDataSet(entries1, dataSetLabel1); 
     lineDataSet1.setColor(color1); 
     lineDataSet1.setLineWidth(2.5f); 
     lineDataSet1.setCircleColor(color1); 
     lineDataSet1.setCircleRadius(5f); 
     lineDataSet1.setFillColor(color1); 
     lineDataSet1.setMode(LineDataSet.Mode.CUBIC_BEZIER); 
     lineDataSet1.setDrawValues(true); 
     lineDataSet1.setValueTextSize(10f); 
     lineDataSet1.setValueTextColor(color1); 
     lineDataSet1.setAxisDependency(YAxis.AxisDependency.LEFT); 
     lineData.addDataSet(lineDataSet1); 

     ArrayList<Entry> entries2 = new ArrayList<Entry>(); 
     for (int index = 0; index < itemcount; index++) { 
      entries2.add(new Entry(index + 0.5f, getRandom(15, 6))); 
     } 
     int color2 = Color.rgb(240, 0, 0); 
     String dataSetLabel2 = "Line Data 2"; 
     LineDataSet lineDataSet2 = new LineDataSet(entries2, dataSetLabel2); 
     lineDataSet2.setColor(color2); 
     lineDataSet2.setLineWidth(2.5f); 
     lineDataSet2.setCircleColor(color2); 
     lineDataSet2.setCircleRadius(5f); 
     lineDataSet2.setFillColor(color2); 
     lineDataSet2.setMode(LineDataSet.Mode.CUBIC_BEZIER); 
     lineDataSet2.setDrawValues(true); 
     lineDataSet2.setValueTextSize(10f); 
     lineDataSet2.setValueTextColor(color2); 
     lineDataSet2.setAxisDependency(YAxis.AxisDependency.LEFT); 
     lineData.addDataSet(lineDataSet2); 

     ArrayList<Entry> entries3 = new ArrayList<Entry>(); 
     for (int index = 0; index < itemcount; index++) { 
      entries3.add(new Entry(index + 0.5f, getRandom(100, 150))); 
     } 
     int color3 = Color.rgb(0, 0, 255); 
     String dataSetLabel3 = "Line Data 3"; 
     LineDataSet lineDataSet3 = new LineDataSet(entries3, dataSetLabel3); 
     lineDataSet3.setColor(color3); 
     lineDataSet3.setLineWidth(2.5f); 
     lineDataSet3.setCircleColor(color3); 
     lineDataSet3.setCircleRadius(5f); 
     lineDataSet3.setFillColor(color3); 
     lineDataSet3.setMode(LineDataSet.Mode.CUBIC_BEZIER); 
     lineDataSet3.setDrawValues(false); 
     lineDataSet3.setValueTextSize(10f); 
     lineDataSet3.setValueTextColor(color3); 
     lineDataSet3.setAxisDependency(YAxis.AxisDependency.RIGHT); 
     lineData.addDataSet(lineDataSet3); 

     return lineData; 
    } 

    private BarData generateBarData() { 

     ArrayList<BarEntry> entries1 = new ArrayList<BarEntry>(); 
     ArrayList<BarEntry> entries2 = new ArrayList<BarEntry>(); 

     for (int index = 0; index < itemcount; index++) { 
      entries1.add(new BarEntry(0, getRandom(25, 25))); 

      // stacked 
      entries2.add(new BarEntry(0, new float[]{getRandom(13, 12), getRandom(13, 12)})); 
     } 

     BarDataSet lineDataSet1 = new BarDataSet(entries1, "Bar 1"); 
     lineDataSet1.setColor(Color.rgb(60, 220, 78)); 
     lineDataSet1.setValueTextColor(Color.rgb(60, 220, 78)); 
     lineDataSet1.setValueTextSize(10f); 
     lineDataSet1.setAxisDependency(YAxis.AxisDependency.LEFT); 

     BarDataSet lineDataSet2 = new BarDataSet(entries2, ""); 
     lineDataSet2.setStackLabels(new String[]{"Stack 1", "Stack 2"}); 
     lineDataSet2.setColors(new int[]{Color.rgb(61, 165, 255), Color.rgb(23, 197, 255)}); 
     lineDataSet2.setValueTextColor(Color.rgb(61, 165, 255)); 
     lineDataSet2.setValueTextSize(10f); 
     lineDataSet2.setAxisDependency(YAxis.AxisDependency.LEFT); 

     float groupSpace = 0.06f; 
     float barSpace = 0.02f; // x2 dataset 
     float barWidth = 0.45f; // x2 dataset 
     // (0.45 + 0.02) * 2 + 0.06 = 1.00 -> interval per "group" 

     BarData d = new BarData(lineDataSet1, lineDataSet2); 
     d.setBarWidth(barWidth); 

     // make this BarData object grouped 
     d.groupBars(0, groupSpace, barSpace); // start at x = 0 

     return d; 
    } 

    protected ScatterData generateScatterData() { 

     ScatterData d = new ScatterData(); 

     ArrayList<Entry> entries = new ArrayList<Entry>(); 

     for (float index = 0; index < itemcount; index += 0.5f) 
      entries.add(new Entry(index + 0.25f, getRandom(10, 55))); 

     ScatterDataSet set = new ScatterDataSet(entries, "Scatter DataSet"); 
     set.setColors(ColorTemplate.MATERIAL_COLORS); 
     set.setScatterShapeSize(7.5f); 
     set.setDrawValues(false); 
     set.setValueTextSize(10f); 
     d.addDataSet(set); 

     return d; 
    } 

    protected CandleData generateCandleData() { 

     CandleData d = new CandleData(); 

     ArrayList<CandleEntry> entries = new ArrayList<CandleEntry>(); 

     for (int index = 0; index < itemcount; index += 2) 
      entries.add(new CandleEntry(index + 1f, 90, 70, 85, 75f)); 

     CandleDataSet set = new CandleDataSet(entries, "Candle DataSet"); 
     set.setDecreasingColor(Color.rgb(142, 150, 175)); 
     set.setShadowColor(Color.DKGRAY); 
     set.setBarSpace(0.3f); 
     set.setValueTextSize(10f); 
     set.setDrawValues(false); 
     d.addDataSet(set); 

     return d; 
    } 

    protected BubbleData generateBubbleData() { 

     BubbleData bd = new BubbleData(); 

     ArrayList<BubbleEntry> entries = new ArrayList<BubbleEntry>(); 

     for (int index = 0; index < itemcount; index++) { 
      float y = getRandom(10, 105); 
      float size = getRandom(100, 105); 
      entries.add(new BubbleEntry(index + 0.5f, y, size)); 
     } 

     BubbleDataSet set = new BubbleDataSet(entries, "Bubble DataSet"); 
     set.setColors(ColorTemplate.VORDIPLOM_COLORS); 
     set.setValueTextSize(10f); 
     set.setValueTextColor(Color.WHITE); 
     set.setHighlightCircleWidth(1.5f); 
     set.setDrawValues(true); 
     bd.addDataSet(set); 

     return bd; 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.combined, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.actionToggleLineValues: { 
       for (IDataSet set : mChart.getData().getDataSets()) { 
        if (set instanceof LineDataSet) 
         set.setDrawValues(!set.isDrawValuesEnabled()); 
       } 

       mChart.invalidate(); 
       break; 
      } 
      case R.id.actionToggleBarValues: { 
       for (IDataSet set : mChart.getData().getDataSets()) { 
        if (set instanceof BarDataSet) 
         set.setDrawValues(!set.isDrawValuesEnabled()); 
       } 

       mChart.invalidate(); 
       break; 
      } 
      case R.id.actionRemoveDataSet: { 

       int rnd = (int) getRandom(mChart.getData().getDataSetCount(), 0); 
       mChart.getData().removeDataSet(mChart.getData().getDataSetByIndex(rnd)); 
       mChart.getData().notifyDataChanged(); 
       mChart.notifyDataSetChanged(); 
       mChart.invalidate(); 
       break; 
      } 
     } 
     return true; 
    } 

    protected float getRandom(float range, float startsfrom) { 
     return (float) (Math.random() * range) + startsfrom; 
    } 

    @Override 
    public void onBackPressed() { 
     super.onBackPressed(); 
     overridePendingTransition(R.anim.move_left_in_activity, R.anim.move_right_out_activity); 
    } 

} 

回答

0

检查CombinedChartRendererBarLineChartBase的源代码。

基部渲染第一绘制数据。为CombinedChartRenderer,这意味着通过所有的子渲染器的迭代和绘图其数据(用于LineChart线和气泡的BubbleChart)。

之后,基础渲染器将渲染演员。对于CombinedChartRenderer,这意味着遍历所有的子渲染器并绘制他们的演员

因为LineChart中的圆圈是临时演员它们是在所有数据之后绘制的。这意味着您将不得不寻找某种方法重新排列渲染顺序以满足要求。您可以通过继承CombinedChart并重写protected void onDraw(Canvas canvas)方法来更改订单以符合您的自定义要求。

有一个完整的解决方案(包括代码)以解决您的问题this answer