【问题标题】:MpAndroidChart CombinedChart - How to prevent LineData circles being drawn over Bubble data?MpAndroidChart CombinedChart - 如何防止在气泡数据上绘制 LineData 圆圈?
【发布时间】:2017-01-04 18:34:52
【问题描述】:

我一直在玩官方CombinedChartActivity example 显示2个折线图,1个条形图和一些气泡数据。

尽管更改了DrawOrder...

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

...我的气泡仍然被线圈所吸引。正如您在此屏幕截图中看到的那样, 正确地出现在气泡后面;只是出现在气泡前面的圆圈线:

如何使圆圈表现得像它们的线条一样,所以它们也出现在气泡后面?

这是我的完整活动代码:

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);
    }

}

【问题讨论】:

    标签: android mpandroidchart


    【解决方案1】:

    检查CombinedChartRendererBarLineChartBase 的源代码。

    基础渲染器首先绘制数据。对于CombinedChartRenderer,这意味着遍历所有子渲染器并绘制它们的数据LineChart 的行和BubbleChart 的气泡)。

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

    因为 LineChart 中的圆圈是附加,所以它们是在所有数据之后绘制的。这意味着您必须找到某种方法来重新排列渲染顺序以满足要求。您可以先继承 CombinedChart 并覆盖 protected void onDraw(Canvas canvas) 方法来更改顺序以满足您的自定义要求。

    this answer中有一个与你类似的问题的完整解决方案(包括代码)

    【讨论】:

      猜你喜欢
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2022-07-12
      • 2021-12-13
      • 1970-01-01
      相关资源
      最近更新 更多