ly-front/src/components/columnChart.vue

346 lines
9.1 KiB
Vue
Raw Normal View History

2025-03-31 15:26:29 +00:00
<template>
<div class="age_distribution">
<div :id="id"></div>
</div>
</template>
<script>
import * as echarts from "echarts";
import "echarts-gl";
export default {
name: "AgeDistricolumn",
props: {
xData: {
type: Array,
required: true
},
seriesData: {
type: Array,
required: true
},
config: {
type: Object,
default: () => {
return {
bottom: "22%"
};
}
},
className: {
type: String,
default: "tooltip-box"
},
id: {
type: String,
default: "column"
}
},
data() {
return {
x: [],
series: []
};
},
watch: {
xData: {
handler: function (newVal) {
this.x = newVal;
}
},
seriesData: {
handler: function (newVal) {
this.series = newVal;
this.getPeople();
}
}
},
mounted() {},
methods: {
// 柱图
getPeople() {
const offsetX = 10;
const offsetY = 5;
// 绘制左侧面
const CubeLeft = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
// 会canvas的应该都能看得懂shape是从custom传入的
const xAxisPoint = shape.xAxisPoint;
// console.log(shape);
const c0 = [shape.x, shape.y];
const c1 = [shape.x - offsetX, shape.y - offsetY];
const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
const c3 = [xAxisPoint[0], xAxisPoint[1]];
ctx
.moveTo(c0[0], c0[1])
.lineTo(c1[0], c1[1])
.lineTo(c2[0], c2[1])
.lineTo(c3[0], c3[1])
.closePath();
}
});
// 绘制右侧面
const CubeRight = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
const xAxisPoint = shape.xAxisPoint;
const c1 = [shape.x, shape.y];
const c2 = [xAxisPoint[0], xAxisPoint[1]];
const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
const c4 = [shape.x + offsetX, shape.y - offsetY];
ctx
.moveTo(c1[0], c1[1])
.lineTo(c2[0], c2[1])
.lineTo(c3[0], c3[1])
.lineTo(c4[0], c4[1])
.closePath();
}
});
// 绘制顶面
const CubeTop = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
const c1 = [shape.x, shape.y];
const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
const c3 = [shape.x, shape.y - offsetX];
const c4 = [shape.x - offsetX, shape.y - offsetY];
ctx
.moveTo(c1[0], c1[1])
.lineTo(c2[0], c2[1])
.lineTo(c3[0], c3[1])
.lineTo(c4[0], c4[1])
.closePath();
}
});
// 注册三个面图形
echarts.graphic.registerShape("CubeLeft", CubeLeft);
echarts.graphic.registerShape("CubeRight", CubeRight);
echarts.graphic.registerShape("CubeTop", CubeTop);
var myChart = echarts.init(document.getElementById(this.id));
let bottom = "22%";
let top = "9%";
if (this.config.bottom) {
bottom = this.config.bottom;
}
if (this.config.top) {
top = this.config.top;
}
let option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
},
padding: 0,
className: this.className,
formatter: function (params) {
const item = params[1];
return `
<div class="tooltip-item">
<div class="uqn"></div>
<div class="toolTipName">${item.name}</div>
<div class="toolTipValue">${item.value}</div>
</div>
`;
}
},
grid: {
left: "0%",
right: "0%",
top: top,
bottom: bottom,
containLabel: true
},
xAxis: {
type: "category",
data: this.x,
axisLine: {
show: true,
lineStyle: {
width: 2,
color: "rgba(186, 231, 255, 0.6)" //轴线颜色
}
},
axisTick: {
show: false
},
axisLabel: {
fontSize: 14,
textStyle: {
color: "rgba(230, 247, 255, 1)" //轴字体色
}
}
},
yAxis: {
type: "value",
splitNumber: 4, //分割段数,需要注意的是这个分割段数只是个预估值
minInterval: 1, //最小间隔
axisLine: {
show: false,
lineStyle: {
width: 2,
color: "rgba(186, 231, 255, 1)"
}
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(255, 255, 255, 0.12)"
}
},
axisTick: {
show: false
},
axisLabel: {
fontSize: 12,
textStyle: {
color: "rgba(230, 247, 255, 1)" //轴字体色
}
}
},
series: [
{
type: "custom",
renderItem: (params, api) => {
const location = api.coord([api.value(0), api.value(1)]);
return {
type: "group",
children: [
{
type: "CubeLeft",
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1],
xAxisPoint: api.coord([api.value(0), 0])
},
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(133, 200, 255, 1)"
},
{
offset: 1,
color: "rgba(133, 200, 255, 0.1)"
}
])
}
},
{
type: "CubeRight",
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1],
xAxisPoint: api.coord([api.value(0), 0])
},
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(133, 200, 255, 1)"
},
{
offset: 1,
color: "rgba(133, 200, 255, 0.1)"
}
])
}
},
{
type: "CubeTop",
shape: {
api,
xValue: api.value(0),
yValue: api.value(1),
x: location[0],
y: location[1],
xAxisPoint: api.coord([api.value(0), 0])
},
style: {
fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(201, 225, 254, 1)"
},
{
offset: 1,
color: "rgba(201, 225, 254, 1)"
}
])
}
}
]
};
},
data: this.series
},
{
type: "bar",
label: {
normal: {
show: false,
position: "top",
formatter: (e) => {
return e.value + "条";
},
fontSize: 13,
color: "#43C4F1",
offset: [0, 0]
}
},
itemStyle: {
color: "transparent"
},
tooltip: {},
data: this.series
}
]
};
myChart.setOption(option);
// 让图表自适应容器大小
window.addEventListener("resize", function () {
myChart.resize();
});
}
}
};
</script>
<style lang="scss" scoped>
.age_distribution {
position: relative;
width: 100%;
height: 100%;
#column {
z-index: 3;
width: 90%;
height: 80%;
margin-top: 10%;
margin-left: 5%;
}
#column1 {
z-index: 3;
width: 90%;
height: 80%;
margin-top: 10%;
margin-left: 5%;
}
}
</style>