Hot questions for Chart Color in MPAndroidChart

MPAndroidChart I'd like to change the color of the graph at the top of the limit line

Question: I'd like to change the color of the graph at the top of the limit line. We've now implemented changing the color of chart bars across the limit line. But what I want to do is change the color of the chart where it crosses the limit line.

Answer: It seems that a normal BarChart data no longer suits your need. In order to stack different colours in the same bar, you'll need what's called a StackedBarChart

For using the aforementioned StackedBarChart (which is almost the same as the BarChart) you need to adapt the data and the colours for the data: for each bar you will need to add two values that will be painted differently

  1. The Y value below the limit -> let's call it A
  2. The Y value above the limit -> let's call it B

So here, A value cannot be higher than your limit. Let's give an example:

Limit = 10  
Total value = 12  
A = 10  
B = 2  

Then, you should input your data as follows (assuming the first bar starts at X=0):

BarEntry stackedEntry = new BarEntry(0f, new float[] { 10, 2 });

The colours: Once you've set the data, you just need to say the colours of each part of the Bar. Your bar will have two different colours, so the code should be something similar to this (kotlin code):

dataSet.color = listOf(LightBlue, Darkblue)

The dataSet here, is the object with all the BarEntries we have defined above.


MPandroidchart some dot's color doesn't change

Question: I'm making scatter chart that if value over specific value, the dot's color is changed.

I wrote codes like these.

for (int i = 0; i < 30; i++) 
{  
       float y = (float) (Math.random()*0.2+0.1);
       value1.add(new Entry(i, y));

        if(y>=0.2f)
        {
            colors.add(getBaseContext().getResources().getColor(R.color.color_red));
        }
        else
            colors.add(getBaseContext().getResources().getColor(R.color.color_skyblue));
       }
}

And the result is below.

As you can see, there is a line. Upper side's color should be red, lower side's color should be blue. And you can see the square that below the graph.

for example, the number of the squares is same as the number of circles, 9

but only one circle is blue.

I think there is no problem in my codes. But clearly there is a problem.

Answer: You can create two sets for the points above and below the reference and assign colors to the two sets.

ArrayList<Entry> aboveLevel = new ArrayList<>();
ArrayList<Entry> belowLevel = new ArrayList<>();

for (int i = 0; i < 30; i++){
    float y = (float) (Math.random()*0.2+0.1);
    if (y>=0.2f) {
       aboveLevel.add(new Entry(i, y));
    } else {
       belowLevel.add(new Entry(i, y));
    }
}

ScatterDataSet set1 = new ScatterDataSet(aboveLevel, "Above");
set1.setColor(ColorTemplate.COLORFUL_COLORS[0]);

ScatterDataSet set2 = new ScatterDataSet(belowLevel, "Below");
set2.setColor(ColorTemplate.COLORFUL_COLORS[1]);

ArrayList<IScatterDataSet> dataSets = new ArrayList<>();
dataSets.add(set1); // add the data sets
dataSets.add(set2);

// create a data object with the data sets
ScatterData data = new ScatterData(dataSets);

chart.setData(data);

How to change dot colors if value is higher than constant in MPAndroidChart

Question: I need to draw red circles if value higher than 3. How to realize that? I've read that I should override method drawCircles but I dont understand where I should do this.

LineDataSet set1;

    set1 = new LineDataSet(entries, "");
    chart.getLegend().setEnabled(false);

    set1.setColor(Color.WHITE);
    set1.setCircleColor(Color.WHITE);
    set1.setLineWidth(2f);
    set1.setCircleRadius(4f);
    set1.setValueTextSize(9f);
    set1.setValueTextColor(Color.WHITE);
    ArrayList<ILineDataSet> dataSets = new ArrayList<>();
    dataSets.add(set1); // add the datasets

    // create a data object with the datasets
    LineData data = new LineData(xVals, dataSets);
    chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
    chart.getAxisRight().setEnabled(false);
    chart.setScaleMinima(6f, 1f);
    if (measure.equals("co")) {
        LimitLine ll = new LimitLine(CO_CRITICAL, getResources().getString(R.string.critical_co));
        ll.setLineColor(Color.RED);
        ll.setLineWidth(1f);
        ll.setTextColor(Color.WHITE);
        ll.setTextSize(10f);
        chart.getAxisLeft().addLimitLine(ll);
    } else if (measure.equals("no2")) {
        LimitLine ll = new LimitLine(NO2_CRITICAL, getResources().getString(R.string.critical_no2));
        ll.setLineColor(Color.RED);
        ll.setLineWidth(1f);
        ll.setTextColor(Color.WHITE);
        ll.setTextSize(10f);
        chart.getAxisLeft().addLimitLine(ll);
    }

    // set data
    chart.setData(data);

Answer: Try with this:

Define one ArrayList:

ArrayList<Integer> color = new ArrayList<>();

And add your condition as:

if (YOUR_CONDITION) {
    color.add(ColorTemplate.rgb("#f8bf94"));
    yVals1.add(new Entry(VALUE, COUNTER));
} else {
    color.add(ColorTemplate.rgb("#e0e0e0"));
    yVals1.add(new Entry(VALUE, COUNTER));
}

And before adding dataset, add

set1.setColors(color);

MPAndroidChart I want to change dot color if the value over the constant

Question: I want to make a linechart that, for many values, if there are values that over constant, its dot color changed to another color.

what can i do?

here's my code

private void setData(int count, int range){
   ArrayList<Integer> color = new ArrayList<>();
   ArrayList<Entry> yVals1 = new ArrayList<>();
   for (int i=0; i<count; i++)
   {
    float val = (float) (Math.random()*range);
    if (val > 50){

        //color.add(Color.RED);
        //color.add(ColorTemplate.rgb("ff0000"));
        yVals1.add(new Entry(i, val));
    } else {


        //color.add(Color.BLACK);
       // color.add(ColorTemplate.rgb("000000"));
        yVals1.add(new Entry(i, val));
    }
}

Answer: First replace following line:

color.add(Color.RED);

with:

color.add(context.getResources().getColor(R.color.your_defined_color_in_colors_xml));

then after your code you need to add following line:

dataSet.setCircleColors(color);

How to set pie chart's label color?

Question: I am using mpandroidchart library for creating a pie chart.

I wanted to format text labels on the pie chart but I don't know how to do it. I tried it using

data.setValueTextColor(ContextCompat.getColor(getActivity(),R.color.black));

but, it only changes the value of data, not the labels. also, I wanted to be the label inside the pie chart I also tried that using the following code,

PieEntry entry2=new PieEntry(50-scratches,"Remaining \nScratches");

But, it didn't work.

My code is as follows:

private void setPiechart(float scratches) {

    List<PieEntry> values = new ArrayList<>();

    PieEntry entry1=new PieEntry(scratches,"Scratches");
    PieEntry entry2=new PieEntry(50-scratches,"Remaining \nScratches");

    values.add(entry1);
    values.add(entry2);

    PieDataSet dataSet = new PieDataSet(values,"");

    dataSet.setColors(ContextCompat.getColor(getActivity(),R.color.color_veridoc_gradient1),
            ContextCompat.getColor(getActivity(),R.color.colorBgChat));

    dataSet.setHighlightEnabled(true);
    dataSet.setAutomaticallyDisableSliceSpacing(true);

    dataSet.setSliceSpace(10);

    PieData data=new PieData(dataSet);
    data.setValueTextSize(20f);
    data.setValueTextColor(ContextCompat.getColor(getActivity(),R.color.black));


    pieChart.setData(data);
    Description description=new Description();
    description.setText("Scratches ");
    pieChart.setDescription(description);
    pieChart.setDrawHoleEnabled(true);
    pieChart.setHoleRadius(10f);

    pieChart.animateY(500);

    Legend legend = pieChart.getLegend();
    legend.setEnabled(true);

    legend.setTextColor(Color.BLACK);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        pieChart.setElevation(10);
    }

}

and the result I get is:

What I want to do is in nutshell

  1. change the label color inside the pie chart (from white to black)
  2. Prevent the label from going outside the pie chart. (e.g. Remaining Scratches as shown in image)

Can anybody help me with it?

Answer: To change the color of the label inside the pie chart use below code:

pieChart.setEntryLabelColor(Color.BLACK);

I assumed that pieChart is the view of your Pie chart graph view of XML i.e. pieChart = (PieChart) findViewById(R.id.chart1); If not then replace object of your view with pieChart

For value text color, you have already changed the color of it by the following code:

data.setValueTextColor(ContextCompat.getColor(getActivity(),R.color.black));

or you can use like

data.setValueTextColor(Color.BLACK);

Now, regarding the display label text in two line:

I think it is not possible to do it because the chart is drawn on canvas and canvas doesn't support multiline. If you want multiline you have to do some trick. To do it you have to modify MPAndroidChartLibrary.

So as an alternative, you can change the text size of the label as below:

pieChart.setEntryLabelTextSize(12f);  // You can increase or decrease value as per your need in argument

Also, you can apply TypeFace(Font) to that label as below:

pieChart.setEntryLabelTypeface(yourTypeFace);

how to change Bar color in MPandroidCharts based on some individual value stored in sqlite?

Question: If have an SQLite which stores 3 values names,credits,bunks. I have an mpandroid bar chart with x-axis:names,y-axis:bunks. I want to change the individual bar color or add limitline based on their credits for each entry,stored in SQLite. Is this possible?

public class Myhelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME="mydatabase.db";
    public static final String TABLE_NAME="mytable";
    public static final String COLUMN_ID="_id";
    public static final String COL_1="NAME";
    public static  final String COL_2="CREDIT";
    public  static final String COL_3="BUNKS";
    public static final String[] COLUMNS ={COLUMN_ID,COL_1,COL_2,COL_3};
    Context con;

    public Myhelper(Context context) {
        super(context, DATABASE_NAME, null, 1);
        con = context;
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable= "CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID +" INTEGER PRIMARY KEY AUTOINCREMENT, " + " NAME TEXT, CREDIT TEXT, BUNKS INTEGER )";
        db.execSQL(createTable);
        Toast.makeText(con,"table created",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS "+ TABLE_NAME);
        onCreate(db);

    }
    public boolean insertData(String x,String y,int z){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_1, String.valueOf(x));
        contentValues.put(COL_2,String.valueOf(y));
       contentValues.put(COL_3,z);
        long result = db.insert(TABLE_NAME, null, contentValues);
        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }

    public ArrayList<String> queryXdata(){
        ArrayList<String> xnewdata= new ArrayList<String>();
        String query = "SELECT "+ COL_1 + " FROM " + TABLE_NAME;
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cursor= db.rawQuery(query,null);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
            xnewdata.add(cursor.getString(cursor.getColumnIndex(COL_1)));
        }
        cursor.close();
        return xnewdata;

    }
    public ArrayList<Integer> queryYdata(){
        ArrayList<Integer> ynewdata= new ArrayList<Integer>();
        String query = "SELECT "+ COL_3+ " FROM " + TABLE_NAME;
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cursor= db.rawQuery(query,null);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
            ynewdata.add(cursor.getInt(cursor.getColumnIndex(COL_3)));
        }
        cursor.close();
        return ynewdata;

    }
    public  ArrayList<Integer> queryZdata(){
       ArrayList<Integer> znewdata= new ArrayList<Integer>();
        String query = "SELECT "+ COL_2+ " FROM " + TABLE_NAME;
        SQLiteDatabase db=this.getWritableDatabase();
        Cursor cursor= db.rawQuery(query,null);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
            znewdata.add(((cursor.getColumnIndex(COL_2))));
        }
        cursor.close();
        return znewdata;
    }

    public attendence getdetails(long id){
        SQLiteDatabase db = this.getWritableDatabase();
        String query= "SELECT" + COL_2+" FROM " + TABLE_NAME +" WHERE _id=" + id;
        Cursor cursor= db.rawQuery(query,null);
        attendence attendence1= new attendence();
        if (cursor.getCount()>0){
            cursor.moveToFirst();
            attendence1.setSubname(cursor.getString(cursor.getColumnIndex(COL_1)));
            attendence1.setCredit(cursor.getString(cursor.getColumnIndex(COL_2)));
            attendence1.setBunks(cursor.getInt(cursor.getColumnIndex(COL_3)));
        }
        return attendence1;
    }

    public void delete(long id,Context context){
        SQLiteDatabase db=this.getWritableDatabase();
        db.execSQL("DELETE FROM "+TABLE_NAME+" WHERE _id='"+id+"'");
        Toast.makeText(context,"delted",Toast.LENGTH_SHORT).show();
    }
    public List<attendence> list(String  filter){
        String query;
        if (filter.equals("")){
            query = "SELECT * FROM " + TABLE_NAME ;

        }
        else {
            query= " SELECT * FROM " + TABLE_NAME ;

        }
        List<attendence> linkedlist = new LinkedList<>();
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(query,null);
        attendence attendence;
        if (cursor.moveToFirst()){
            do {
                attendence = new attendence();
                attendence.setId(cursor.getLong(cursor.getColumnIndex(COLUMN_ID)));
                attendence.setSubname(cursor.getString(cursor.getColumnIndex(COL_1)));
                attendence.setCredit(cursor.getString(cursor.getColumnIndex(COL_2)));
                attendence.setBunks(cursor.getInt(cursor.getColumnIndex(COL_3)));
                linkedlist.add(attendence);
            }
            while (cursor.moveToNext());
        }
        return linkedlist;
    }


    public int getbunk(long id) {
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COLUMN_ID + " = " + String.valueOf(id), null);
        int output = -1;
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                output = cursor.getInt(cursor.getColumnIndex(COL_3));
            }
            cursor.close();
        }
        return output;

    }
    public int updatebunk(long id){
        SQLiteDatabase db = this.getWritableDatabase();
        int bunk = getbunk(id);
        if (bunk<0){
            Log.i("error", "updatebunk:below 0 ");

        }
        int bunkinc= ++bunk;
        ContentValues contentValues= new ContentValues();
        contentValues.put(COL_3, bunkinc);
        db.update(TABLE_NAME,contentValues,COLUMN_ID+ "=?",new String[]{String.valueOf(id)});
        db.close();

        return bunkinc;
    }
    public int updatebunkdelete(long id){
        SQLiteDatabase db = this.getWritableDatabase();
        int bunk = getbunk(id);
        int bunkdec= --bunk;
        ContentValues contentValues= new ContentValues();
        contentValues.put(COL_3,bunkdec);
        db.update(TABLE_NAME,contentValues,COLUMN_ID+ "=?",new String[]{String.valueOf(id)});
        db.close();
        return bunkdec;
    }
}

my activity(bar chart)

public  void addData(){
        ArrayList<BarEntry> yVals = new ArrayList<>();
        for (int i=0; i<myhelper.queryYdata().size(); i++){
            yVals.add(new BarEntry((((myhelper.queryYdata().get(i)))),i));
        }
        ArrayList<String> xvals= new ArrayList<>();
    for (int i=0;i<myhelper.queryXdata().size();i++){
        xvals.add(myhelper.queryXdata().get(i));
    }


    MyBarDataset dataSet= new MyBarDataset(yVals,"");
    dataSet.setColors(new int[]{ContextCompat.getColor(mcontext,R.color.green),
    ContextCompat.getColor(mcontext,R.color.yellow),
    ContextCompat.getColor(mcontext,R.color.red)});
    BarData data = new BarData(xvals,dataSet);
    mychart.setData(data);
    //bar custamization
    mychart.animateY(1000);
    mychart.setDrawGridBackground(false);
    mychart.setBackgroundColor(Color.WHITE);
    mychart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
    mychart.getAxisRight().setEnabled(false);
    mychart.setDescription("");
    mychart.getLegend().setEnabled(false);
    mychart.getXAxis().setDrawGridLines(false);
    mychart.getAxisLeft().setDrawGridLines(false);
    mychart.getAxisLeft().setStartAtZero(true);
    mychart.getAxisLeft().setAxisMinValue(0);


}
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()<8){
            return mColors.get(0);
        }
        else if (getEntryForXIndex(index).getVal()<13)
            return mColors.get(1);
        else
            return mColors.get(2);

    }
}

Answer: As I understand it, you want to plot the bars based on bunk but color them based on credits. Using the custom bar dataset is the right approach, just need to modify it a bit. The code below gets what you're describing.

Changes I made:

  1. Cannot pass list of names to BarData, use an axis value formatter instead
  2. Changed custom bar dataset to also hold the credits array. Not sure if your getEntryForXIndex method is defined elsewhere, but it's not in the code you posted.
  3. Removed deprecated calls and invalid syntax (can't call setDescription("");)

As far as I could tell the question was about the chart and not about the SQL database.

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

    BarChart chart = findViewById(R.id.test_chart);

    // Some made up data - replace these with your
    //  queryYdata, queryXdata, and queryZdata methods
    String[] names = new String[]{"foo","bar","fiz","bam","boo"};
    List<Float> credits = new ArrayList<>(Arrays.asList(1f,9f,2.5f,15f,50f));
    float[] bunks = new float[]{10f,15f,16f,20f,5f};

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

    float textSize = 16f;

    MyBarDataset dataSet = new MyBarDataset(entries, "data", credits);
    dataSet.setColors(ContextCompat.getColor(this,R.color.green),
            ContextCompat.getColor(this,R.color.yellow),
            ContextCompat.getColor(this,R.color.red));
    BarData data = new BarData(dataSet);
    data.setDrawValues(false);
    data.setBarWidth(0.9f);

    chart.setData(data);
    chart.setFitBars(true);
    chart.getXAxis().setValueFormatter(new IndexAxisValueFormatter(names));
    chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
    chart.getXAxis().setTextSize(textSize);
    chart.getAxisLeft().setTextSize(textSize);
    chart.setExtraBottomOffset(10f);

    chart.getAxisRight().setEnabled(false);
    Description desc = new Description();
    desc.setText("");
    chart.setDescription(desc);
    chart.getLegend().setEnabled(false);
    chart.getXAxis().setDrawGridLines(false);
    chart.getAxisLeft().setDrawGridLines(false);

    chart.invalidate();
}

public class MyBarDataset extends BarDataSet{

    private List<Float> credits;

    MyBarDataset(List<BarEntry> yVals, String label, List<Float> credits) {
        super(yVals, label);
        this.credits = credits;
    }

    @Override
    public int getColor(int index){
        float c = credits.get(index);

        if (c < 8){
            return mColors.get(0);
        }
        else if (c < 13) {
            return mColors.get(1);
        }
        else {
            return mColors.get(2);
        }
    }
}

An aside about the SQL database - don't call queryXData and queryYData inside the loop! This will extract the entire data array every loop iteration, then again inside the loop itself (very expensive). Just use something like this instead:

ArrayList<BarEntry> yVals = new ArrayList<>();
ArrayList<Integer> yData = myhelper.queryYdata();
for (int i=0; i<yData.size(); i++){
    yVals.add(new BarEntry(i,yData.get(i)));
}

ArrayList<String> xData = myhelper.queryXdata();

How can i set color in PieChart of MPAndroidChart

Question: I try to set color in PieChart of MPAndroidChart.But its not set it.I want to add custom color in my partition . Here is my code :

fun setupPieChartView() {
    mPie = findViewById(R.id.piechart)

    mPie?.setUsePercentValues(true)

    val desc: Description = Description()
    desc.text = "PieChart"
    mPie?.description = desc

    val legend: Legend? = mPie?.legend
    legend?.horizontalAlignment = Legend.LegendHorizontalAlignment.LEFT

    val value = Arrays.asList(trueAns.toFloat(), wrongAns.toFloat(), noAns.toFloat())
    val label = Arrays.asList("True", "false", "Not")

    val entry = ArrayList<PieEntry>()
    for (i in value.indices) {
        entry.add(PieEntry(value.get(i), label.get(i)))

    }


    val dataSet = PieDataSet(entry, "Result")
    dataSet.setDrawValues(true)

    val pieData = PieData(dataSet)
    pieData.setValueFormatter(PercentFormatter())
    pieData.setValueTextSize(10f)
    pieData.setValueTextColor(Color.WHITE)

    mPie?.data = pieData
}

Answer: Instead of this

dataSet.colors = ColorTemplate.COLORFUL_COLORS.toList()

it should be

dataSet.setColors(Color.RED, Color.GREEN, Color.BLUE);  

Because first one gives default colors, that's why you can't override colors. Here is result of your code