I'm trying the following behaviour: When clicking on bar chart entry, I'd like to get the coresponding legend label (SF Zoo or LA Zoo)
The code that builds the BarDataSet:
List<IBarDataSet> barDataSetList = new ArrayList<>();
for (Map.Entry<String, List<Float>> entry : hashMapCategorySpending.entrySet()) {
String category = entry.getKey(); // here category is either SF Zoo or LA Zoo
List<Float> values = entry.getValue();
List<BarEntry> valuesConverted = convertToBarEntryArray(values); // some utility function
BarDataSet barDataSet = new BarDataSet(valuesConverted, category); // create BarDataSet
barDataSet.setColor(StatisticsCategoryFragment.categoryColorHashMap.getOrDefault(category, 0));
barDataSetList.add(barDataSet);
}
/* Set data to chart */
BarData barData = new BarData(barDataSetList);
barData.setValueTextSize(12.5f);
barChart.setData(barData);
My problem is that when overriding setOnChartValueSelectedListener that I cannot convert Entry e to something useful:
barChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
#Override
public void onValueSelected(Entry e, Highlight h) {
BarEntry barDataSet = (BarEntry) e; // Doesn't help at all
// I want to do something like e.getLegendLabel(); and it should return SF Zoo or LA Zoo
}
#Override
public void onNothingSelected() {
}
});
Figured it out. You could take the info from the Highlight h object:
String category = barChart.getLegend().getEntries()[h.getDataSetIndex()].label;
Related
I've used the BarChart provided by MPAndroidChart library to display a bar graph.
When there is data for more than one values on the x-axis (in this case the date), the output is shown as expected. However, when there is data for only a single date, for some reason that date is displayed twice on the x-axis.
I would like to prevent one of the values from being displayed. Below is the code that is displayed the results in the image.
private void showBarGraph(List<Object> response) {
barChart.setNoDataText(getResources().getString(R.string.sorry_data_not_available));
barChart.clear();
if(response.size()>0) {
int highestValue = response != null && response.size() > 0 ? response.size() : 0;
barChart.getAxisLeft().setAxisMaximum(highestValue);
barChart.getAxisLeft().setAxisMinimum(0);
barChart.animateY(1000);
List<BarEntry> entries = new ArrayList<>();
List<String> xAxisValues = new ArrayList<>();
if (response != null) {
for (int i = 0; i < respones.size(); i++) {
entries.add(new BarEntry(i, response.get(i).getCount(), ContextCompat.getColor(getActivity(), R.color.graph)));
xAxisValues.add(response.get(i).getTimekey());
}
barChart.getAxisLeft().setLabelCount(highestValue > 10 ? 10 : highestValue, false);
barChart.getXAxis().setLabelCount(response.size() <= 12 ? response.size() : 12, false);
if (response.size() >= 4) {
barChart.getXAxis().setLabelRotationAngle(-45);
} else {
barChart.getXAxis().setLabelRotationAngle(0);
}
}
IndexAxisValueFormatter xAxisValueFormatter = new IndexAxisValueFormatter(xAxisValues);
barChart.getXAxis().setValueFormatter(xAxisValueFormatter);
BarXYMarkerView xymv = new BarXYMarkerView(getActivity(), xAxisValueFormatter);
// Set the marker to the chart
xymv.setChartView(barChart);
barChart.setMarker(xymv);
BarDataSet set = new BarDataSet(entries, null);
set.setDrawValues(false);
List<Integer> graphColors = new ArrayList<>();
graphColors.add(ContextCompat.getColor(getActivity(), R.color.graph));
set.setColors(graphColors);
BarData data = new BarData(set);
barChart.setData(data);
barChart.invalidate();
}
}
The code is good for data with entries on multiple dates. Can someone guide me on how I can prevent the duplicate date value when there is data for only one date.
i am using MPAndroidChart barchart ... every thing is okay except the x-axis... my bars are not aligned properly on labels. when i zoome the chart then bars come on its labels but that zoom is not what i wanted and also when i zooming the labels repeat until next and so on.
my data is like eg:
age(x) weight(y)
2 90
5 100
7 200
10 300
the age is my labels and it is string type ... i need it to be string label.
this is what i got
this is my code in c#
//-----chart-------------
barChart = FindViewById<BarChart>(Resource.Id.barChart);
List<BarEntry> entries = new List<BarEntry>();
List<string> labelz = new List<string>();
int c = 0;
foreach(var rec in weighting_lst)
{
entries.Add(new BarEntry(c, rec.Weight));
labelz.Add(rec.Age.ToString());
c++;
}
BarDataSet dataset = new BarDataSet(entries, "وزن به گرم");
BarData data = new BarData(dataset);
var xdata = barChart.XAxis;
xdata.ValueFormatter = new MyLabelFormatter(labelz);
xdata.SetCenterAxisLabels(false);
barChart.Data = data;
barChart.SetScaleEnabled(true);
barChart.SetFitBars(true);
public class MyLabelFormatter : Java.Lang.Object, IAxisValueFormatter
{
//private string[] customLabels = new string[] { "A", "B", "C", "D", "E", "F" };
public List<string> label_lst = new List<string>();
public MyLabelFormatter(List<string> _label_lst)
{
label_lst = _label_lst;
}
public string GetFormattedValue(float value, AxisBase axis)
{
return label_lst[(int)value % label_lst.Count];
}
}
for x position of bar entry i just use integer called c which increases by 1 on each loop so it gives me like 0f,1f,2f,......
i added xdata.Granularity = 1f; and it works for me .... xdata is my Xaxis
Does anybody have an idea on how to make this: my app image look like this: how it should be?
My question is: how to make each line of the Horizontal Bar Chart fill between the two lines?
for (Iterator<Map.Entry<String, Float>> iterator = structuredData.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<String, Float> entry = iterator.next();
//i*10 => starting position of the bar
horizontalBarChartArr.add(new BarEntry((i*10), entry.getValue()));
names.add(entry.getKey());
i++;
}
XAxis xAxis = horizontalBarChart.getXAxis();
xAxis.setValueFormatter(new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return names.get((int)value % names.size());
}
});
xAxis.setDrawGridLines(true);
xAxis.setDrawAxisLine(true);
BarDataSet barDataSet = new BarDataSet(horizontalBarChartArr, "Day Expenses");
barDataSet.setColors(Color.RED);
BarData data = new BarData(barDataSet);
data.setBarWidth(9f);
horizontalBarChart.setDoubleTapToZoomEnabled(false);
Description a = new Description();
a.setText("");
horizontalBarChart.setDescription(a);
horizontalBarChart.invalidate();
horizontalBarChart.animateY(1200);
horizontalBarChart.setData(data);
Check this example to your case:
https://github.com/ddanny/achartengine
It´s Automatically exported from code.google.com/p/achartengine
I created a graph app using MP android chart, i used it to plot two different line data sets . But my problem is that the value labels for the xaxis appear on the top of the graph . I need a way to make it to the bottom . below is my code
final LineChart linechart = (LineChart)findViewById(R.id.idlinechart);
//created list enties to hold the values
List<Entry> valuesCompany1 = new ArrayList<>(); List<Entry> valuesCompany2 = new ArrayList<>();
//created entry values to be entered into the lsit entry b
Entry c1e1 = new Entry(0f, 100000f); valuesCompany1.add(c1e1);
Entry c1e2 = new Entry (1f, 140000f);valuesCompany1.add(c1e2);
Entry c1e3 = new Entry(2f,90000f);valuesCompany1.add(c1e3);
Entry c1e4 = new Entry (3f, 150000f); valuesCompany1.add(c1e4);
Entry c2e1 = new Entry(0f, 50000f); valuesCompany2.add(c2e1);
Entry c2e2 = new Entry (1f, 50000f);valuesCompany2.add(c2e2);
Entry c2e3 = new Entry(2f,150000f);valuesCompany2.add(c2e3);
Entry c2e4 = new Entry (3f, 110000f); valuesCompany2.add(c2e4);
//so now we create line data to hold the list
LineDataSet linedatasetComp1 = new LineDataSet(valuesCompany1, "company 1");
linedatasetComp1.setAxisDependency(YAxis.AxisDependency.LEFT);
linedatasetComp1.setColor(Color.BLUE);
LineDataSet linedatasetComp2 = new LineDataSet(valuesCompany2, "company 2");
linedatasetComp2.setAxisDependency(YAxis.AxisDependency.LEFT);
linedatasetComp2.setColor(Color.RED);
List<ILineDataSet> iLinedata = new ArrayList<ILineDataSet>();
iLinedata.add(linedatasetComp1); //adding the line data sets into the line data list
iLinedata.add(linedatasetComp2);
//setting the Ilinedata list into line data
LineData linedata = new LineData(iLinedata);
//setting the line data into line chart
linechart.setData(linedata);
linechart.invalidate(); //refreshing the line chart
//Saving the picture to galery
Button savebutton = (Button)findViewById(R.id.button);
savebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
linechart.saveToGallery("new Line chart", 150);
Toast.makeText(getApplicationContext(), "graph saved ", Toast.LENGTH_LONG).show();
}
});
final String[] Quaters = {"Q1", "Q2", "Q3", "Q4"};
IAxisValueFormatter valueFormater = new IAxisValueFormatter() {
#Override
public String getFormattedValue(float value, AxisBase axis) {
return Quaters[(int) value];
}
#Override
public int getDecimalDigits() {
return 0;
}
};
XAxis xAxis = linechart.getXAxis();
xAxis.setGranularity(1f);
xAxis.setValueFormatter(valueFormater);
Description desc = new Description();
desc.setText("A graph comparing revenuews of two companies ");
desc.setEnabled(true);
desc.setPosition(0,0);
desc.setTextColor(Color.BLACK);
linechart.setDescription(desc);
I don't know if LineChart has that option, but in case it does you just have to get the XAxis adjust the Position like this:
linechart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
Hope it helps!
Use MPAndroid chart version 2.2.4 or above and use the code
mChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM);
as said by Ponchotg
Just started using the MPAndroidChart version 3.0.0 beta and i have created a project that can show my values in a bar chart. My question is where do i add and display labels.
Each Bar should have its own label eg. "Flue", "Cheese" etc at the bottom. Not sure what function does this, am actively searching and reading the Docs/Wiki but no joy currently.
Depending on your preferences, you can use the data property of an Entry to store the label and then return it in your IAxisValueFormatter implementation:
public class LabelValueFormatter implements IAxisValueFormatter {
private final DataSet mData;
public LabelValueFormatter(DataSet data) {
mData = data;
}
#Override
public String getFormattedValue(float value, AxisBase axis) {
// return the entry's data which represents the label
return (String) mData.getEntryForXPos(value, DataSet.Rounding.CLOSEST).getData();
}
}
This approach allows you to use the Entry constructor (or BarEntry in this case) to add the labels, which can improve the readability of your code:
ArrayList<BarEntry> entries = new ArrayList<>();
for (int i = 0; i < length; i++) {
// retrieve x-value, y-value and label
entries.add(new BarEntry(x, y, label));
}
BarDataSet dataSet = new BarDataSet(entries, "description");
BarData data = new BarData(dataSet);
mBarChart.setData(data);
mBarChart.getXAxis().setValueFormatter(new LabelValueFormatter(data));
Also check out this answer for more information and an alternative approach on using labels with the BarChart and the new 3.0.0 version of the library.