我想使用一些合适的免费图表引擎在 android 应用程序中显示条形图。这就是我期望图表的方式:
我正在尝试使用以下功能。
将 onclick 添加到每个栏(红色、蓝色、绿色)。
在顶部而不是底部显示图例。
在 Y 轴上,它显示我想要显示的值 1 - 200。
并且 onlick 在每个条形图的顶部显示值。
我已经调查过了Achart engine
,但它没有这样的条形图。
请帮助我。
我想使用一些合适的免费图表引擎在 android 应用程序中显示条形图。这就是我期望图表的方式:
我正在尝试使用以下功能。
将 onclick 添加到每个栏(红色、蓝色、绿色)。
在顶部而不是底部显示图例。
在 Y 轴上,它显示我想要显示的值 1 - 200。
并且 onlick 在每个条形图的顶部显示值。
我已经调查过了Achart engine
,但它没有这样的条形图。
请帮助我。
我用MPAndroiChart做到了这一点。完整的解决方案请参考我在 Github 中的MPAndroidChart-barchart项目。
结果如下:
这是条形图的一些代码片段:
mChart = (BarChart) findViewById(R.id.chart);
final ArrayList<BarEntry> bar1List = new ArrayList<>();
final ArrayList<BarEntry> bar2List = new ArrayList<>();
final ArrayList<BarEntry> bar3List = new ArrayList<>();
final ArrayList<String> xLabels = new ArrayList<>();
for (int i = 0; i < 3; i++) {
bar1List.add(new BarEntry(i, (float) randInt()));
bar2List.add(new BarEntry(i, (float) randInt()));
bar3List.add(new BarEntry(i, (float) randInt()));
xLabels.add("entry " + i);
}
BarDataSet bar1Set = new BarDataSet(bar1List, "Bar 1");
bar1Set.setColor(bar1Color);
bar1Set.setAxisDependency(YAxis.AxisDependency.LEFT);
bar1Set.setDrawValues(false);
BarDataSet bar2Set = new BarDataSet(bar2List, "Bar 2");
bar2Set.setColor(bar2Color);
bar2Set.setAxisDependency(YAxis.AxisDependency.LEFT);
bar2Set.setDrawValues(false);
BarDataSet bar3Set = new BarDataSet(bar3List, "Bar 3");
bar3Set.setColor(bar3Color);
bar3Set.setAxisDependency(YAxis.AxisDependency.LEFT);
bar3Set.setDrawValues(false);
// (0.20 + 0.05) * 3 + 0.25 = 1.00 -> interval per "group"
final float groupSpace = 0.25f;
final float barSpace = 0.05f;
final float barWidth = 0.2f;
BarData barData = new BarData(bar1Set, bar2Set, bar3Set);
barData.setBarWidth(barWidth);
// make this BarData object grouped
barData.groupBars(0, groupSpace, barSpace); // start at x = 0
mChart.setData(barData);
mChart.getDescription().setEnabled(false);
mChart.setBackgroundColor(backgroundColor);
mChart.setDrawGridBackground(false);
mChart.setDrawBarShadow(false);
mChart.setDoubleTapToZoomEnabled(false);
mChart.setPinchZoom(false);
mChart.setScaleEnabled(false);
// show legend on Top Left
Legend legend = mChart.getLegend();
legend.setEnabled(true);
legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
YAxis leftAxis = mChart.getAxisLeft();
leftAxis.setDrawGridLines(false);
leftAxis.setDrawAxisLine(false);
leftAxis.setDrawLabels(true);
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
leftAxis.setValueFormatter(new LargeValueFormatter());
// show range: 0 -> 200
leftAxis.setAxisMaximum(200);
XAxis xAxis = mChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setDrawAxisLine(false);
xAxis.setCenterAxisLabels(true);
xAxis.setAxisMinimum(0);
xAxis.setGranularity(1f);
xAxis.setTextSize(12);
xAxis.setAxisMaximum(barData.getXMax() + 1);
xAxis.setLabelRotationAngle(-40f);
IAxisValueFormatter xAxisFormatter = new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
if (value >= 0 && value <= xLabels.size() - 1) {
return xLabels.get((int) value);
}
// to avoid IndexOutOfBoundsException on xLabels, if (value < 0 || value > xLabels.size() - 1)
return "";
}
};
xAxis.setValueFormatter(xAxisFormatter);
// display value during highlight
YMarkerView mv = new YMarkerView(this);
mv.setChartView(mChart); // For bounds control
mChart.setMarker(mv); // Set the marker to the chart
mChart.invalidate();
为了在单击栏时显示值,我实现了自定义 MarkerView:
package com.example.shuwnyuan.barchart;
import android.content.Context;
import android.widget.TextView;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.utils.MPPointF;
/**
* Custom implementation of the MarkerView.
*
* @author Shuwn Yuan Tee
*/
public class YMarkerView extends MarkerView {
private TextView tvContent;
public YMarkerView(Context context) {
super(context, R.layout.custom_marker_view);
tvContent = findViewById(R.id.tvContent);
}
// callbacks everytime the MarkerView is redrawn, can be used to update the
// content (user-interface)
@Override
public void refreshContent(Entry e, Highlight highlight) {
tvContent.setText("" + (int)e.getY());
super.refreshContent(e, highlight);
}
@Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -getHeight());
}
}
希望这有帮助。