仪表盘
仪表盘的简介
仪表盘(Gauge)是一种拟物化的图表,刻度表示度量,指针表示维度,指针角度表示数值。仪表盘图表就像汽车的速度表一样,有一个圆形的表盘及相应的刻度,有一个指针指向当前数值。目前很多的管理报表或报告上都是用这种图表,以直观的表现出某个指标的进度或实际情况。
仪表盘的好处在于它能跟人们的常识结合,使大家马上能理解看什么、怎么看。拟物化的方式使图标变得更友好更人性化
,正确使用可以提升用户体验。
仪表盘的圆形结构,可以更有效的利用空间
。
为了视觉上的不拥挤且符合常识,我们建议指针的数量不超过 3 根。
仪表盘的构成
图表类型 | 仪表盘 |
---|---|
适合的数据 | 一个分类字段,一个连续字段 |
功能 |
对比 分类字段对应的数值大小
|
数据与图形的映射 | 指针映射到分类字段,指针的角度映射连续字段 |
适合的数据条数 | 小于等于3 |
仪表盘的应用场景
适合仪表盘的场景
时钟&表
- 图表说明:与普通仪表盘相比,该种图表坐标轴的首尾相连
- 场景说明:钟表
- 数据说明:有3维度,分类数据表示秒针、分针、时针,时间数值数据映射指针角度,长度数值数据映射表针大小
时针 | 分针 | 秒针 |
---|---|---|
0~24 | 0~60 | 0~60 |
$(function(){
var Shape = G2.Shape;
var Vector = G2.Canvas.Matrix.Vector2;
// 自定义Shape 部分
Shape.registShape('point', 'clock', {
drawShape: function(cfg, group){
var point; // 针尖点
var point1; // 针尾点1
var point2; // 针尾点2
var center;
var shape;
var r; // 中心点半径
var v1; // 指针向量
var v2; // 与指针垂直向量
var vstash;
point = cfg.points[0];
point.y = cfg.size;
point = this.parsePoint(point);
center = this.parsePoint({
x: 0,
y: 0
});
r = 20 * (1-cfg.size);
v1 = Vector.sub(point, center);
v2 = v1.vertical();
shape = group.addShape('circle', {
attrs: {
x: center.x,
y: center.y,
r: r/1.3,
fill: cfg.color
}
});
// v2.negate();
v2.setLength(r/2);
point1 = Vector.add(v2, center);
point2 = Vector.add({
x: -v2.x,
y: -v2.y
}, center);
shape = group.addShape('polygon', {
attrs: {
points: [
[point1.x, point1.y],
[point2.x, point2.y],
[point.x, point.y]
],
lineWidth: 2,
arrow: true,
fill: cfg.color
}
});
return shape;
}
});
// G2 语法部分
var color = ['#18B7D6', '#EFCF6E', '#E47668'];
var chart = new G2.Chart({
id : 'c2',
forceFit: true,
height: 500,
plotCfg: {
margin: 50
}
});
chart.legend(false);
chart.tooltip(false);
chart.source(getData(),{
'value': {type: 'linear',min: 0,max: 12, tickCount:12}
});
chart.coord('clock');
chart.axis('value', {
labels: {
label: {
fontSize: 14
},
autoRotate: false
},
line: {
stroke: "#ccc"
},
tickLine: {
stroke: "#333",
value: -10
},
labelOffset: -12
});
chart.point()
.position('value')
.size('length',0.8, 0.4)
.color('name', ['#333333', '#333333', '#CC0000'])
.shape('clock');
chart.render();
function getData(){
var date = new Date();
var data = [
{name: 'hour', value: date.getHours(), length: 5},
{name: 'minute', value: date.getMinutes()*12/60, length: 9},
{name: 'second', value: date.getSeconds()*12/60, length: 10}
];
return data;
}
setInterval(function(){
chart.changeData(getData());
}, 1000);
});
投资收益率
- 场景说明:下图是蚂蚁金服某金融产品的投资收益率
- 数据说明:有1维度,收益率数值数据映射指针角度
var Shape = G2.Shape;
// 自定义Shape 部分
Shape.registShape('point', 'dashBoard', {
drawShape: function(cfg, group){
var origin = cfg.origin; // 原始数据
var value = origin.value;
var point = cfg.points[0]; // 获取第一个标记点
point = this.parsePoint({ // 将标记点转换到画布坐标
x: point.x,
y: 0.95
});
var center = this.parsePoint({ // 获取极坐标系下画布中心点
x: 0,
y: 0
});
var r = 20;
var ra = 0.8 * r;
var X1 = center.x;
var Y1 = center.y;
var X2 = point.x;
var Y2 = point.y;
var B = 150/180;
var Xa,Xb,Xc,Ya,Yb,Yc; // 绘制小箭头需要的三个点
var shape;
if (Y1==Y2) {
if(X1>X2){
Xa = X2 + Math.cos(B)* ra;
Ya = Y2 - Math.sin(B)* ra;
Xb = X2 + Math.cos(B)* ra;
Yb = Y2 + Math.sin(B)* ra;
Xc = X2 + 2 * ra;
Yc = Y2;
}else{
Xa = X2 - Math.cos(B)* ra;
Ya = Y2 - Math.sin(B)* ra;
Xb = X2 - Math.cos(B)* ra;
Yb = Y2 + Math.sin(B)* ra;
Xc = X2 - 2 * ra;
Yc = Y2;
}
}else if(Y1>Y2){
var A = Math.atan((X1 - X2) / (Y1 - Y2));
Xa = X2 + ra * Math.sin(A + B);
Ya = Y2 + ra * Math.cos(A + B);
Xb = X2 + ra * Math.sin(A - B);
Yb = Y2 + ra * Math.cos(A - B);
Xc = X2 + 2 * ra * Math.sin(A);
Yc = Y2 + 2 * ra * Math.cos(A);
}else{
if(X1>X2){
var A = Math.atan((Y2 - Y1) / (X1 - X2));
Xa = X2 + ra * Math.cos(A + B);
Ya = Y2 - ra * Math.sin(A + B);
Xb = X2 + ra * Math.cos(A - B);
Yb = Y2 - ra * Math.sin(A - B);
Xc = X2 + 2 * ra * Math.cos(A);
Yc = Y2 - 2 * ra * Math.sin(A);
}else{
var A = Math.atan((Y2 - Y1) / (X2 - X1));
Xa = X2 - ra * Math.cos(A - B);
Ya = Y2 - ra * Math.sin(A - B);
Xb = X2 - ra * Math.cos(A + B);
Yb = Y2 - ra * Math.sin(A + B);
Xc = X2 - 2 * ra * Math.cos(A);
Yc = Y2 - 2 * ra * Math.sin(A);
}
}
shape = group.addShape('circle', {
attrs:{
x: X2,
y: Y2,
r: r,
fill: cfg.color
}
});
group.addShape('circle', {
attrs:{
x: X2,
y: Y2,
r: r/2,
fill: 'white'
}
});
// 添加文本1
group.addShape('text', {
attrs: {
x: X1,
y: Y1-25,
text: '当前收益率',
fontSize: 32,
fill: '#CCCCCC',
textAlign: 'center'
}
});
// 添加文本2
group.addShape('text', {
attrs: {
x: X1,
y: Y1+25,
text: value,
fontSize: 32,
fill: '#F75B5B',
textAlign: 'center'
}
});
group.addShape('polygon', {
attrs: {
points: [
[Xa, Ya],
[Xc, Yc],
[Xb, Yb],
[Xa, Ya]
],
fill: cfg.color
}
});
return shape;
}
});
// G2 语法部分
var color = ['#18B7D6', '#EFCF6E', '#E47668'];
var chart = new G2.Chart({
id : 'c3',
forceFit: true,
height: 500,
plotCfg: {
margin: 100
}
});
chart.source(creatData());
chart.coord('gauge', {
startAngle: -9/8 * Math.PI,
endAngle: 1/8 * Math.PI
});
chart.col('value', {
min: 0,
max: 0.15,
tickInterval: 0.075
});
chart.axis('value', {
tickLine: {
stroke: '#EEEEEE'
},
labelOffset: -26
});
chart.point().position('value').shape('dashBoard').color('value', function(v){ // 根据值的大小确定标记的颜色
var rst;
if ( v < 0.05 ) {
rst = color[0];
} else if ( v < 0.1 ){
rst = color[1];
} else {
rst = color[2];
}
return rst;
});
chart.legend(false);
draw(creatData());
function draw(data) {
var val = data[0].value;
var lineWidth = 30;
chart.guide().clear();
chart.guide().arc([0, 0.95],[0.15, 0.95],{ // 底灰色
stroke: '#CCCCCC',
lineWidth: lineWidth
});
val > 0.05 && chart.guide().arc([0, 0.95],[0.05, 0.95],{ // 低收益率
stroke: color[0],
lineWidth: lineWidth
});
val > 0.1 && chart.guide().arc([0.05, 0.95],[0.1, 0.95],{ // 中收益率
stroke: color[1],
lineWidth: lineWidth
});
val > 0 && val <= 0.05 && chart.guide().arc([0, 0.95],[val, 0.95],{ // 低收益率
stroke: color[0],
lineWidth: lineWidth
});
val > 0.05 && val <= 0.1 && chart.guide().arc([0.05, 0.95],[val, 0.95],{ // 中收益率
stroke: color[1],
lineWidth: lineWidth
});
val > 0.1 && val <= 0.15 && chart.guide().arc([0.1, 0.95],[val, 0.95],{ // 中收益率
stroke: color[2],
lineWidth: lineWidth
});
chart.changeData(data);
}
function creatData(){
var data = [];
var val = 0.13;
val = val.toFixed(3);
data.push({value: Number(val)});
return data;
}