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/>(xcl_168@aliyun.com)
* @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: xcl_168@aliyun.com