What I have done: I have created a pie chart using MPAndroidChart library and ended up having the legend in the left corner. I tried changing the pie chart width but then when the items increase legend tends to wrap to a second line.
What I expect: I want the legend to be in the center every time when it updates. Even legend wrap to the second line, I want it to be in the center. I would appreciate any suggestions on this.
Thank you!
<com.github.mikephil.charting.charts.PieChart
android:id="#+id/chart"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
>
</com.github.mikephil.charting.charts.PieChart>
Activity Code :
private void setupPieChart(){
//pupulating list of PieEntires
List<PieEntry> pieEntires = new ArrayList<>();
for( int i = 0 ; i<time.length;i++){
pieEntires.add(new PieEntry(time[i],activity[i]));
}
PieDataSet dataSet = new PieDataSet(pieEntires,"");
dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
PieData data = new PieData(dataSet);
//pie slices text value
data.setValueTextSize(10);
//Get the chart
pieChart.setData(data);
pieChart.invalidate();
pieChart.setCenterText("50%");
pieChart.setDrawEntryLabels(false);
pieChart.setContentDescription("");
//pieChart.setDrawMarkers(true);
//pieChart.setMaxHighlightDistance(34);
pieChart.setEntryLabelTextSize(12);
pieChart.setHoleRadius(75);
//to remove bottom left description
pieChart.getDescription().setEnabled(false);
//legend attributes
Legend legend = pieChart.getLegend();
legend.setForm(Legend.LegendForm.CIRCLE);
legend.setTextSize(12);
legend.setFormSize(20);
legend.setFormToTextSpace(2);
//to wrap legend text
legend.setWordWrapEnabled(true);
Log.d("legend " ,legend.getEntries().toString());
}
I was able to center the legend by adding the below line in setupPieChart() mentioned in the question above.
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
Related
MPAndroidChart is very awesome library.I am very thankful to.
But now, I have 3 problems.
The version I used is...
compile 'com.github.PhilJay:MPAndroidChart:v2.2.5'
And my problem is,...
Left: now -> Right: want to be
1.
How to draw limit a Y value line on line chart or bar chart?
e.g. I want to draw value y=200 line on Image.
(e.g. attached image top.shown in red)
2.
How to set viewpoint to bottom and get y-axis mint limit to bottom value?
(e.g. attached image bottom)
I want to set viewpoint to bottom.
I tried this code ,But still,there is some padding.
XAxis xAxis = mBarChart.getXAxis();
xAxis.setAxisMinValue(0);
I want to trim this padding.
*Edited
This works well. Thank you!
mChart.getAxisLeft().setAxisMinValue(0);
3.How to remove point of graph on line chart?
A line chart, the bottom image, has lots of marker.
So I want to remove these plot point.
1) You need to add a LimitLine
int maxCapacity = 100;
LimitLine ll = new LimitLine(maxCapacity, "Max Capacity");
chart.getAxisLeft().addLimitLine(ll);
You can also style the line by:
ll.setLineWidth(4f);
ll.setTextSize(12f);
2) This method may be useful:
chart.setViewPortOffsets(float left, float top, float right, float bottom);
You can read the documentation here.
3) This method is what you need:
lineDataSet.setDrawCircles(false);
Once again, its all available in the documentation.
For Kotlin
You can use LimitLine
val limitValue = 100
val nameLimitLine = LimitLine(limitValue.toFloat(), "Limit").apply{
enableDashedLine(10f, 15f, 0f) //For "- - - -"
lineWidth = 2f
}
chart.axisLeft.addLimitLine(nameLimitLine)
I am working in project in project that needs implement chart , I decide use MPAndroidChart its work just fine but I need some things done to be perfect to me
First can I change bars to specific image or it takes just images , as I have 3D image as bars in app design .
Second Can I put the legend to the right of chart in two line like image below and change legend text color
my java code
mChart = (BarChart) view.findViewById(R.id.chart);
mChart.setDescription("");
Legend mLegend = mChart.getLegend();
//mLegend.setPosition(Legend.LegendPosition.RIGHT_OF_CHART_CENTER);
FillBarChart(mChart);
}
private void FillBarChart(BarChart barChart) {
ArrayList<BarEntry> entries = new ArrayList<>();
entries.add(new BarEntry(87f, 0));
entries.add(new BarEntry(90f, 1));
ArrayList<String> labels = new ArrayList<>();
labels.add("Omeprazole 20 mg");
labels.add("Esomeprazole 40 mg");
BarDataSet dataSet = new BarDataSet(entries, " ");
dataSet.setBarSpacePercent(40f);
BarData barData = new BarData(labels, dataSet);
dataSet.setColors(new int[]{R.color.omeprazole_color , R.color.esomeprazole_color} , getActivity());
barChart.setData(barData);
barChart.animateY(3000 , Easing.EasingOption.EaseOutBack );
}
You can do that if you create a custom Chart class and overwrite the init().
In this method, the Chart initializes a LegendRenderer and this is the point you need to get in and make changes.
Create a custom LegendRenderer and make sure that all the measurements are in place for those drawable. drawForm() method will allow you to draw the images instead of the default forms (Circle, Square, Line).
I am drawing a bar chart using the Achart Library. I want to customize the chart as follows:
Give space between first bar from start
Increase the width of each bar
Increase text size of numbers which are at top of the bars
The following is the code for my bar chart:
![private void openChart()
{
int\[\] x = { 0,1,2,3,4,5,6};
// Creating an XYSeries for Income
XYSeries wSeries = new XYSeries("Workout");
// Creating an XYSeries for Expense
for(int i=0;i<x.length;i++){
wSeries.add(i,workout\[i\]);
}
// Creating a dataset to hold each series
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
// Adding Income Series to the dataset
dataset.addSeries(wSeries);
// Adding Expense Series to dataset
// Creating XYSeriesRenderer to customize incomeSeries
XYSeriesRenderer wRenderer = new XYSeriesRenderer();
wRenderer.setColor(getResources().getColor(R.color.header_blue)); //color of the graph set to cyan
wRenderer.setFillPoints(true);
wRenderer.setLineWidth(5);
wRenderer.setDisplayChartValues(true);
wRenderer.setDisplayChartValuesDistance(20); //setting chart value distance
// Creating a XYMultipleSeriesRenderer to customize the whole chart
XYMultipleSeriesRenderer multiRenderer = new XYMultipleSeriesRenderer();
multiRenderer.setOrientation(XYMultipleSeriesRenderer.Orientation.HORIZONTAL);
multiRenderer.setXLabels(0);
/***
* Customizing graphs
*/
//setting text size of the title
multiRenderer.setChartTitleTextSize(30);
//setting text size of the axis title
multiRenderer.setAxisTitleTextSize(30);
//setting text size of the graph lable
multiRenderer.setLabelsTextSize(30);
//setting zoom buttons visiblity
multiRenderer.setZoomButtonsVisible(false);
//setting pan enablity which uses graph to move on both axis
multiRenderer.setPanEnabled(false, false);
//setting click false on graph
multiRenderer.setClickEnabled(false);
//setting zoom to false on both axis
multiRenderer.setZoomEnabled(false, false);
//setting lines to display on y axis
multiRenderer.setShowGridY(false);
//setting lines to display on x axis
multiRenderer.setShowGridX(false);
//setting legend to fit the screen size
multiRenderer.setFitLegend(true);
//setting displaying line on grid
multiRenderer.setShowGrid(false);
//setting zoom to false
multiRenderer.setZoomEnabled(false);
//setting external zoom functions to false
multiRenderer.setExternalZoomEnabled(false);
//setting displaying lines on graph to be formatted(like using graphics)
multiRenderer.setAntialiasing(true);
//setting to in scroll to false
multiRenderer.setInScroll(false);
//setting to set legend height of the graph
multiRenderer.setLegendHeight(30);
//setting x axis label align
multiRenderer.setXLabelsAlign(Align.CENTER);
//setting y axis label to align
multiRenderer.setYLabelsAlign(Align.RIGHT);
//setting text style
multiRenderer.setTextTypeface("sans_serif", Typeface.BOLD);
//change y axis label color
multiRenderer.setYLabelsColor(0,Color.BLACK);
//change x axis label color
multiRenderer.setXLabelsColor(Color.BLACK);
//setting no of values to display in y axis
multiRenderer.setYLabels(7);
// setting y axis max value, Since i'm using static values inside the graph so i'm setting y max value to 4000.
// if you use dynamic values then get the max y value and set here
multiRenderer.setYAxisMin(0);
multiRenderer.setYAxisMax(49);
//setting used to move the graph on xaxiz to .5 to the right
multiRenderer.setXAxisMin(0);
//setting max values to be display in x axis
multiRenderer.setXAxisMax(7);
//setting bar size or space between two bars
multiRenderer.setBarSpacing(3);
//Setting background color of the graph to transparent
multiRenderer.setBackgroundColor(Color.TRANSPARENT);
//Setting margin color of the graph to transparent
multiRenderer.setMarginsColor(getResources().getColor(R.color.light_red));
multiRenderer.setApplyBackgroundColor(true);
//setting the margin size for the graph in the order top, left, bottom, right
multiRenderer.setMargins(new int\[\]{20, 40, 20, 20});
for(int i=0; i< x.length;i++){
multiRenderer.addXTextLabel(i, week\[i\]);
}
// Adding incomeRenderer and expenseRenderer to multipleRenderer
// Note: The order of adding dataseries to dataset and renderers to multipleRenderer
// should be same
multiRenderer.addSeriesRenderer(wRenderer);
//this part is used to display graph on the xml
LinearLayout chartContainer = (LinearLayout) findViewById(R.id.nut_sum_graphLayout);
//remove any views before u paint the chart
chartContainer.removeAllViews();
//drawing bar chart
mChart = ChartFactory.getBarChartView(HealthNutritionSummary.this, dataset, multiRenderer,Type.DEFAULT);
//adding the view to the linearlayout
chartContainer.addView(mChart);
}][2]
To give space on the left side a chart, I set X axis min to smaller size. For example, this should do the trick in your case.
multiRenderer.setXAxisMin(-0.5);
To increase width, you have two options.You can set bar spacing or bar width.
multiRenderer.setBarSpacing(0.5);
or
multiRenderer.setBarWidth(20); // I think this is in pixels
And finally, for text size there is option for XYSeriesRenderer, in your case:
wRenderer.setChartValuesTextSize(20);
I am creating a Bar Chart:
final JFreeChart result = ChartFactory.createBarChart(TITLE, // chart title
X_TITLE, // domain axis label
Y_TITLE, // range axis label
dataset, // data
PlotOrientation.HORIZONTAL, // the plot orientation
true, // legend
true, // tooltips
false // urls
);
I then added a ChartMouseListener as described here.
When I click on a legend item, "LegendItemEntity: seriesKey=null, dataset=null" is displayed.
How do I access the legend text for the corresponding item?
Starting from org.jfree.chart.demo.BarChartDemo1 and adding the same ChartMouseListener to the source yields results like this:
LegendItemEntity: seriesKey=First, dataset=org.jfree.data.category.DefaultCategoryDataset#d9510071
LegendItemEntity: seriesKey=Second, dataset=org.jfree.data.category.DefaultCategoryDataset#d9510071
LegendItemEntity: seriesKey=Third, dataset=org.jfree.data.category.DefaultCategoryDataset#d9510071
If you're geting a different result, an sscce may help.
Can someone tell me how to change samples of series color in legend in jfreechart. What I have now is small line of series color eg: I would like to have square sample of those colors. Here is an example
Can someone help me?
Ok I found the solution. At least I think. Of course there is no simple way to do this. There is now, you know, setShape(square) method, that will do the trick, at least i haven't found one.
Basicly XY chart and time chart have "line style" legend by default in contrary to bar chart for example (if has square legend by default). So I had to remove current legend and create new one with square samples of color and this new legend add to my time chart.
LegendItemCollection legend = new LegendItemCollection();
for (int i = 0; i < seriecCount; ++i) {
chart.getXYPlot().getRenderer().setSeriesPaint(i, colorPalette.get(i));
LegendItem li = new LegendItem(data.getSeriesName(i), "-", null, null, Plot.DEFAULT_LEGEND_ITEM_BOX, colorPalette.get(i));
legend.add(li);
}
chart.getXYPlot().setFixedLegendItems(legend);
Thanks for attention. I hope it will help someone.
Generating your own legend, as you do above, is a perfectly acceptable way of doing things in JFreeChart. If you didn't want to do it, you can also define your own renderer with the lookupLegendShape() method overridden.
thePlot.setRenderer(new XYLineAndShapeRenderer()
{
public Shape lookupLegendShape(int series)
{
return new Rectangle(15, 15);
}
});
If you use a XYBarRenderer Class XYBarRenderer
(Subclasses: ClusteredXYBarRenderer, StackedXYBarRenderer)
You can use XYBarRenderer.setLegendBar(java.awt.Shape bar);
See: Javadoc
to get nice squares.
Example:
JFreeChart chart = ChartFactory.createXYBarChart(/*...*/);
XYPlot plot = (XYPlot) chart.getPlot();
ClusteredXYBarRenderer renderer = new ClusteredXYBarRenderer();
renderer.setLegendBar(new Rectangle(17, 17));
plot.setRenderer(renderer);