Комбинированная диаграмма MPAndroidChart (Bar

#android #mpandroidchart

#Android #mpandroidchart

Вопрос:

Я использую комбинированную диаграмму MPAndroidChart для отображения гистограммы и диаграммы рассеяния. При нажатии на точки графика рассеяния я показываю пользовательский маркер, который выглядит как показано ниже :

 public class YourMarkerView  extends MarkerView {

    private TextView tvContent;
    private RelativeLayout mainbackground;


    /**
     * Constructor. Sets up the MarkerView with a custom layout resource.
     *
     * @param context
     * @param layoutResource the layout resource to use for the MarkerView
     */
    public YourMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);
        tvContent = (TextView) findViewById(R.id.tvContent);
        mainbackground = (RelativeLayout) findViewById(R.id.mainbackground);

    }



    // callbacks everytime the MarkerView is redrawn, can be used to update the
    // content (user-interface)
    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        if(e!=null amp;amp; e.getData()!=null){
            Log.d("Yoyo",e.getData().toString());

            mainbackground.setBackgroundColor(Color.parseColor(e.getData().toString().split(";")[1]));

            tvContent.setText(""   e.getData().toString().split(";")[0]);

            // this will perform necessary layouting
            super.refreshContent(e, highlight);
        }

    }

    private MPPointF mOffset;

    @Override
    public MPPointF getOffset() {

        if(mOffset == null) {
            // center the marker horizontally and vertically
            mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
        }

        return mOffset;
    }
}
 

Ниже приведен код для диаграммы:

 chart.getDescription().setEnabled(false);
        chart.setBackgroundColor(Color.parseColor("#f9f9f9"));
        chart.setDrawGridBackground(false);
        chart.setDrawBarShadow(false);
        chart.setHighlightFullBarEnabled(false);

        // draw bars behind lines
        chart.setDrawOrder(new CombinedChart.DrawOrder[]{
                CombinedChart.DrawOrder.BAR, CombinedChart.DrawOrder.SCATTER
        });

        chart.getAxisRight().setEnabled(false);
        chart.getAxisLeft().setEnabled(false);
        chart.getXAxis().setEnabled(false);

        Legend legend = chart.getLegend();
        legend.setEnabled(false);

        YourMarkerView mv = new YourMarkerView(myActivity, R.layout.custom_marker_view);
        // Set the marker to the chart
        mv.setChartView(chart);
        chart.setMarker(mv);
        chart.setDragEnabled(false);
        chart.setScaleEnabled(false);

        // force pinch zoom along both axis
        chart.setPinchZoom(false);

        // enable touch gestures
        chart.setTouchEnabled(true);
        CombinedData data = new CombinedData();

        data.setData(generateBarData());
        data.setData(generateScatterData());

        chart.setData(data);
        chart.invalidate();

private BarData generateBarData() {

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

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

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

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

        BarDataSet set2 = new BarDataSet(entries2, "");
        set2.setStackLabels(new String[]{"Stack 1", "Stack 2"});
        set2.setColors(Color.rgb(61, 165, 255), Color.rgb(23, 197, 255));
        set2.setValueTextColor(Color.rgb(61, 165, 255));
        set2.setValueTextSize(10f);
        set2.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(set1, set2);
        d.setBarWidth(barWidth);

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

        return d;
    }

    private ScatterData generateScatterData() {

        ScatterData d = new ScatterData();
        ArrayList<Integer> colors = new ArrayList<Integer>();
        for (String color : details.getSequenceColors()) {
        colors.add(Color.parseColor(color));
        }
        ArrayList<Entry> entries = new ArrayList<>();

        for (float index = 0; index < count; index  = 0.5f)
            entries.add(new Entry(index   0.25f, getRandom(10, 55),"title;" colors.get(index)));

        ScatterDataSet set = new ScatterDataSet(entries, "Scatter DataSet");
        set.setDrawHorizontalHighlightIndicator(false);
        set.setDrawVerticalHighlightIndicator(false);
        set.setColors(colors);
        set.setScatterShape(ScatterChart.ScatterShape.CIRCLE);
        set.setScatterShapeSize(20f);
        set.setDrawValues(false);
        set.setValueTextSize(10f);
        d.addDataSet(set);

        return d;
    }
 

details.getSequenceColors — это простой pojo, содержащий список цветов. Для каждой точки на графике рассеяния я устанавливаю разные цвета. Я устанавливаю форму рассеяния.Цвет КРУГА и цвет фона маркера одинаковы на графике рассеяния. В соответствии с порядком рисования я сначала рисую гистограмму, а затем диаграмму рассеяния. Проблема, с которой я сталкиваюсь, заключается в том, что когда я нажимаю на область, где нет точек рассеяния, цвет фона маркера и цвет ближайшей точки рассеяния отличаются, и это также выделяет точку данных гистограммы. Он не показывает точный маркер на точках рассеяния, не знаю почему. Как я могу убедиться, что цвет круга рассеяния и цвет фона маркера всегда будут синхронизированы для каждой точки данных?

Ответ №1:

Решается с помощью пользовательского класса ScatterDataSet:

 public class MyScatterDataSet extends ScatterDataSet {
    static int currentIndex = 0;

    public MyScatterDataSet(List<Entry> yVals, String label) {
        super(yVals, label);
    }

    @Override
    public int getColor(int index) {
        int ret =super.getColor(currentIndex);
        currentIndex =1;
        return ret;
    }
}