【问题标题】:MpChart Draw icons as labels in Xaxis of bar chartMpChart 在条形图的 X 轴中将图标绘制为标签
【发布时间】:2017-07-15 03:13:48
【问题描述】:

Hi 我想在条形图的 xaxis 中绘制图标而不是值。如下图所示

【问题讨论】:

    标签: android mpandroidchart


    【解决方案1】:

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

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

    自定义渲染器

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

    结果

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

    如果您想了解自定义渲染器的工作原理 检查这个link

    【讨论】:

    • 不错的答案+1!
    • 你有折线图的解决方案吗?
    • @felipe.rce 这是同一个概念。你必须创建一个扩展 LineChartRenderer 的类
    • @sauvik 你能帮我解答我的问题吗? stackoverflow.com/questions/58503297/…
    【解决方案2】:

    我发现如何做到这一点非常简单:

    添加另一个值设置为 -1 的数据集,并在创建该条目时提供一个可绘制对象:new Entry(i, value, icon)

    使用setStartAtZero(false) 启用负值绘制。 将数据集颜色设置为透明,以使该数据集对用户不可见。

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

    【讨论】:

      【解决方案3】:

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

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

      它是这样使用的(从 BarChart 子类内部):

      init {
          renderer = BarChartIconRenderer(this, animator, viewPortHandler,
              mBarXAxisIcons, context)
      }
      

      ...mBarXAxisIcons 是您添加位图的 ArrayList&lt;Bitmap&gt;

      另外,需要添加维度barchart_icon_size,或者在上面链接的类中自定义getScaledBitmap函数。

      渲染器有一个问题:条形顶部的标签比平时高一点,我还不知道为什么,但试图找出并相应地更新这个答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-04
        • 2021-07-24
        • 1970-01-01
        • 2019-12-19
        • 1970-01-01
        • 2017-10-30
        • 1970-01-01
        相关资源
        最近更新 更多