简体   繁体   English

MPAndroidChart LineChart自定义高亮显示drawable

[英]MPAndroidChart LineChart custom highlight drawable

I'm using MPAndroid Chart library to draw Line Chart in my Android app. 我正在使用MPAndroid Chart库在我的Android应用程序中绘制折线图。 The status of graph is like: 图的状态如下: MPAndroidChart  - 折线图

I want to change it like this: 我想改变它:

折线图

So I want to change MPAnroid Line Chart's points, ts called "Circle Hole" in library. 所以我想改变MPAnroid Line Chart的点,在图书馆中称为“圆孔”。 I want to switch this hole to drawable. 我想把这个洞换成可画的。 There is a way I can do that? 我有办法做到这一点吗?

The circle hole change code is here: 圆孔更改代码在这里:

LineDataSet set1 = new LineDataSet(yVals, "DataSet 1");
set1.setDrawCircleHole( true );
set1.setCircleColor( Color.BLACK );

Library reference is here: MPAndroidChart 库参考在这里: MPAndroidChart

Since version 3.0 you can provide your own custom image that will be displayed on selecting a given point on the chart. 从版本3.0开始,您可以提供自己的自定义图像,该图像将在选择图表上的给定点时显示。 The instructions below are as per the wiki 以下说明是根据维基

To summarise, you can now use the class called MarkerImage : 总而言之,您现在可以使用名为MarkerImage的类:

MarkerImage myMarkerImage = new MarkerImage(this, R.drawable.my_drawable);

Then: 然后:

myChart.setMarker(myMarkerImage);

To adjust the position of the image, you can call: 要调整图像的位置,您可以调用:

setOffset(float x, float y);

If you don't want to use MarkerView , you would probably have to make your own sub-class of LineChartRenderer and add logic to draw your custom highlight drawable. 如果您不想使用MarkerView ,您可能必须创建自己的LineChartRenderer子类并添加逻辑来绘制自定义高亮显示。

Here is a very basic proof of concept: 这是一个非常基本的概念证明:

import android.graphics.Bitmap;
import android.graphics.Canvas;

import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.renderer.LineChartRenderer;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;

import java.util.List;

/**
 * Created by David on 3/01/2017.
 */

public class ImageLineChartRenderer extends LineChartRenderer {

    private final LineChart lineChart;
    private final Bitmap image;

    public ImageLineChartRenderer(LineChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Bitmap image) {
        super(chart, animator, viewPortHandler);
        this.lineChart = chart;
        this.image = image;
    }

    @Override
    public void drawExtras(Canvas c) {
        super.drawExtras(c);

        Highlight[] highlighted = lineChart.getHighlighted();
        if (highlighted == null) return;

        float phaseY = mAnimator.getPhaseY();

        float[] imageBuffer = new float[2];
        imageBuffer[0] = 0;
        imageBuffer[1] = 0;
        LineData lineData = mChart.getLineData();
        List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();

        Bitmap[] scaledBitmaps = new Bitmap[dataSets.size()];
        float[] scaledBitmapOffsets = new float[dataSets.size()];
        for (int i = 0; i < dataSets.size(); i++) {
            float imageSize = dataSets.get(i).getCircleRadius() * 10;
            scaledBitmapOffsets[i] = imageSize / 2f;
            scaledBitmaps[i] = scaleImage((int) imageSize);
        }

        for (Highlight high : highlighted) {
            int dataSetIndex = high.getDataSetIndex();
            ILineDataSet set = lineData.getDataSetByIndex(dataSetIndex);
            Transformer trans = lineChart.getTransformer(set.getAxisDependency());

            if (set == null || !set.isHighlightEnabled())
                continue;

            Entry e = set.getEntryForXValue(high.getX(), high.getY());

            if (!isInBoundsX(e, set))
                continue;

            imageBuffer[0] = e.getX();
            imageBuffer[1] = e.getY() * phaseY;
            trans.pointValuesToPixel(imageBuffer);

            c.drawBitmap(scaledBitmaps[dataSetIndex],
                    imageBuffer[0] - scaledBitmapOffsets[dataSetIndex],
                    imageBuffer[1] - scaledBitmapOffsets[dataSetIndex],
                    mRenderPaint);
        }
    }

    private Bitmap scaleImage(int radius) {
        return Bitmap.createScaledBitmap(image, radius, radius, false);
    }
}

Consume it like this: 像这样消费:

Bitmap starBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star);
mChart.setRenderer(new ImageLineChartRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), starBitmap));

Explanation: drawExtras in LineChartRenderer draws the circles. 说明: LineChartRenderer中的drawExtras绘制圆圈。 We still want these, so in our drawExtras override we call super first. 我们仍然想要这些,所以在我们的drawExtras覆盖中,我们先调用super。 Then we generate a scaled bitmap for each DataSet (DataSets may have different circle radii). 然后我们为每个DataSet生成一个缩放的位图(DataSet可能有不同的圆半径)。 We scale the bitmaps to an arbitrary size (10x the circle radius). 我们将位图缩放到任意大小(圆半径的10倍)。 We then iterate through the Highlights exposed through the LineChart field of our renderer and draw the appropriate bitmap. 然后,我们遍历通过渲染器的LineChart字段公开的高光,并绘制相应的位图。

Here is a screenshot - you can see the 'star' bitmap instead of the circle on the highlighted index: 这是一个截图 - 您可以在突出显示的索引上看到'star'位图而不是圆圈:

在突出显示的点处使用星形而不是圆形的折线图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM