echarts 3D 柱状图
今天开发一个驾驶舱大屏,里面有柱状图的图表,而且是3D的,搜索可视化社区,有找到一个示例【https://www.makeapie.cn/echarts_content/xH0E6KFMcG.html】,纵向的柱子,但我开发的大屏,柱状图有横向、纵向两种,所以在此记录一下,便于下一次开发。
注意:示例中是直接把echarts挂在了window上,作为全局。
效果如下:
1 <template> 2 <!-- 横向的3D柱状图 --> 3 <div ref="echartRef" :style="{ width: width, height: height }"></div> 4 </template> 5 <script> 6 import {chunk} from "lodash"; 7 export default { 8 props: { 9 width: { 10 default: "100%", 11 }, 12 height: { 13 default: "100%", 14 }, 15 data: { 16 default: () => [],//[{label.value}] 17 type: Array, 18 }, 19 }, 20 data() { 21 return { 22 myChart: null, 23 }; 24 }, 25 computed:{ 26 dataStringify(){ 27 return JSON.stringify(this.data||[]) 28 } 29 }, 30 watch:{ 31 dataStringify:{ 32 handler(){ 33 this.initOption() 34 } 35 } 36 }, 37 mounted() { 38 this.myChart = this.$echarts.init(this.$refs.echartRef); 39 this.myChart.resize(); 40 window.addEventListener("resize", this.resize); 41 }, 42 beforeDestroy() { 43 this.myChart && this.myChart.dispose(); 44 window.removeEventListener("resize", this.resize); 45 }, 46 methods: { 47 resize() { 48 this.myChart && this.myChart.resize(); 49 }, 50 initOption() { 51 const VALUE = (this.data||[]).map(one=>one.value); 52 const NAMES = (this.data||[]).map(one=>one.label); 53 const CubeLeft = echarts.graphic.extendShape({ 54 shape: { 55 x: 0, 56 y: 0, 57 }, 58 buildPath: function (ctx, shape) { 59 const yAxisPoint = shape.yAxisPoint; 60 const c0 = [shape.x, shape.y]; 61 const c1 = [shape.x + 6, shape.y - 6]; 62 const c2 = [yAxisPoint[0] + 6, yAxisPoint[1] - 6]; 63 const c3 = [yAxisPoint[0], yAxisPoint[1]]; 64 ctx 65 .moveTo(c0[0], c0[1]) 66 .lineTo(c1[0], c1[1]) 67 .lineTo(c2[0], c2[1]) 68 .lineTo(c3[0], c3[1]) 69 .closePath(); 70 }, 71 }); 72 const CubeRight = echarts.graphic.extendShape({ 73 shape: { 74 x: 0, 75 y: 0, 76 }, 77 buildPath: function (ctx, shape) { 78 const yAxisPoint = shape.yAxisPoint; 79 const c1 = [shape.x, shape.y]; 80 const c2 = [yAxisPoint[0], yAxisPoint[1]]; 81 const c3 = [yAxisPoint[0] + 6, yAxisPoint[1] + 12]; 82 const c4 = [shape.x + 6, shape.y + 12]; 83 ctx 84 .moveTo(c1[0], c1[1]) 85 .lineTo(c2[0], c2[1]) 86 .lineTo(c3[0], c3[1]) 87 .lineTo(c4[0], c4[1]) 88 .closePath(); 89 }, 90 }); 91 const CubeTop = echarts.graphic.extendShape({ 92 shape: { 93 x: 0, 94 y: 0, 95 }, 96 buildPath: function (ctx, shape) { 97 const c1 = [shape.x, shape.y]; 98 const c2 = [shape.x + 6, shape.y + 12]; 99 const c3 = [shape.x + 12, shape.y + 6]; 100 const c4 = [shape.x + 6, shape.y - 6]; 101 ctx 102 .moveTo(c1[0], c1[1]) 103 .lineTo(c2[0], c2[1]) 104 .lineTo(c3[0], c3[1]) 105 .lineTo(c4[0], c4[1]) 106 .closePath(); 107 }, 108 }); 109 echarts.graphic.registerShape("CubeLeft", CubeLeft); 110 echarts.graphic.registerShape("CubeRight", CubeRight); 111 echarts.graphic.registerShape("CubeTop", CubeTop); 112 113 let option = { 114 backgroundColor: "transparent", 115 tooltip: { 116 show: true, 117 trigger: "axis", 118 axisPointer: { 119 type: "none", 120 }, 121 formatter: function (params) { 122 // <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#1B7EF2;"></span> 123 const item = params[0]; 124 return item.name + " : " + item.value; 125 }, 126 }, 127 grid: { 128 left: 20, 129 right: 10, 130 bottom: 10, 131 top: 0, 132 containLabel: true, 133 }, 134 yAxis: { 135 type: "category", 136 data: NAMES, 137 axisLine: { 138 show: false, 139 lineStyle: { 140 color: "white", 141 }, 142 }, 143 offset: 0, 144 axisTick: { 145 show: false, 146 }, 147 axisLabel: { 148 fontSize: 12, 149 interval: 0, 150 formatter: (label) => { 151 // 最多展示6个文字 152 // let text = chunk((label || "").split(""), 6) 153 // .map((one) => one.join("")) 154 // .join("\n"); 155 let text = label || ""; 156 text = text.substr(0, 6); 157 if (label && label.length > 6) { 158 text += "..."; 159 } 160 return text; 161 }, 162 }, 163 }, 164 xAxis: { 165 type: "value", 166 axisLine: { 167 show: false, 168 }, 169 splitLine: { 170 show: false, 171 }, 172 axisTick: { 173 show: false, 174 }, 175 axisLabel: { 176 show: false, 177 }, 178 }, 179 series: [ 180 { 181 type: "custom", 182 renderItem: (params, api) => { 183 const location = api.coord([api.value(0), api.value(1)]); 184 return { 185 type: "group", 186 children: [ 187 { 188 type: "CubeLeft", 189 shape: { 190 api, 191 xValue: api.value(0), 192 yValue: api.value(1), 193 x: location[0], 194 y: location[1], 195 yAxisPoint: api.coord([0, api.value(1)]), 196 }, 197 style: { 198 fill: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ 199 { 200 offset: 0, 201 color: "rgba(0,0,0,0.4)", 202 }, 203 { 204 offset: 0.3, 205 color: "RGBA(16, 76, 145, 0.3)", 206 }, 207 { 208 offset: 0.5, 209 color: "RGBA(16, 76, 145, 0.6)", 210 }, 211 { 212 offset: 1, 213 color: "RGBA(16, 76, 145, 1)", 214 }, 215 ]), 216 }, 217 }, 218 { 219 type: "CubeRight", 220 shape: { 221 api, 222 xValue: api.value(0), 223 yValue: api.value(1), 224 x: location[0], 225 y: location[1], 226 yAxisPoint: api.coord([0, api.value(1)]), 227 }, 228 style: { 229 fill: new echarts.graphic.LinearGradient(0, 0, 1, 0, [ 230 { 231 offset: 0, 232 color: "rgba(0,0,0,0.4)", 233 }, 234 { 235 offset: 0.3, 236 color: "rgba(27, 126, 242, 0.3)", 237 }, 238 { 239 offset: 0.5, 240 color: "rgba(27, 126, 242, 0.6)", 241 }, 242 { 243 offset: 1, 244 color: "rgba(27, 126, 242, 1)", 245 }, 246 ]), 247 }, 248 }, 249 { 250 type: "CubeTop", 251 shape: { 252 api, 253 xValue: api.value(0), 254 yValue: api.value(1), 255 x: location[0], 256 y: location[1], 257 yAxisPoint: api.coord([0, api.value(1)]), 258 }, 259 style: { 260 fill: new echarts.graphic.LinearGradient(1, 0, 0, 0, [ 261 { 262 offset: 0, 263 color: "#3B80E2", 264 }, 265 { 266 offset: 1, 267 color: "#49BEE5", 268 }, 269 ]), 270 }, 271 }, 272 ], 273 }; 274 }, 275 data: VALUE, 276 }, 277 ], 278 }; 279 this.myChart.setOption(option); 280 this.myChart.resize(); 281 }, 282 }, 283 }; 284 </script>
1 <template> 2 <!-- 纵向的柱状图 --> 3 <div ref="echartRef" :style="{ width: width, height: height }"></div> 4 </template> 5 <script> 6 import { chunk } from "lodash"; 7 export default { 8 props: { 9 width: { 10 default: "100%", 11 }, 12 height: { 13 default: "100%", 14 }, 15 data: { 16 default: () => [], //[{label.value}] 17 type: Array, 18 }, 19 }, 20 data() { 21 return { 22 myChart: null, 23 }; 24 }, 25 computed: { 26 dataStringify() { 27 return JSON.stringify(this.data || []); 28 }, 29 }, 30 watch: { 31 dataStringify: { 32 handler() { 33 this.initOption(); 34 }, 35 }, 36 }, 37 mounted() { 38 this.myChart = this.$echarts.init(this.$refs.echartRef); 39 this.myChart.resize(); 40 window.addEventListener("resize", this.resize); 41 }, 42 beforeDestroy() { 43 this.myChart && this.myChart.dispose(); 44 window.removeEventListener("resize", this.resize); 45 }, 46 methods: { 47 resize() { 48 this.myChart && this.myChart.resize(); 49 }, 50 initOption() { 51 const VALUE = (this.data || []).map((one) => one.value); 52 const NAMES = (this.data || []).map((one) => one.label); 53 // 绘制左侧面 54 const CubeLeft = echarts.graphic.extendShape({ 55 shape: { 56 x: 0, 57 y: 0, 58 }, 59 buildPath: function (ctx, shape) { 61 const xAxisPoint = shape.xAxisPoint; 62 const c0 = [shape.x + 2, shape.y]; 63 const c1 = [shape.x - 7, shape.y - 1]; 64 const c2 = [xAxisPoint[0] - 7, xAxisPoint[1] - 3]; 65 const c3 = [xAxisPoint[0] + 2, xAxisPoint[1]]; 66 ctx 67 .moveTo(c0[0], c0[1]) 68 .lineTo(c1[0], c1[1]) 69 .lineTo(c2[0], c2[1]) 70 .lineTo(c3[0], c3[1]) 71 .closePath(); 72 }, 73 }); 74 // 绘制右侧面 75 const CubeRight = echarts.graphic.extendShape({ 76 shape: { 77 x: 0, 78 y: 0, 79 }, 80 buildPath: function (ctx, shape) { 81 const xAxisPoint = shape.xAxisPoint; 82 const c1 = [shape.x + 2, shape.y]; 83 const c2 = [xAxisPoint[0] + 2, xAxisPoint[1]]; 84 const c3 = [xAxisPoint[0] + 10, xAxisPoint[1] - 5]; 85 const c4 = [shape.x + 10, shape.y - 5]; 86 ctx 87 .moveTo(c1[0], c1[1]) 88 .lineTo(c2[0], c2[1]) 89 .lineTo(c3[0], c3[1]) 90 .lineTo(c4[0], c4[1]) 91 .closePath(); 92 }, 93 }); 94 // 绘制顶面 95 const CubeTop = echarts.graphic.extendShape({ 96 shape: { 97 x: 0, 98 y: 0, 99 }, 100 buildPath: function (ctx, shape) { 101 const c1 = [shape.x + 2, shape.y + 3]; 102 const c2 = [shape.x + 10, shape.y - 5]; //右点 103 const c3 = [shape.x - 0, shape.y - 7]; 104 const c4 = [shape.x - 7, shape.y - 1]; 105 ctx 106 .moveTo(c1[0], c1[1]) 107 .lineTo(c2[0], c2[1]) 108 .lineTo(c3[0], c3[1]) 109 .lineTo(c4[0], c4[1]) 110 .closePath(); 111 }, 112 }); 113 // 注册三个面图形 114 echarts.graphic.registerShape("CubeLeft", CubeLeft); 115 echarts.graphic.registerShape("CubeRight", CubeRight); 116 echarts.graphic.registerShape("CubeTop", CubeTop); 117 let option = { 118 backgroundColor: "transparent", 119 tooltip: { 120 trigger: "axis", 121 axisPointer: { 122 type: "shadow", 123 }, 124 formatter: function (params) { 125 const item = params[0]; 126 return item.name + " : " + item.value; 127 }, 128 }, 129 grid: { 130 left: 20, 131 top: 10, 132 // bottom: 30, 133 bottom:0, 134 right: 20, 135 containLabel: true, 136 }, 137 xAxis: { 138 offset:12, 139 type: "category", 140 data: NAMES, 141 axisLine: { 142 show: true, 143 lineStyle: { 144 color: "#0C315D", 145 }, 146 }, 147 axisTick: { 148 show: false, 149 }, 150 axisLabel: { 151 rotate:35, 152 textStyle: { 153 color: "#FFF", 154 }, 155 fontSize: 12, 156 interval: 0, 157 formatter: (label) => { 158 let text = chunk(((label||'').substr(0,8) || "").split(""), 4) 159 .map((one) => one.join("")) 160 .join("\n"); 161 return text; 162 }, 163 }, 164 }, 165 yAxis: [{ 166 type: "value", 167 axisLine: { 168 show: false, 169 lineStyle: { 170 color: "#7ebaf2", 171 }, 172 }, 173 splitLine: { 174 show: false, 175 }, 176 axisTick: { 177 show: false, 178 }, 179 splitNumber: 4, 180 axisLabel: { 181 fontSize: 12, 182 textStyle: { 183 color: "#FFF", 184 }, 185 }, 186 }], 187 series: [ 188 { 189 type: "custom", 190 renderItem: (params, api) => { 191 let cubeLeftStyle = ""; 192 let cubeRightStyle = ""; 193 let cubeTopStyle = ""; 194 // 颜色 195 cubeLeftStyle = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ 196 { 197 offset: 0, 198 color: "rgba(27, 126, 242, 0.8)", 199 }, 200 { 201 offset: 0.5, 202 color: "rgba(27, 126, 242, 0.6)", 203 }, 204 { 205 offset: 0.8, 206 color: "rgba(27, 126, 242, 0.3)", 207 }, 208 { 209 offset: 1, 210 color: "rgba(0,0,0,0.2)", 211 }, 212 ]); 213 cubeRightStyle = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ 214 { 215 offset: 0, 216 color: "rgba(23,176,255,1)", 217 }, 218 { 219 offset: 0.5, 220 color: "rgba(23,176,255, 0.6)", 221 }, 222 { 223 offset: 0.8, 224 color: "rgba(23,176,255, 0.3)", 225 }, 226 { 227 offset: 1, 228 color: "rgba(0,0,0,0.2)", 229 }, 230 ]); 231 cubeTopStyle = new echarts.graphic.LinearGradient(0, 0, 0, 1, [ 232 { 233 offset: 0, 234 color: "rgba(27, 126, 242, 1)", 235 }, 236 { 237 offset: 1, 238 color: "rgba(27, 126, 242, 1)", 239 }, 240 ]); 241 //颜色end 242 const location = api.coord([api.value(0), api.value(1)]); 243 return { 244 type: "group", 245 children: [ 246 { 247 type: "CubeLeft", 248 shape: { 249 api, 250 xValue: api.value(0), 251 yValue: api.value(1), 252 x: location[0], 253 y: location[1], 254 xAxisPoint: api.coord([api.value(0), 0]), 255 }, 256 style: { 257 fill: cubeLeftStyle, 258 }, 259 }, 260 { 261 type: "CubeRight", 262 shape: { 263 api, 264 xValue: api.value(0), 265 yValue: api.value(1), 266 x: location[0], 267 y: location[1], 268 xAxisPoint: api.coord([api.value(0), 0]), 269 }, 270 style: { 271 fill: cubeRightStyle, 272 }, 273 }, 274 { 275 type: "CubeTop", 276 shape: { 277 api, 278 xValue: api.value(0), 279 yValue: api.value(1), 280 x: location[0], 281 y: location[1], 282 xAxisPoint: api.coord([api.value(0), 0]), 283 }, 284 style: { 285 fill: cubeTopStyle, 286 }, 287 }, 288 ], 289 }; 290 }, 291 data: VALUE, 292 }, 293 ], 294 }; 295 296 this.myChart.setOption(option); 297 this.myChart.resize(); 298 }, 299 }, 300 }; 301 </script>