I am using mpandroidchart and I want to draw a circle only for one Entry in the LineDataSet but not the rest. I have tried to accomplish it using two LineDataSets but it hasn't worked so far. Here's my code:
LineDataSet scoreDataSet = new LineDataSet(values, "Score");
scoreDataSet.setDrawCircles(false);
// Entry with max value is the last one
Entry circleEntry = scoreDataSet.getEntryForXIndex(scoreDataSet.getEntryCount()-1);
LineDataSet circularDataSet = new LineDataSet(values, "Score");
circularDataSet.setDrawCircles(true);
int size = circularDataSet.getEntryCount()-1;
for (int i=0; i<size; i++) {
if (i != circleEntry.getXIndex()) {
circularDataSet.removeEntry(circularDataSet.getEntryForXIndex(i));
}
}
.
.
.
ArrayList<LineDataSet> dataSets = new ArrayList<LineDataSet>();
dataSets.add(scoreDataSet);
dataSets.add(circularDataSet);
This just prints a dot(circularDataSet) and not the scoreDataSet. I was expecting it to merge both the DataSets so as to mark the highest value with a circle and drawing the rest as a line chart.
Your approach looks good in general, there are just a few flaws.
Don't create the "circularDataSet" and initialize it with the same values like the "scoreDataSet" and then remove all except one.
What you should do instead is find the largest entry in your "scoreDataSet", and then only add this single entry to the "circularDataSet".
Related
I have made pie charts using mp-android chart.I have placed 9 charts in a grid but there is extra spaces between them.I need to remove those necessary spaces and make the edges touch each other.
This is the java method which inflates each piechart,I have tried the previous answers but nothing works.
static void makePie(PieChart pieChart, int type, boolean spin, Context con){
pieChart.setExtraOffsets(-30, -30, -30, -30);
ArrayList<PieEntry> yvalues = new ArrayList<>();
for(int i=0;i<type;i++){
yvalues.add(new PieEntry(10F, ""));
}
PieDataSet dataSet = new PieDataSet(yvalues, "Net Worth");
ArrayList<String> xVals = new ArrayList<String>();
PieData data = new PieData(dataSet);
pieChart.setCenterTextColor(Color.BLACK);
pieChart.setData(data);
pieChart.setDrawHoleEnabled(false);
final int[] MY_COLORS = {
Color.rgb(246,230,196),
Color.rgb(200,237,253),
Color.rgb(252,199,202),
Color.rgb(179,233,216),
Color.rgb(247,233,174),
Color.rgb(211,211,246),
Color.rgb(108,59,57),
Color.rgb(75,132,138),
Color.rgb(124,96,66),
Color.rgb(247,173,89),
Color.rgb(235,108,63),
Color.rgb(208,75,52),
Color.rgb(255,202,39),
Color.rgb(147,37,166),
Color.rgb(22,158,250),
Color.rgb(118,7,47),
Color.rgb(44,183,80),
Color.rgb(100,22,151),
Color.rgb(88,42,71),
Color.rgb(27,40,121),
Color.rgb(29,112,74),
Color.rgb(252,216,82),
Color.rgb(247,99,64),
Color.rgb(232,57,52)
};
ArrayList<Integer> colors = new ArrayList<Integer>();
dataSet.setColors(colors);
for(int i=0;i<type;i++){
colors.add(getRandom(MY_COLORS));
}
List<LegendEntry> entries = new ArrayList<>();
dataSet.setDrawValues(false);
data.setValueTextSize(16f);
data.setValueTextColor(Color.DKGRAY);
pieChart.getDescription().setEnabled(false);
pieChart.setTransparentCircleAlpha(0);
pieChart.getLegend().setEnabled(false);
pieChart.setRotationEnabled(false);
pieChart.setClickable(false);
pieChart.setTouchEnabled(false);
pieChart.setExtraOffsets(-10,0,-10,0);
pieChart.invalidate();
if(spin){
Animation animation = AnimationUtils.loadAnimation(con, R.anim.rotate);
pieChart.startAnimation(animation);
}
}
https://drive.google.com/open?id=1mIPMjFW3BlWhWLfQWIV65sfx9FO091pv
This is the output, there are spaces between the grids, which is taking too much space, andneeded to be removed so that the piecharts touch each other,
I've tried my self then I changed the setExtraOffsets in your code
it had an effect on the padding of your view but the shape was not circled any more
I recommend to remove setExtraOffsets in your code and see the result.
mention that you are using setExtraOffsets two parts of your code
I am using MPAndroidChart to generate a simple bar chart, inside a collapsing toolbar. When I add entries, the value of the entry is visible at the correct height on the chart, but I can't see the bar.
This is how I create my variables:
final List<BarEntry> barEntries = new ArrayList<>();
final BarDataSet barDataSet = new BarDataSet(barEntries, getResources().getString(R.string.cycles_profiled));
final BarData barData = new BarData(barDataSet);
This is how I populate the data and refresh the chart:
final Calendar cal = getFirstDayOfWeek();
for (int i = 0; i < NUMBER_OF_DAYS; i++) {
long date = cal.getTimeInMillis();
barEntries.add(new BarEntry(date, map.get(date)));
cal.add(Calendar.DAY_OF_WEEK, 1);
}
barDataSet.setValues(barEntries);
barChart.setData(barData);
barData.notifyDataChanged();
barChart.notifyDataSetChanged();
barChart.invalidate();
I have no problem creating bar charts in other parts of my app. When I draw linecharts inside the collapsing toolbar, it also works fine.
Had the same issue, solved it thanks to OumaSyuu.
For some reason the BarChart has a difficulty with milliseconds.. convert your milliseconds to minutes: TimeUnit.MILLISECONDS.toMinutes(millisecondValue) and your life will be honey!
If converting to minutes doesn't help try to a different (higher) time unit. The time unit that will be good for you is the average gap between the bars, for me it was hours.
Another interesting point that may help you style the chart - In the method setBarWidth(float mBarWidth), the input mBarWidth represent values not pixels.
i was facing the same issue when i used timestamp for X axis values which was reported as a bug in the library, so i came out with the following solution
first create an arraylist:
ArrayList<String> xAxis_stringArray = new ArrayList<>();
and then while you add the entries to the entry list, set the x value to be the index of the data source (string value) and add the string value to the string array like that:
jsonObject = results.getJSONObject(index);
String s = jsonObject.getString(x);
xAxis_stringArray.add(s);
entries.add(new Entry(Float.valueOf(index), Float.valueOf(jsonObject.getString(y))));
and finally refer the xAxis to the value formatter class:
XAxis xAxis = sum_chart.getXAxis();
xAxis.setValueFormatter(new TimeAxisValueFormatter(xAxis_stringArray));
TimeAxisValueFormatter class:
public class TimeAxisValueFormatter implements IAxisValueFormatter {
ArrayList<String> arrayList = new ArrayList<>();
public TimeAxisValueFormatter(ArrayList<String> list) {
this.arrayList = list;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
return arrayList.get(Math.round(value));
}}
You are missing to set .setColor
Try with
barDataSet.setColor(Color.rgb(0, 155, 0)); //Put your RGB Color
I had the same problem just now, for me increasing the barwidth solved the problem. I think the problem lays with how spread out your data is which impacts the width of the lines. If you have a dataset that is only spread out over an hour and has entry for every minute of that hour, I think this problem won't exist. But if you are like me and have sparse data over 5 hours or so, then the barwidth just become smaller and smaller to accommodate all those entries and the bar just disappears.
Example:
data.setBarWidth(2f);
When I increased the barwidth to 80f:
data.setBarWidth(80f);
I´m working with MPAndroid charts on my app to draw a chart from my sqlite database using "weight" values for the Y axes and "date" values for the X axes.
The problem is that just some rows of my database have that weight value. When all the rows have the weight layout my code works like a charm, but when there is a row that doesn´t have weight value, and the next one contains that weight value, it leaves a space on the YAxes of the chart, altought the date value is set on XAxes. As a result of that, a value is missed on Y Axes for every row without the weight value, because the value that comes after the weight row is moved one point forward. For example:
I have this code for setting up the chart:
public void setUpCharts(){
chart = (LineChart) rootView.findViewById(R.id.weightChart);
chart.setNoDataTextDescription("Nothing");
chart.setDrawBorders(false);
chart.setDescription("");
chart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
chart.getAxisRight().setEnabled(false);
chart.getAxisLeft().setEnabled(false);
chart.getAxisLeft().setDrawGridLines(false);
chart.getAxisRight().setDrawGridLines(false);
chart.getXAxis().setDrawGridLines(false);
chart.getXAxis().setDrawAxisLine(false);
chart.getLegend().setEnabled(false);
chart.setScaleEnabled(false);
chart.setPinchZoom(false);
chart.setDoubleTapToZoomEnabled(false);
weights = new ArrayList<>(); //Pesos
dates = new ArrayList<String>(); //Días del mes
getChartData();
LineDataSet dataSet = new LineDataSet(weights, "Weights");
dataSet.setDrawCubic(false);
dataSet.setCircleRadius(4);
dataSet.setLineWidth(3);
dataSet.setDrawValues(true);
dataSet.setColor(getContext().getResources().getColor(R.color.colorWeightChart));
dataSet.setCircleColor(getContext().getResources().getColor(R.color.colorWeightChart));
dataSet.setCircleColorHole(getContext().getResources().getColor(R.color.colorWeightChart));
LineData data = new LineData(dates, dataSet);
chart.setData(data);
//LimitLine
String weight_get = PreferenceManager.getDefaultSharedPreferences(getContext()).getString("Goal_weight", null);
if(!weight_get.equals(null) && !weight_get.equals("")){
float weight_goal = Float.valueOf(weight_get);
YAxis leftAxis = chart.getAxisLeft();
LimitLine ll = new LimitLine(weight_goal);
ll.setLineColor(getContext().getResources().getColor(R.color.weightTabFAB));
ll.setLineWidth(1f);
ll.enableDashedLine(10f, 10f, 0f);
leftAxis.addLimitLine(ll);
float YMax= dataSet.getYMax();
if(weight_goal > YMax){
float difference = weight_goal - YMax;
chart.getAxisRight().setAxisMaxValue(weight_goal + difference); //So the limit line will be always visible
chart.getAxisLeft().setAxisMaxValue(weight_goal + difference);
}
}
chart.setVisibleXRangeMaximum(5f);
}
And I use getChartData to set up all the chart data getting the values from my sqlite database. It´s supposed to add just the values of rows in which weight exists, and in fact the log shows that it works correctly, so I don´t know how can I fix it.
protected void getChartData(){
IDs = new ArrayList<Integer>();
Cursor data = dataSource.getAllItems();
if(data!=null) {
while(data.moveToNext()){
int id = data.getInt(data.getColumnIndex(RecordsDataSource.ColumnRecords.ID_RECORDS));
String weight= data.getString(data.getColumnIndex(RecordsDataSource.ColumnRecords.WEIGHTS_RECORDS));
if(weight!=null && !weight.equals("")){
long milisDate =data.getLong(data.getColumnIndex(RecordsDataSource.ColumnRecords.DATES_RECORDS));
String date = Utils.milisToDate(milisDate, "dd/MM");
IDs.add(id);
weights.add(new Entry(Float.valueOf(weight), id -1));
dates.add(date);
Log.i("ID "+ String.valueOf(id),"Not null, "+ weight);
}else{
Log.i("ID "+ String.valueOf(id), "Null");
}
}
data.close();
}
}
I have been all the day trying to solve this issue, but nothing has worked.
Could somebody help me please?
By the way, sorry for my bad English.
The problem is in your id in getChartData() method. The id is skipping your chart Entry position.
Instead of this
weights.add(new Entry(Float.valueOf(weight), -1));
Add a variable for entry index and increment it on each iteration
index++;
weights.add(new Entry(Float.valueOf(weight), index));
It should work.
I want to delimit on vertical values between 13 and 14 not this is how it looks my linear chart, always starts on 0 as the starting limit, I want to be something around 13. Please see the image on the next link to see what I am talking about, I am attaching the piece of code for it enter image description here
LineChart lineChart = (LineChart) rootView.findViewById(R.id.chart);
LineData data = new LineData(labels, dataset);
dataset.setColors(ColorTemplate.COLORFUL_COLORS); //
dataset.setDrawCubic(true);
dataset.setDrawFilled(true);
lineChart.setData(data);
lineChart.animateY(5000);
Finally I got the answer about this, you can check it here
LineChart lineChart = (LineChart) rootView.findViewById(R.id.chart);
LineData data = new LineData(labels, dataset);
lineChart.getAxisLeft().setLabelCount(2, true);
lineChart.getAxisRight().setEnabled(false);
lineChart.getAxisLeft().setStartAtZero(false);
lineChart.setAutoScaleMinMaxEnabled(false);
lineChart.getAxisLeft().setAxisMaxValue(maxYval + 1);
lineChart.getAxisLeft().setAxisMinValue(minYval - 1);
dataset.setColors(ColorTemplate.COLORFUL_COLORS); //
dataset.setValueTextSize(10);
dataset.setDrawCubic(true);
dataset.setDrawFilled(true);
lineChart.setData(data);
lineChart.animateY(10);
How not to show the highlighted bottom labels in pie chart?
And how to change entries text color?
You can do that by setting the setDrawLegend property to false.
Wherever you initialize your pieChart just add the following line:
pieChart.setDrawLegend(false);
[EDIT]
About changing the colors this is what you can do:
First of all this is happening when you add some data to your chart. When you add the data you add a PieData object to the chart. This PieData object takes 2 arguments, the names, and the values. The list of names is an ArrayList of Strings, but the values need to be an instance of a PieDataSet object. This is where you can add the colors and add other properties as well(such as the spacing between slices). Also, the PieDataSet object wraps up the Y values of a set and the label for this. And finally the PieDataSet's values are an ArrayList of Entry objects. One single Entry object takes the value to be shown, and it's index on the chart.
Here is a sample DEMO code that illustrates the above short description:
ArrayList<Entry> yChartValues = new ArrayList<Entry>();
int[] chartColorsArray = new int[] {
R.color.clr1,
R.color.clr2,
R.color.clr3,
R.color.clr4,
R.color.clr5
};
// These are the 2 important elements to be passed to the chart
ArrayList<String> chartNames = new ArrayList<String>();
PieDataSet chartValues = new PieDataSet(yChartValues, "");
for (int i = 0; i < 5; i++) {
yChartValues.add(new Entry((float) i*2, i));
chartNames.add(String.valueOf(i));
}
chartValues.setSliceSpace(1f); // Optionally you can set the space between the slices
chartValues.setColors(ColorTemplate.createColors(this, chartColorsArray)); // This is where you set the colors. The first parameter is the Context, use "this" if you're on an Activity or "getActivity()" if you're on a fragment
// And finally add all these to the chart
pieChart.setData(new PieData(chartNames, chartValues));
Does this help?
Edit 2:
This is how you change the color of the text inside the pie-slices:
PieChart pieChart = ...;
// way 1, simply change the color:
pieChart.setValueTextColor(int color);
// way 2, acquire the whole paint object and do whatever you want
Paint p = pieChart.getPaint(Chart.PAINT_VALUES);
p.setColor(yourcolor);
I know this is not an ideal solution, but it should work for now.