x
1
2
<html>
3
<head>
4
<meta charset="utf-8">
5
<title>层叠柱状图(温度计隐喻)</title>
6
<script src="https://a.alipayobjects.com/jquery/jquery/1.11.1/jquery.js"></script>
7
<script src="https://gw.alipayobjects.com/as/g/datavis/g2/2.3.13/index.js"></script>
8
</head>
9
<body>
10
<div id="c1"></div>
11
<script>
12
var gapWidth = 3;
13
var Shape = G2.Shape;
14
var Util = G2.Util;
15
function getFillAttrs(cfg) {
16
var attrs = {
17
fill: cfg.color,
18
fillOpacity: cfg.opacity,
19
};
20
return attrs;
21
}
22
function getRectPath(points) {
23
var path = [];
24
for (var i = 0; i < points.length; i++) {
25
var point = points[i];
26
if (point) {
27
var action = i === 0 ? 'M' : 'L';
28
path.push([action, point.x, point.y]);
29
}
30
}
31
var first = points[0];
32
path.push(['L', first.x, first.y]);
33
path.push(['z']);
34
return path;
35
}
36
Shape.registShape('interval', 'top', {
37
drawShape(cfg, container) {
38
var points = cfg.points;
39
var attrs = getFillAttrs(cfg);
40
var path = getRectPath(cfg.points);
41
path = this.parsePath(path); // 将 0 - 1 的值转换为画布坐标
42
var realInterval = container.addShape('path', {
43
attrs: Util.mix(attrs, {
44
path,
45
}),
46
});
47
var radius = (path[2][1] - path[1][1]) / 2;
48
var temp = [];
49
temp.push(['M', path[1][1], path[1][2]]);
50
temp.push(['A', radius, radius, 90, 0, 1, (path[2][1] + path[1][1]) / 2, path[2][2] - radius]);
51
temp.push(['A', radius, radius, 90, 0, 1, path[2][1], path[2][2]]);
52
temp.push(['L', path[2][1], path[2][2]]);
53
var topShape = container.addShape('path', {
54
attrs: {
55
path: temp,
56
fill: '#fff',
57
stroke: '#000',
58
},
59
});
60
return realInterval;
61
},
62
});
63
// 中间带边的矩形
64
Shape.registShape('interval', 'other', {
65
drawShape(cfg, container) {
66
var points = cfg.points;
67
var attrs = getFillAttrs(cfg);
68
var path = getRectPath(cfg.points);
69
path = this.parsePath(path); // 将 0 - 1 的值转换为画布坐标
70
var intervalPath = [];
71
intervalPath.push(['M', path[0][1] + gapWidth, path[0][2]]);
72
intervalPath.push(['L', path[1][1] + gapWidth, path[1][2]]);
73
intervalPath.push(['L', path[2][1] - gapWidth, path[2][2]]);
74
intervalPath.push(['L', path[3][1] - gapWidth, path[3][2]]);
75
intervalPath.push(['Z']);
76
var intervalShape = container.addShape('path', {
77
attrs: Util.mix(attrs, {
78
path: intervalPath,
79
}),
80
});
81
container.addShape('line', {
82
attrs: {
83
x1: path[0][1],
84
y1: path[0][2],
85
x2: path[1][1],
86
y2: path[2][2],
87
stroke: '#000',
88
lineWidth: 1,
89
},
90
});
91
container.addShape('line', {
92
attrs: {
93
x1: path[2][1],
94
y1: path[2][2],
95
x2: path[3][1],
96
y2: path[3][2],
97
stroke: '#000',
98
lineWidth: 1,
99
},
100
});
101
return intervalShape;
102
},
103
});
104
// 底边带圆角
105
Shape.registShape('interval', 'bottom', {
106
drawShape(cfg, container) {
107
var points = cfg.points;
108
var attrs = getFillAttrs(cfg);
109
var path = getRectPath(cfg.points);
110
path = this.parsePath(path);
111
var circleStartY = path[1][2] + (path[0][2] - path[1][2]) / 3;
112
var h = path[0][2] - circleStartY;
113
var w = (path[2][1] - path[1][1]) / 2;
114
var radius = (Math.pow(w, 2) + Math.pow(h, 2)) / (2 * h);
115
var temp1 = [];
116
temp1.push(['M', path[1][1], path[1][2]]);
117
temp1.push(['L', path[1][1], circleStartY]);
118
temp1.push(['A', radius, radius, 0, 1, 0, path[2][1], circleStartY]);
119
temp1.push(['L', path[2][1], path[2][2]]);
120
var temp2 = [];
121
temp2.push(['M', path[1][1] + gapWidth, path[1][2]]);
122
temp2.push(['L', path[1][1] + gapWidth, circleStartY + gapWidth]);
123
temp2.push(['A', radius - gapWidth, radius - gapWidth, 0, 1, 0, path[2][1] - gapWidth, circleStartY + gapWidth]);
124
temp2.push(['L', path[2][1] - gapWidth, path[2][2]]);
125
container.addShape('path', {
126
attrs: Util.mix({
127
path: temp1,
128
stroke: '#000',
129
lineWidth: 1,
130
}),
131
});
132
return container.addShape('path', {
133
attrs: Util.mix(attrs, {
134
path: temp2,
135
}),
136
});
137
},
138
});
139
var colors = ["#CECA9B","#B1C753","#3CA6DF","#459E96","#2E6936","#52AD3B","#90C320","#F7B632","#F39831","#EA452F"];
140
var data = [
141
{ name: '个人奢侈品', value: 2490 },
142
{ name: '豪华车', value: 4380 },
143
{ name: '豪华酒店', value: 1830 },
144
{ name: '优质葡萄酒和烈酒', value: 660 },
145
{ name: '优质食品', value: 460 },
146
{ name: '艺术精品', value: 390 },
147
{ name: '设计师家具', value: 330 },
148
{ name: '私人飞机', value: 180 },
149
{ name: '游艇', value: 70 },
150
{ name: '豪华游轮', value: 20 },
151
];
152
var Frame = G2.Frame;
153
var frame = new Frame(data);
154
frame.addCol('type', obj => '1');
155
frame = Frame.sortBy(frame, (obj1, obj2) => obj1.value > obj2.value);
156
var max = Frame.max(frame, 'value');
157
var min = Frame.min(frame, 'value');
158
var chart = new G2.Chart({
159
id: 'c1',
160
width: 500,
161
height: 450,
162
plotCfg: {
163
margin: [20, 150, 80, 80]
164
}
165
});
166
chart.source(frame);
167
chart.axis(false);
168
chart.legend({
169
title: null,
170
mode: false // 不可点击
171
});
172
chart.tooltip({
173
title: null,
174
});
175
chart.intervalStack().position('type*value').color('name', colors).size(40)
176
.shape('name*value', (name, val) => {
177
var value = val[1] - val[0];
178
if (value === min) {
179
return 'top';
180
} else if (value === max) {
181
return 'bottom';
182
}
183
return 'other';
184
});
185
chart.render();
186
</script>
187
</body>
188
</html>
189
层叠柱状图(温度计隐喻)