MpChart在条形图的Xaxis中绘制图标作为标签

时间:2017-07-15 03:13:48

标签: android mpandroidchart

enter image description here您好我想在条形图的x轴中绘制图标而不是值。如下图所示

3 个答案:

答案 0 :(得分:10)

您必须创建自己的自定义渲染器并将其应用于图表。这是一个粗略的实现。

<强> XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="250dp"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.sauvik.samplegraphs.MainActivity">

    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/chart1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

<强>活动

public class MainActivity extends AppCompatActivity {

    private BarChart mChart;
    int val[] = {3, 2, 7, 3, 4, 8};
    ArrayList<Bitmap> imageList = new ArrayList<>();

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

        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_grade);
        imageList.add(bitmap);
        imageList.add(bitmap);
        imageList.add(bitmap);
        imageList.add(bitmap);
        imageList.add(bitmap);
        imageList.add(bitmap);

        mChart = (BarChart) findViewById(R.id.chart1);

        mChart.setDrawBarShadow(false);
        mChart.setDrawValueAboveBar(true);
        mChart.getDescription().setEnabled(false);
        mChart.setPinchZoom(false);
        mChart.setDrawGridBackground(false);


        XAxis xAxis = mChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawGridLines(false);
        xAxis.setGranularity(1f);
        xAxis.setLabelCount(7);
        xAxis.setDrawLabels(false);


        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.setAxisLineColor(Color.WHITE);
        leftAxis.setDrawGridLines(false);
        leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)

        YAxis rightAxis = mChart.getAxisRight();
        rightAxis.setEnabled(false);
        Legend l = mChart.getLegend();
        l.setEnabled(false);
        setData();

    }

    private void setData() {

        ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
        for (int i = 0; i < val.length; i++) {
            yVals1.add(new BarEntry(i, val[i]));
        }

        BarDataSet set1;

        set1 = new BarDataSet(yVals1, "");

        set1.setColors(Color.BLUE);
        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);

        BarData data = new BarData(dataSets);
        data.setDrawValues(false);
        mChart.setData(data);
        mChart.setScaleEnabled(false);
        mChart.setRenderer(new BarChartCustomRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), imageList, this));
        mChart.setExtraOffsets(0, 0, 0, 20);

    }

}

CUSTOM RENDERER

public class BarChartCustomRenderer extends BarChartRenderer {

    private Context context;
    private ArrayList<Bitmap> imageList;

    public BarChartCustomRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, ArrayList<Bitmap> imageList, Context context) {
        super(chart, animator, viewPortHandler);
        this.context = context;
        this.imageList = imageList;
    }

    @Override
    public void drawValues(Canvas c) {
        List<IBarDataSet> dataSets = mChart.getBarData().getDataSets();
        final float valueOffsetPlus = Utils.convertDpToPixel(22f);
        float negOffset;

        for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {

            IBarDataSet dataSet = dataSets.get(i);
            applyValueTextStyle(dataSet);
            float valueTextHeight = Utils.calcTextHeight(mValuePaint, "8");
            negOffset = valueTextHeight + valueOffsetPlus;

            BarBuffer buffer = mBarBuffers[i];

            float left, right, top, bottom;

            for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {

                left = buffer.buffer[j];
                right = buffer.buffer[j + 2];
                top = buffer.buffer[j + 1];
                bottom = buffer.buffer[j + 3];

                float x = (left + right) / 2f;

                if (!mViewPortHandler.isInBoundsRight(x))
                    break;

                if (!mViewPortHandler.isInBoundsY(top) || !mViewPortHandler.isInBoundsLeft(x))
                    continue;

                BarEntry entry = dataSet.getEntryForIndex(j / 4);
                float val = entry.getY();
                mValuePaint.setTextAlign(Paint.Align.CENTER);
                if (val > 0) {

                    drawValue(c, dataSet.getValueFormatter(), val, entry, i, x,
                            (bottom + negOffset),
                            dataSet.getValueTextColor(j / 4));
                }

                Bitmap bitmap = imageList.get(j / 4);

                if (bitmap != null) {
                    Bitmap scaledBitmap = getScaledBitmap(bitmap);
                    c.drawBitmap(scaledBitmap, x - scaledBitmap.getWidth() / 2f, (bottom + 0.5f * negOffset) - scaledBitmap.getWidth() / 2f, null);
                }
            }
        }
    }


    private Bitmap getScaledBitmap(Bitmap bitmap) {
        int width = (int) context.getResources().getDimension(R.dimen.dimen_18);
        int height = (int) context.getResources().getDimension(R.dimen.dimen_18);
        return Bitmap.createScaledBitmap(bitmap, width, height, true);
    }


}

<强> RESULT

enter image description here

您可以用自己的图像替换星星。

如果您想知道自定义渲染器的工作原理 请检查此link

答案 1 :(得分:0)

我已经找到了如何做到这一点非常容易:

添加另一个值设置为-1的数据集,并在创建该条目时提供drawable:setStartAtZero(false)

使用for (var i=0,length=variant.options.length; i<length; i++) { var radioButton = $productForm.find('.swatch[data-option-index="' + escape(i) + '"] :radio[value="' + variant.options[i].replace(/\"/g,'\\"') +'"]'); if (radioButton.length) { radioButton.get(0).checked = true; } } 启用负值绘制。 将数据集颜色设置为透明,以使此数据集对用户不可见。

我承认,这是一个非常hacky的解决方案,但它很容易,并且不需要从lib复制粘贴和重写代码,因此更容易维护更新。

答案 2 :(得分:0)

基于sauvik的回答,我在Kotlin中为MPAndroidChart v3.1.0编写了更新版本。 sauvik的实现似乎不适用于当前版本。

完整的Renderer类可以在here中找到。

它的用法如下(从BarChart子类内部):

Dim files as string() = IO.Directory.GetFiles(sPath, "*.adi", IO.SearchOption.TopDirectoryOnly)

...,其中init { renderer = BarChartIconRenderer(this, animator, viewPortHandler, mBarXAxisIcons, context) } 是要添加位图的mBarXAxisIcons

此外,您需要在上面链接的类中添加维度ArrayList<Bitmap>,或自定义barchart_icon_size函数。

渲染器存在一个问题:条形图顶部的标签绘制得比平时高一些,我不知道为什么,但是尝试找出并相应地更新此答案。

enter image description here