MPAndroidChart icon indicating copy to clipboard operation
MPAndroidChart copied to clipboard

Custom Line Chart(Using limit line)

Open enes-sakut opened this issue 7 years ago • 16 comments

I want to draw this line chart and I added 3 limit lines.Chart's default color must be grey and if chart lower than 2.limit line chart color is must be green and higher than 3. limit line chart color is must be orange.How can I do that? This is the reference picture. @PhilJay @androideveloper

line

enes-sakut avatar Nov 16 '17 06:11 enes-sakut

It seems the rendering is done in LineChartRenderer which does not support limit lines. The quickest way would be to implement your own renderer. Set it by calling setRenderer().

Hope this helps :)

gcasar avatar Nov 21 '17 11:11 gcasar

@gcasar hi bro thank you) I tried this `ArrayList<String> xVals = new ArrayList<>(); for (int i = 0; i < 100; i++) { xVals.add((i) + ""); }

    ArrayList<Integer> colors = new ArrayList<>();
    ArrayList<Entry> yValue = new ArrayList<>();


    for (int i = 0; i <93; i=i+2) {
        int y = (int) (Math.random() * 50);

        yValue.add(new Entry(y,i));


        if ( y >= 0 && y <= 15 )
            colors.add( this.getResources().getColor( R.color.green) );
        else if ( y >= 16 && y <= 35 )
            colors.add( this.getResources().getColor( R.color.grey ) );
        else if ( y >= 36 && y <= 55 )
            colors.add( this.getResources().getColor( R.color.green ) );


    }

LineDataSet set1 = new LineDataSet(yValue, "DataSet 1"); set1.setCubicIntensity(1.0f); set1.setColors(colors); ` but its not to same my graphics))my code is wrong I think?

enes-sakut avatar Nov 21 '17 11:11 enes-sakut

To do it your way you should insert new values at correct spots to break the color at the limit line. So, for each new data point check if the new line segment would intersect any of your limit lines. If it does insert a new data point at the intersection.

Another posible solution is by overriding onDraw callback and drawing rectangles with paint.setXfermode(new PorterDuffXfermode(Mode.ADD));. Actually I suggest you do this, might be the simplest solution available.

gcasar avatar Nov 21 '17 15:11 gcasar

Hey thanks your suggestion but I don't know paint.setXfermode(new PorterDuffXfermode(Mode.ADD)); this.Do you have any source or example?

enes-sakut avatar Nov 22 '17 06:11 enes-sakut

@delhmela hello,I want to achieve this effect about your xaxis similar to the above picture

.Can you help me,thank you! 20171130160249

lqq1312 avatar Nov 30 '17 08:11 lqq1312

@lqq1312 hi bro, you can do this Xaxis effect two ways

  • ValueFormatter -Or manual(your xml design)

enes-sakut avatar Nov 30 '17 08:11 enes-sakut

@delhmela thanks,I try this way for custom the valueFormatter,but this effect is fail!Do you have any source or example?This is my test result,so bad! 162849

lqq1312 avatar Nov 30 '17 08:11 lqq1312

@lqq1312 I think valueformatter NOT BAD but I used visible Xaxis like this // set up the axis at the bottom of the graph XAxis x = holder.chart.getXAxis(); x.setPosition(XAxis.XAxisPosition.BOTTOM); x.setEnabled(false); x.setAvoidFirstLastClipping(false); and than I injected my design textViews("00.00") etc.Easy way)

enes-sakut avatar Nov 30 '17 08:11 enes-sakut

if use x.setEnabled(false); code,I find this verticaldashLine is invisable.How i can deal with this issue?thank your patient reply!thanks!!!

lqq1312 avatar Nov 30 '17 08:11 lqq1312

@lqq1312 I don't understand which verticaldashLine.Maybe you can use mChart.getData().setHighlightEnabled(false); this code for Vertical Highlight enabled or disabled.

enes-sakut avatar Nov 30 '17 09:11 enes-sakut

sorry,I should clear describe the verticaldashLine,it mean this picture mark. 20171130170726

lqq1312 avatar Nov 30 '17 09:11 lqq1312

@lqq1312 uppsy this is grid background.Use this code to visible all grid backgrounds chart.setDrawGridBackground(false);

enes-sakut avatar Nov 30 '17 09:11 enes-sakut

Same here. Any further progress since 2017 on this issue?

I believe community would have to do something about it.

thesiamak avatar Nov 01 '20 07:11 thesiamak

@enes-sakut , Hey bro. Have you found a solution?

thesiamak avatar Nov 01 '20 07:11 thesiamak

I achieved this by writing a subclass of the LineChartRenderer class and overriding the drawLinear (Canvas c, ILineDataSet dataSet)function. Replace the original mRenderPaint with a custom LinearGradient shader before canvas.drawLines(mLineBuffer, 0, size, mRenderPaint).

//mRenderPaint.setColor(dataSet.getColor());
mRenderPaint.setShader(new LinearGradient(0, mViewPortHandler.getContentRect().top,
    0, mViewPortHandler.getContentRect().bottom, colors, pos, Shader.TileMode.CLAMP));

canvas.drawLines(mLineBuffer, 0, size, mRenderPaint);

Image 001 Here I have three limit lines dividing the four zones.

float[] limits = {limit1, limit2, limit3};
float[] pos = new float[8];
float Ymax = ((LineChart) mChart).getAxisLeft().getAxisMaximum();
float Ymin = ((LineChart) mChart).getAxisLeft().getAxisMinimum();
// zone 1
pos[0] = 0f;
pos[1] = (Ymax - limits[2]) / (Ymax - Ymin);
// zone 2
pos[2] = (Ymax - limits[2]) / (Ymax - Ymin);
pos[3] = (limits[2] - limits[1]) / (Ymax - Ymin) + pos[1];
// zone 3
pos[4] = (limits[2] - limits[1]) / (Ymax - Ymin) + pos[1];
pos[5] = (limits[1] - limits[0]) / (Ymax - Ymin) + pos[3];
// zone 4
pos[6] = (limits[1] - limits[0]) / (Ymax - Ymin) + pos[3];
pos[7] = 1f;

int[] colors {zone4color, zone4color, zone3color, zone3color, zone2color, zone2color, zone1color, zone1color}

EvilOctopusFu avatar Sep 30 '22 05:09 EvilOctopusFu

This was very helpful to me today. Thanks @EvilOctopusFu

Prosquid1 avatar May 26 '23 18:05 Prosquid1