本文出自:http://blog.csdn.net/dt235201314/article/details/70237777
Demo下载(UpDating):https://github.com/JinBoy23520/MPAndroidChartDemoByJin
MPAndroidChart常见设置属性(一)——应用层
一丶慨述
虽然在MPAndroidChart项目实战(一)里面就说了双柱状图的实现,但毕竟那是旧的jar包版,而目前的项目开发,用到的都是新版本,所以还是说一下总结一下,不整理不知道,一整理吓一跳,问题还真不少。
二丶效果:
三丶实现功能
1.实现柱状图。
2.解决柱状图上换行拼接文字问题。
3.解决X轴文字偶尔不显示问题。
四丶看代码
1.项目复用率很高,先得有个BarChartEntry.Java
/** * 柱状图 * Created by jin */ public class BarChartEntity extends BaseChartEntity{ public BarChartEntity(BarLineChartBase chart, List [] entries, String[] labels, int[] chartColor, int valueColor, float textSize) { super(chart, entries, labels, chartColor, valueColor, textSize); } @Override protected void initChart() { super.initChart(); mChart.getAxisLeft().setDrawGridLines(true); mChart.getAxisLeft().enableGridDashedLine(10f, 15f, 0f); mChart.getAxisLeft().setGridLineWidth(0.5f); mChart.getAxisLeft().setGridColor(Color.parseColor("#f5f5f5")); mChart.getAxisLeft().setDrawZeroLine(false); mChart.getAxisRight().setDrawZeroLine(false); mChart.getAxisRight().setZeroLineWidth(0f); mChart.getAxisLeft().setZeroLineWidth(0f); mChart.getAxisLeft().setDrawAxisLine(false); mChart.getXAxis().setDrawAxisLine(false); mChart.getXAxis().setAxisMinimum(0); } @Override protected void setChartData() { BarDataSet barDataSet; if (mChart.getData() != null && mChart.getData().getDataSetCount() > 0) { barDataSet = (BarDataSet) mChart.getData().getDataSetByIndex(0); barDataSet.setValues(mEntries[0]); mChart.getData().notifyDataChanged(); mChart.notifyDataSetChanged(); } else { barDataSet = new BarDataSet(mEntries[0], labels == null ? "" : labels[0]); barDataSet.setColors(mChartColors); List colors = new ArrayList<>(); for (int color : mChartColors) { colors.add(color); } barDataSet.setValueTextColors(colors); ArrayList dataSets = new ArrayList<>(); dataSets.add(barDataSet); BarData data = new BarData(dataSets); data.setValueTextSize(mTextSize); data.setBarWidth(0.9f); mChart.setData(data); } } public void setDrawValueAboveBar(boolean aboveBar) { ((BarChart)mChart).setDrawValueAboveBar(aboveBar); } /** * 设置bar宽度 * @param barWidth float */ public void setBarWidth(float barWidth) { ((BarChart)mChart).getData().setBarWidth(barWidth); } }
这样就可以直接添加方法用了
/** * 柱状图 该在X轴得文字显示在柱状图上 */ private void updataBarChart() { mBarChart = (BarChart) mView.findViewById(R.id.new_the_bar_chart); List[] entries = new ArrayList[3]; final String[] labels = { getActivity().getResources().getString(R.string.actual_value), getActivity().getResources().getString(R.string.budget_value), getActivity().getResources().getString(R.string.yoy_value),}; int[] cahrtColors = { Color.parseColor("#45A2FF"), Color.parseColor("#58D4C5"), Color.parseColor("#FDB25F")}; final double[] values = new double[3]; ArrayList entries1 = new ArrayList<>(); float actualValue = 10086; float budgetValue = 1001; float yoyValue = 12580; entries1.add(new BarEntry(0.5f, actualValue)); entries1.add(new BarEntry(1.3f, budgetValue)); entries1.add(new BarEntry(2.1f, yoyValue)); values[0] = actualValue; values[1] = budgetValue; values[2] = yoyValue; entries[0] = entries1; if (mBarChart.getData() != null) { mBarChart.getData().clearValues(); } BarChartEntity barChartEntity = new BarChartEntity(mBarChart, entries, labels, cahrtColors, Color.parseColor("#999999"), 13f); barChartEntity.setBarWidth(0.55f); barChartEntity.setDrawValueAboveBar(true); mBarChart.setPinchZoom(false); mBarChart.setScaleEnabled(false); mBarChart.animateY(2000, Easing.EasingOption.EaseInOutQuart); barChartEntity.setAxisFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float value, AxisBase axis) { return ""; } }, null); mBarChart.getLegend().setEnabled(false); /** * 拼接柱状图上文字,涉及到修改源码 */ mBarChart.getData().setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { return labels[entry.getX() == 0.5f ? 0 : (entry.getX() == 1.3f ? 1 : 2)] + "\n" + mFormat.format(values[entry.getX() == 0.5f ? 0 : (entry.getX() == 1.3f ? 1 : 2)]); } }); /** * 处理当数据都为0,不好看情况 */ float yMax = mBarChart.getData().getYMax() == 0 ? 100f : mBarChart.getData().getYMax(); float delta = yMax / 5.5f; mBarChart.getAxisLeft().setAxisMaximum(yMax + delta); float yMin = mBarChart.getData().getYMin(); if (yMin == 0) { yMin = 0; } float deltaMin = yMin / 5.0f; mBarChart.getAxisLeft().setAxisMinimum(yMin - deltaMin); }
代码敲完,发现没报错,但问题了来,柱状图上的文字是在同一排显,方法getFormattedValue里的“\n”,换行符并没起到作用。
此刻埋怨(该死的设计师,把那行字写在X轴出不久OK,非要整在柱状图上),初级工程师满心抓狂,大神微微一下,可能是绘图的部分出问题,找到位置
方法 public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color){}用到的是paint,是不支持换行符的,那么怎么办呢,换支持的textpaint。
/** * Draws the value of the given entry by using the provided IValueFormatter. * * @param c canvas * @param formatter formatter for custom value-formatting * @param value the value to be drawn * @param entry the entry the value belongs to * @param dataSetIndex the index of the DataSet the drawn Entry belongs to * @param x position * @param y position * @param color */ public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) { mValuePaint.setColor(color); //回车换行符处理 TextPaint textPaint = new TextPaint(); textPaint.setColor(mValuePaint.getColor()); textPaint.setTextSize(mValuePaint.getTextSize()); textPaint.setAntiAlias(true); String valueTemp = formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler); StaticLayout myStaticLayout = new StaticLayout(valueTemp, 0, valueTemp.length(), textPaint, (int)textPaint.measureText(valueTemp), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); c.save(); c.translate(x - myStaticLayout.getWidth() / 2, y - myStaticLayout.getHeight()); //开始画位置 myStaticLayout.draw(c); c.restore(); // c.drawText(formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x, y, mValuePaint); }问题解决了。菜鸟此刻仰望大神,我要怎么才能像大神一样,大神微微一笑:“恶补Android 绘图部分,多读源码,Believe you can fly”
菜鸟恍然大悟,原来设计师并不是刁难自己,原来是磨练啊。
说完X轴文字放到柱状图上的,再说说,X轴显示时间段的。
看方法:
/** * X轴显示时间段的柱状图 */ public void updataXBarChart(){ final MonthItemEntity entity = new MonthItemEntity(); xBarChart = (BarChart) mView.findViewById(R.id.new_x_bar_chart); List理论上这样就OK了,设置了根据方法设置了XY的显示,然而X轴得文字去有一写无法显示,如效果图一。[]entries = new ArrayList[1]; //x轴坐标 控制显示位置,并不会在X轴上显示具体的值 final float[] xlabels = new float[entity.getMonthDatas().size()]; int[] color ={Color.parseColor("#7f45a2ff")}; final String unit = "%"; //x轴坐标增量 float delta = 1; for (int index = 0, len = entity.getMonthDatas().size(); index < len; index ++) { xlabels[index] = index * delta + delta; } entries[0] = entity.getMonthEntries(); BarChartEntity barChartEntity = new BarChartEntity(xBarChart, entries, null, color, Color.parseColor("#999999"), 10f); /*属性修改设置*/ barChartEntity.setBarWidth(0.55f); barChartEntity.setDrawValueAboveBar(true); xBarChart.setPinchZoom(false); xBarChart.setScaleEnabled(false); xBarChart.getLegend().setEnabled(false); xBarChart.getXAxis().setTextSize(9f); xBarChart.getAxisLeft().setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART); mBarChart.animateY(1000, Easing.EasingOption.EaseInOutQuart); /*X,Y坐标显示设置*/ barChartEntity.setAxisFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float value, AxisBase axis) { for (int index = 0,len = xlabels.length; index < len; index ++) { if (value == xlabels[index]) { return entity.getMonthDatas().get(index).getBeginTime() + "-" + entity.getMonthDatas().get(index).getEndTime(); } } return ""; } }, new IAxisValueFormatter() { @Override public String getFormattedValue(float value, AxisBase axis) { return mFormat.format(value) + (unit.equals("%") ? unit : ""); } }); /*值显示设置*/ xBarChart.getData().setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { return mFormat.format(value) + (unit.equals("%") ? unit : ""); } }); /*Y轴最大值最小值设置,为了尽可能的显示完整数据*/ float yMax = xBarChart.getData().getYMax() == 0 ? 100f :xBarChart.getData().getYMax(); float yDelta = yMax / 5.5f; float axisMaximum = yMax + yDelta; if (axisMaximum < 5) { axisMaximum = 5; } xBarChart.getAxisLeft().setAxisMaximum(axisMaximum); float yMin = xBarChart.getData().getYMin(); float deltaMin = yMin / 5.0f; xBarChart.getAxisLeft().setAxisMinimum(yMin - deltaMin); }
这下有gg了,没时间还怎么用,找大神,这下大神也笑不出来了:“待我细细研究再做讨论”......
第二天,大神微微一笑,先看在显示X轴字符样式的方法里面的判断if (value == xlabels[index]),为什么我要这么去判断呢。我们知道X轴的值在显示上是平均分的,而我只有三个柱子的时候,我只要他显示三个值,所以用了xlabels[index]作为对比,只在整数位置显示拼接文字。那么问题又来了。X轴得Value是的浮点型,这样计算出柱子的平均位置就可能是浮点型,不等了自然就不显示。好了,改。
找到位置:
方法computeAxisValues(),把计算值改为int型
主要修改位置(截了修改位置的代码):
protected void computeAxisValues(float min, float max) { float yMin = min; float yMax = max; int labelCount = mAxis.getLabelCount(); double range = Math.abs(yMax - yMin); if (labelCount == 0 || range <= 0 || Double.isInfinite(range)) { mAxis.mEntries = new float[]{}; mAxis.mCenteredEntries = new float[]{}; mAxis.mEntryCount = 0; return; } // Find out how much spacing (in y value space) between axis values int rawInterval = (int)range / labelCount; int interval = (int)Utils.roundToNextSignificant(rawInterval); if (interval == 0) { interval +=1; } // If granularity is enabled, then do not allow the interval to go below specified granularity. // This is used to avoid repeated values when rounding values for display. if (mAxis.isGranularityEnabled()) interval = interval < mAxis.getGranularity() ? (int)mAxis.getGranularity() : interval; // Normalize interval double intervalMagnitude = Utils.roundToNextSignificant(Math.pow(10, (int) Math.log10(interval))); int intervalSigDigit = (int) (interval / intervalMagnitude); if (intervalSigDigit > 5) { // Use one order of magnitude higher, to avoid intervals like 0.9 or // 90 interval = (int)Math.floor(10 * intervalMagnitude); } int n = mAxis.isCenterAxisLabelsEnabled() ? 1 : 0; // force label count if (mAxis.isForceLabelsEnabled()) { interval = (int) range / (int) (labelCount - 1); mAxis.mEntryCount = labelCount; if (mAxis.mEntries.length < labelCount) { // Ensure stops contains at least numStops elements. mAxis.mEntries = new float[labelCount]; }
OK,运行代码,达到图二想要效果
五丶跪求关注下载源码,200粉小目标
欢迎关注我的博客及微信公众号,后面会给大家带来更多相关MPAndroidChart无法解决的仿MPAndroidChart图标自定义控件
源码下载记得顺便Star哦~
下载链接:https://github.com/JinBoy23520/MPAndroidChartDemoByJin