XCL-Charts中的仪表盘是我封装的最麻烦的图之一。原因嘛,用过的人都知道,这类图太有特色了,要弄出一个适用于大部份情况的封装出来实在不容易。
还好,经过一翻折腾,总算搞出来一套自已感觉还行的方法。
先展示下效果:
还可以吧。
这类图封装分开看,从总布局角度看分为180,270,90,360等不同角度的仪表盘。从内容看则主要有两个部份的难点,丰富多彩的各类环与各类指针。
大家注意观察下上图demo中的环与指针就明白有多少类吧。
我在封装时,把不同风格的环分为8大类. 来绘制处理大部份各类环形风格,然后用户可通过属性的细调来画出适合自已需求的图。
因为类别太多,我就不在这一一对每个环形轴显示成什么样举例了。
至于指针,如demo所见,我在这展示了几种不同风格的指针,及其多指针叠加显示的方法。 这当然不包含全部,通过属性的组合设置及与环形轴的配合。
用户可以定制各种类型的指针。因为基本的计算和绘制要素图表库已经搭建好并开放出来了。所以不用担心没合适的指针可绘制。
指针是一方面,回到我们的主要问题点。demo中有各种各类的图,是不是我在图表库中每一个都独立封装一个呢?
答案当然是不,我的解决方法如下:
前面提过,我封装了8大类的轴风格。在实现绘制时,用户可以自己决定add哪些轴,并显示在图中的哪个位置。
我的方法很明显了,把所有的决定权交给用户,通过用户自己的add,再通过相关的轴的属性设置来画出他们自己满意的效果。
他们有多少创意,都可以通过自由组合方式绘制出来。
噢,忘记了,还有一个仪表盘中文字的显示。常要定制各种不同的文字,对于这个,我的解决方法同样是,把决定权交给用户。
让用户定好文字及设置好paint画笔属性后,传入用户指定的显示位置即可。 想怎么弄就怎么弄吧,我上图的demo已经证明了。
说这么多没用,我拿上面demo其中混合图(包含了270,180,90三种仪表盘及不同轴的add方法)的例子的代码在这展示下吧。
/** * Copyright 2014 XCL-Charts * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @Project XCL-Charts * @Description Android图表基类库演示 * @author XiongChuanLiang<br/>([email protected]) * @license http://www.apache.org/licenses/ Apache v2 License * @version 1.3 */ package com.demo.xclcharts.view; import java.util.ArrayList; import java.util.List; import org.xclcharts.chart.DialChart; import org.xclcharts.common.DensityUtil; import org.xclcharts.common.MathHelper; import org.xclcharts.renderer.XEnum; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.util.AttributeSet; import android.util.Log; public class DialChart07View extends GraphicalView { private String TAG = "DialChart07View"; private DialChart chart = new DialChart(); private DialChart chart180 = new DialChart(); private DialChart chart90 = new DialChart(); private float mPercentage = 0.9f; public DialChart07View(Context context) { super(context); // TODO Auto-generated constructor stub initView(); } public DialChart07View(Context context, AttributeSet attrs){ super(context, attrs); initView(); } public DialChart07View(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(); } private void initView() { chartRender(); chartRender90(); chartRender180(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); chart.setChartRange(w ,h ); chart180.setChartRange(w/2 ,h/3 ); chart90.setChartRange(w ,h/3 ); } public void chartRender() { try { chart.setPadding(0, DensityUtil.dip2px(getContext(), 100), 0, 0); //设置标题背景 chart.setApplyBackgroundColor(true); chart.setBackgroundColor( (int)Color.rgb(28, 129, 243) ); //绘制边框 chart.showRoundBorder(); chart.setTotalAngle(270f); //设置当前百分比 chart.getPointer().setPercentage(mPercentage); //设置指针长度 chart.getPointer().setLength(0.65f,0.2f); //增加轴承 addAxis(); ///////////////////////////////////////////////////////////// //增加指针 addPointer(); //设置附加信息 addAttrInfo(); ///////////////////////////////////////////////////////////// } catch (Exception e) { // TODO Auto-generated catch block Log.e(TAG, e.toString()); } } public void chartRender180() { try { chart180.setTotalAngle(180f); chart180.setStartAngle(180f); //设置当前百分比 chart180.getPointer().setPercentage(mPercentage); //设置指针长度 chart180.getPointer().setPointerStyle(XEnum.PointerStyle.TRIANGLE); chart180.getPointer().setLength(0.65f,0.2f); List<Float> ringPercentage = new ArrayList<Float>(); float rper = MathHelper.getInstance().div(1, 4); //相当于40% //270, 4 ringPercentage.add(rper); ringPercentage.add(rper); ringPercentage.add(rper); ringPercentage.add(rper); List<Integer> rcolor = new ArrayList<Integer>(); rcolor.add((int)Color.rgb(242, 110, 131)); rcolor.add((int)Color.rgb(238, 204, 71)); rcolor.add((int)Color.rgb(42, 231, 250)); rcolor.add((int)Color.rgb(140, 196, 27)); chart180.addStrokeRingAxis(0.75f,0.6f, ringPercentage, rcolor); chart180.getPlotAxis().get(0).getFillAxisPaint().setColor((int)Color.rgb(28, 129, 243) ); Paint paintTB = new Paint(); paintTB.setColor(Color.WHITE); paintTB.setTextAlign(Align.CENTER); paintTB.setTextSize(22); paintTB.setAntiAlias(true); chart180.addAttributeInfo(XEnum.Location.BOTTOM, "180度仪表盘", 0.5f, paintTB); } catch (Exception e) { // TODO Auto-generated catch block Log.e(TAG, e.toString()); } } public void chartRender90() { try { chart90.setPadding(DensityUtil.dip2px(getContext(), 150),0, 0, 0); chart90.setTotalAngle(90f); chart90.setStartAngle(270f); List<Float> ringPercentage = new ArrayList<Float>(); float rper = MathHelper.getInstance().div(1, 2); //相当于40% //270, 4 ringPercentage.add(rper); ringPercentage.add(rper); List<Integer> rcolor = new ArrayList<Integer>(); rcolor.add((int)Color.rgb(242, 110, 131)); rcolor.add((int)Color.rgb(238, 204, 71)); chart90.addStrokeRingAxis(0.75f,0.6f, ringPercentage, rcolor); chart90.getPlotAxis().get(0).getFillAxisPaint().setColor((int)Color.rgb(28, 129, 243) ); chart90.getPointer().setLength(0.65f); Paint paintTB = new Paint(); paintTB.setColor(Color.WHITE); paintTB.setTextAlign(Align.CENTER); paintTB.setTextSize(22); paintTB.setAntiAlias(true); chart90.addAttributeInfo(XEnum.Location.BOTTOM, "90度仪表盘", 0.5f, paintTB); } catch (Exception e) { // TODO Auto-generated catch block Log.e(TAG, e.toString()); } } public void addAxis() { List<String> rlabels2 = new ArrayList<String>(); for(int i=0;i<7;i++) { rlabels2.add(Integer.toString(i * 10)); } chart.addInnerTicksAxis(0.7f, rlabels2); chart.getPlotAxis().get(0).getAxisPaint().setColor(Color.WHITE); chart.getPlotAxis().get(0).getAxisPaint().setStrokeWidth(8); chart.getPlotAxis().get(0).getTickMarksPaint().setColor(Color.WHITE); chart.getPlotAxis().get(0).getTickLabelPaint().setColor(Color.WHITE); List<String> rlabels3 = new ArrayList<String>(); for(int i=0;i<5;i++) { if(0 == i) { rlabels3.add(""); }else rlabels3.add(Integer.toString(i * 10)); } chart.addOuterTicksAxis(0.8f, rlabels3); chart.getPlotAxis().get(1).getAxisPaint().setColor(Color.RED); chart.getPlotAxis().get(1).getAxisPaint().setStrokeWidth(5); chart.getPointer().setPointerStyle(XEnum.PointerStyle.TRIANGLE); chart.getPointer().getPointerPaint().setStrokeWidth(3); chart.getPointer().getPointerPaint().setStyle(Style.FILL); chart.getPointer().getPointerPaint().setColor((int)Color.rgb(242, 110, 131)); chart.getPointer().getBaseCirclePaint().setColor((int)Color.rgb(238, 204, 71)); chart.getPointer().setBaseRadius(10f); } //增加指针 public void addPointer() { } private void addAttrInfo() { Paint paintTB = new Paint(); paintTB.setColor(Color.WHITE); paintTB.setTextAlign(Align.CENTER); paintTB.setTextSize(22); paintTB.setAntiAlias(true); chart.addAttributeInfo(XEnum.Location.BOTTOM, "270度仪表盘", 0.5f, paintTB); } public void setCurrentStatus(float percentage) { mPercentage = percentage; //清理 chart.clearAll(); chart90.clearAll(); chart180.clearAll(); //设置当前百分比 chart.getPointer().setPercentage(mPercentage); addAxis(); //增加指针 addPointer(); addAttrInfo(); chartRender180(); chartRender90(); chart90.getPointer().setPercentage(mPercentage); chart180.getPointer().setPercentage(mPercentage); } @Override public void render(Canvas canvas) { // TODO Auto-generated method stub try{ chart.render(canvas); chart90.render(canvas); chart180.render(canvas); } catch (Exception e){ Log.e(TAG, e.toString()); } } }
代码有点乱,但用于展示功能足够了。
好了,不多说了,想要了具体了解的,自己上github或开源中国下代码看吧。
相信我,我弄的这个图表库,总有一点功能会是你所需要的。 嘿嘿。
BLOG:http://blog.csdn.net/xcl168
Mail: [email protected]
XCL-Charts强大的仪表盘