I want to make a bar chart with 3 different datasets grouped together at each data point like so:
However, I am unable to group the bars together using the library's provided groupBars
method because no matter what x-value I set for an entry, it groups the bars according to the interval I specify in its parameters.
For example, if I generate a dataset with entry x-values {0, 5, 13, 17...50} and call `groupBars', all of my entries are gathered 1 x-value apart like so:
What I want is the bars to each be grouped and each be visible at their specified x-value. If I simply remove the groupBars
call, I get something similar to what I want but not quite since the bars are all overlapping, like so:
How do I achieve a result similar to the above image but with the bar of each dataset completely visible? Here is my code for generating the dataset and grouping the bars:
ArrayList<BarEntry> happinessValues = new ArrayList<>();
ArrayList<BarEntry> stressValues = new ArrayList<>();
ArrayList<BarEntry> painValues = new ArrayList<>();
for (int i = 0; i < 50; ++i) {
happinessValues.add(new BarEntry(
i,
datapoint.getHappiness()));
stressValues.add(new BarEntry(
i,
datapoint.getStress()));
painValues.add(new BarEntry(
i,
datapoint.getPain()));
}
HappinessDataset happyDataset;
BarDataSet stressDataset, painDataset;
happyDataset = new HappinessDataset(happinessValues, "Happiness");
stressDataset = new BarDataSet(stressValues, "Stress");
painDataset = new BarDataSet(painValues, "Pain");
BarData data = new BarData(happyDataset, stressDataset, painDataset);
mChart.setData(data);
mChart.getXAxis().setAxisMinimum(0);
mChart.getXAxis().setAxisMaximum(50);
float groupSpace = 0.4f;
float barSpace = 0f; // x3 DataSet
float barWidth = 0.2f; // x3 DataSet
// (0.2 + 0) * 3 + 0.4 = 1.00 -> interval per "group"
mChart.groupBars(startTime, groupSpace, barSpace);
I have solved the problem by modifying the x-values of each bar-entry and the bar width.
I create a new BarData class with the three datasets and set the bar width (let's call it BAR_WIDTH
) to be 0.2 (i.e. the three bars together will take up 0.6 units in space, and there will be 0.4 unit of spacing after the dataset).
For any given bar entry, I place my first bar at the x-value I want (lets call it i
), my second bar at x-value i+BAR_WIDTH
, and third bar at i+2*BAR_WIDTH
. The result is a group of 3 bar entries centered at any x-value I want, like so:
So in my above code, modify the bar-entry creation code to be as follows:
final float BAR_WIDTH = 0.2f;
happinessValues.add(new BarEntry(
i,
datapoint.getHappiness()));
stressValues.add(new BarEntry(
i + BAR_WIDTH,
datapoint.getStress()));
painValues.add(new BarEntry(
i + 2 * BAR_WIDTH,
datapoint.getPain()));
mChart.getBarData().setBarWidth(BAR_WIDTH);
Two things that you have missed out is:
mChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
mChart.getXAxis().setCenterAxisLabels(true);
BEFORE using setCenterAxisLabels
AFTER setting setCenterAxisLabels to true
this is the code snippet I am using to align labels to center of each set of group
float barSpace = 0.02f;
float groupSpace = 0.3f;
int groupCount = 4;
data.setBarWidth(0.15f);
barChart.getXAxis().setAxisMinimum(0);
barChart.getXAxis().setAxisMaximum(0 + barChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
barChart.groupBars(0, groupSpace, barSpace); // perform the "explicit" grouping
If you are not sure about the number of grouped bar graph (here it's 4) then
float defaultBarWidth = -1;
int groupCount = xAxisValues.size();
defaultBarWidth = (1 - groupSpace)/barDataSets.size() - barSpace;
if(defaultBarWidth >=0) {
barData.setBarWidth(defaultBarWidth);
}
if(groupCount != -1) {
mChart.getXAxis().setAxisMinimum(0);
mChart.getXAxis().setAxisMaximum(0 + mChart.getBarData().getGroupWidth(groupSpace, barSpace) * groupCount);
mChart.getXAxis().setCenterAxisLabels(true);
}
Here the barwidth is calculated as follows
(barwidth + barspace) * no of bars + groupspace = 1
the sum of all this spaces should be equal to 1 for label to be aligned to center of grouped bar graph.
I think the solution is to use
barChart.groupBars(fromX, groupSpace, barSpace);
barChart.notifyDataSetChanged()
along with
XAxis xAxis = chart.getXAxis();
xAxis.setCenterAxisLabels(true);
in order to set X-Axis label into the centre of the bar group.
Please refer to GroupedBarChart section of this for further details.
来源:https://stackoverflow.com/questions/43480358/mpandroidchart-bar-chart-how-to-group-bars-with-random-x-axis-intervals-in-bet