22

I'm plotting a bar chart using MPAndroid chart. Now all my bars have the same color but I want different colors for the bars based on Y axis values, like if value >100. color = red, like in the picture below. Is that possible? someone please help me.

enter image description here

Regards.

Community
  • 1
  • 1
Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104

6 Answers6

48

You can override the BarDataSet class to achieve this

public class MyBarDataSet extends BarDataSet {


    public MyBarDataSet(List<BarEntry> yVals, String label) {
        super(yVals, label);
    }

    @Override
    public int getColor(int index) {
        if(getEntryForXIndex(index).getVal() < 95) // less than 95 green
            return mColors.get(0);
        else if(getEntryForXIndex(index).getVal() < 100) // less than 100 orange
            return mColors.get(1);
        else // greater or equal than 100 red
            return mColors.get(2);
    }

}

And you need to define your colors like this:

MyBarDataSet set = new MyBarDataSet(yVals, "");
set.setColors(new int[]{ContextCompat.getColor(context, R.color.green), 
                ContextCompat.getColor(context, R.color.orange), 
                ContextCompat.getColor(context, R.color.red)});
ArrayList<BarDataSet> dataSets = new ArrayList<>();
dataSets.add(set);


BarData data = new BarData(xVals, dataSets);
m4n3k4s
  • 1,293
  • 1
  • 19
  • 21
  • 1
    Make sure on the dataset, that you dont also call set.setColor(..). This will make it so the getColor is never called. – Kalel Wade Nov 02 '15 at 16:23
  • @m4n3k4s This is the most ever needed solution for a BarChart where bar color depends on Y values. Thanks + 10. – Amit Trivedi May 01 '16 at 18:49
  • BarData data = new BarData(xVals, set);? because dataSets is not assigning. – Shadow May 18 '16 at 10:47
  • I'm using this, getApplicationContext().getResources().getColor(android.R.color.holo_orange_dark), but this seems deprecated...is there another line of code I could use to replace with? I'm just trying to get different colors like YELLOW, but using the line of code I attached not working. – neo Apr 01 '17 at 09:45
  • Hi @neo you should use ContextCompat.getColor(context, R.color.color_name). Meanwhile I updated the answer – m4n3k4s Apr 03 '17 at 08:07
  • hello @m4n3k4s , is there a way i can get something like this done as well for the RadarChart ??? Will so much appreciate your response. – Israel Meshileya Jul 19 '18 at 15:01
  • for the setWebColorInner – Israel Meshileya Jul 19 '18 at 21:09
  • Hi @IsraelMeshileya, did you tried extend RadarDataSet rather than BarDataSet? – m4n3k4s Jul 20 '18 at 10:57
  • I am actually using RadarDataSet..but, i did like to give each webline different color, don't know if that can be achieved @m4n3k4s – Israel Meshileya Jul 20 '18 at 14:30
6

You can find out the documentation about setting colors in MPAndroidChart from this link

    LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
  // sets colors for the dataset, resolution of the resource name to a "real" color is done internally
  setComp1.setColors(new int[] { R.color.red1, R.color.red2, R.color.red3, R.color.red4 }, Context);

  LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");
  setComp2.setColors(new int[] { R.color.green1, R.color.green2, R.color.green3, R.color.green4 }, Context);
Alex Chengalan
  • 8,211
  • 4
  • 42
  • 56
  • @AlexChengalan Can we set bar color based on entry (y-axis) value in MPAndroidChart? If not, please suggest the library which supports the same. – Karthikeyan Ve Jul 17 '15 at 07:21
  • 1
    @Alex Chengalan Can we set bar color based on entry (y-axis) value in MPAndroidChart? If not, please suggest the library which supports the same. – Karthikeyan Ve Jul 22 '15 at 14:00
  • How do I set the color according to the data value. Like for example if the data is less than 50 I would give green and if its more I will give red – viper Feb 06 '17 at 07:46
5

Thumbs up to the answer from @m4n3k4s. Just want to add some clarification with regards to these lines, since it took me a while to figure out:

set.setColors(new int[]{ContextCompat.getColor(context, R.color.green), 
            ContextCompat.getColor(context, R.color.orange), 
            ContextCompat.getColor(context, R.color.red)});

I didn't know what context was or how to use it until I found this thread. I replaced the lines above with:

barDataSet.setColors(
                ContextCompat.getColor(barchart.getContext(), R.color.green),
                ContextCompat.getColor(barchart.getContext(), R.color.yellow),
                ContextCompat.getColor(barchart.getContext(), R.color.red)
        );

Given that BarChart is a subclass of View, and getContext() is a method of the View class.

So my complete code looks like this, where KpBarDataSet is my class that overrides BarDataSet, and DateKp is a custom class.

BarChart barchart = (BarChart) findViewById(R.id.barchart);

    List<BarEntry> entries = new ArrayList<BarEntry>();
    List<String> dateLabels = new ArrayList<>();

    int i = 0;
    for (DateKp day : data) {
        // turn your data into Entry objects
        entries.add(new BarEntry(i, day.getValueY()));
        dateLabels.add(day.getLabel());
        i++;
    }

    KpBarDataSet barDataSet = new KpBarDataSet(entries, null);

    barDataSet.setColors(
            ContextCompat.getColor(barchart.getContext(), R.color.green),
            ContextCompat.getColor(barchart.getContext(), R.color.yellow),
            ContextCompat.getColor(barchart.getContext(), R.color.red)
    );

Lastly, R.color.green, R.color.red etc won't exist until you define them in /res/values/colors.xml.

Hope this helps.

Casey L
  • 617
  • 10
  • 16
2

I have done this for 3 colors, and it worked

if(floatArray.get(i) >= 0.0 && floatArray.get(i) <= max1)
            {
                barColorArray1[i] = Color.rgb(0, 128, 0);           
            }
            else if(floatArray.get(i) > max1 && floatArray.get(i) <= max2)
            {
                barColorArray1[i] = Color.rgb(247, 207, 19);                
            }
            else if(floatArray.get(i) > max2 )
            {
                barColorArray1[i] = Color.rgb(199, 0, 15);              
            }

In this i have created an array with integer values of colors. Lastly pass this in your BarDataSet as barDataSet1.setColors(barColorArray1);

Zeeshan Shabbir
  • 6,704
  • 4
  • 38
  • 74
Trojan Horse
  • 203
  • 2
  • 6
2

here is the class for MPAndroidChart:v3.0.2

class MyBarDataSet extends BarDataSet { 

    public MyBarDataSet(List<BarEntry> yVals, String label) {
        super(yVals, label);
    }

    @Override
    public int getColor(int index) {
        if(getEntryForIndex(index).getY() < 140)
            return mColors.get(0);
        else if(getEntryForIndex(index).getY() > 145)
            return mColors.get(1);
        else
            return mColors.get(2);
    }

}

0

Update

form m4n3k4 answer

public class MyBarDataSet extends BarDataSet {


    public MyBarDataSet(List<BarEntry> yVals, String label) {
        super(yVals, label);
    }

     @Override
    public int getColor(int index) {
        if(getEntryForIndex(index).getY() ==40) // less than 95 green
            return mColors.get(0);
        else if(getEntryForIndex(index).getY() ==30) // less than 100 orange
            return mColors.get(1);
        else // greater or equal than 100 red
            return mColors.get(2);
    }
}

and in JavaCode

 set1.setColors(ContextCompat.getColor(StepCountsActivity.this, R.color.purple),
                ContextCompat.getColor(StepCountsActivity.this, R.color.light_purple),
                ContextCompat.getColor(StepCountsActivity.this, R.color.blue));

    }
YuvrajsinhJadeja
  • 1,383
  • 7
  • 23