469 lines
12 KiB
Vue
469 lines
12 KiB
Vue
<template>
|
||
<div ref="chart" style="width: 96%; height: 250px"></div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onMounted, onBeforeMount, reactive, ref } from "vue";
|
||
// 局部引入echarts核心模块
|
||
import * as echarts from "echarts";
|
||
|
||
const props = defineProps({
|
||
list: {
|
||
type: Array,
|
||
default: () => {
|
||
return [];
|
||
},
|
||
},
|
||
});
|
||
|
||
const chart = ref(); // 创建DOM引用
|
||
|
||
const colors = [
|
||
{
|
||
left: "rgba(14, 252, 255, .16)",
|
||
right: "rgba(14, 252, 255, .6)",
|
||
top: "rgba(14, 252, 255, 1)",
|
||
bottom: "rgba(14, 252, 255, .46)",
|
||
front: "rgba(14, 252, 255, .66)",
|
||
},
|
||
{
|
||
left: "rgba(14, 252, 255, .16)",
|
||
right: "rgba(14, 252, 255, .6)",
|
||
top: "rgba(14, 252, 255, 1)",
|
||
bottom: "rgba(14, 252, 255, .46)",
|
||
front: "rgba(14, 252, 255, .66)",
|
||
},
|
||
{
|
||
left: "rgba(14, 252, 255, .16)",
|
||
right: "rgba(14, 252, 255, .6)",
|
||
top: "rgba(14, 252, 255, 1)",
|
||
bottom: "rgba(14, 252, 255, .46)",
|
||
front: "rgba(14, 252, 255, .66)",
|
||
},
|
||
];
|
||
const maxList = ref([]);
|
||
// const valueList = [20, 53, 47, 65, 29, 11, 10];
|
||
const data = reactive({
|
||
list: [],
|
||
option: {},
|
||
Max: 200,
|
||
valueList: [20, 53, 47, 65, 29, 11, 10],
|
||
xxname: [
|
||
|
||
],
|
||
});
|
||
// 注册5个面图形:左侧、前面、右面、上面、下面
|
||
//c0:左下角,c1:右下角,c2:右上角,c3:左上角
|
||
// 绘制左侧面-ok rgba(103, 180, 233, 0.04)
|
||
const CubeLeft_1 = echarts.graphic.extendShape({
|
||
shape: {
|
||
x: 0,
|
||
y: 0,
|
||
},
|
||
buildPath: function (ctx, shape) {
|
||
// 会canvas的应该都能看得懂,shape是从custom传入的
|
||
const xAxisPoint = shape.xAxisPoint;
|
||
const c0 = [shape.x - 20, shape.y];
|
||
const c1 = [shape.x - 7, shape.y - 14];
|
||
const c2 = [xAxisPoint[0] - 7, xAxisPoint[1] - 14];
|
||
const c3 = [xAxisPoint[0] - 20, 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 CubeFront_1 = echarts.graphic.extendShape({
|
||
shape: {
|
||
x: 0,
|
||
y: 0,
|
||
},
|
||
buildPath: function (ctx, shape) {
|
||
// 会canvas的应该都能看得懂,shape是从custom传入的
|
||
const xAxisPoint = shape.xAxisPoint;
|
||
const c0 = [shape.x - 20, shape.y];
|
||
const c1 = [shape.x + 2, shape.y];
|
||
const c2 = [xAxisPoint[0] + 2, xAxisPoint[1]];
|
||
const c3 = [xAxisPoint[0] - 20, 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_1 = echarts.graphic.extendShape({
|
||
shape: {
|
||
x: 0,
|
||
y: 0,
|
||
},
|
||
buildPath: function (ctx, shape) {
|
||
const xAxisPoint = shape.xAxisPoint;
|
||
const c0 = [shape.x + 2, shape.y];
|
||
const c1 = [shape.x + 15, shape.y - 14];
|
||
const c2 = [xAxisPoint[0] + 15, xAxisPoint[1] - 14];
|
||
const c3 = [xAxisPoint[0] + 2, 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 CubeTop_1 = echarts.graphic.extendShape({
|
||
shape: {
|
||
x: 0,
|
||
y: 0,
|
||
},
|
||
buildPath: function (ctx, shape) {
|
||
const c0 = [shape.x - 20, shape.y];
|
||
const c1 = [shape.x + 2, shape.y];
|
||
const c2 = [shape.x + 15, shape.y - 14];
|
||
const c3 = [shape.x - 7, shape.y - 14];
|
||
ctx
|
||
.moveTo(c0[0], c0[1])
|
||
.lineTo(c1[0], c1[1])
|
||
.lineTo(c2[0], c2[1])
|
||
.lineTo(c3[0], c3[1])
|
||
.closePath();
|
||
},
|
||
});
|
||
const CubeBottom_1 = echarts.graphic.extendShape({
|
||
shape: {
|
||
x: 0,
|
||
y: 0,
|
||
},
|
||
buildPath: function (ctx, shape) {
|
||
// 会canvas的应该都能看得懂,shape是从custom传入的
|
||
const xAxisPoint = shape.xAxisPoint;
|
||
|
||
const c0 = [xAxisPoint[0] - 20, xAxisPoint[1]];
|
||
const c1 = [xAxisPoint[0] + 2, xAxisPoint[1]];
|
||
const c2 = [xAxisPoint[0] + 15, xAxisPoint[1] - 14];
|
||
const c3 = [xAxisPoint[0] - 7, xAxisPoint[1] - 14];
|
||
|
||
ctx
|
||
.moveTo(c0[0], c0[1])
|
||
.lineTo(c1[0], c1[1])
|
||
.lineTo(c2[0], c2[1])
|
||
.lineTo(c3[0], c3[1])
|
||
.closePath();
|
||
},
|
||
});
|
||
|
||
echarts.graphic.registerShape("CubeLeft_1", CubeLeft_1);
|
||
echarts.graphic.registerShape("CubeFront_1", CubeFront_1);
|
||
echarts.graphic.registerShape("CubeRight_1", CubeRight_1);
|
||
echarts.graphic.registerShape("CubeTop_1", CubeTop_1);
|
||
echarts.graphic.registerShape("CubeBottom_1", CubeBottom_1);
|
||
const getOption = () => {
|
||
data.option = {
|
||
tooltip: {
|
||
trigger: "axis",
|
||
formatter: "{b0}:{c1}",
|
||
},
|
||
legend: {
|
||
data: ["两慢病免费用药情况"],
|
||
top: "4%",
|
||
right: "5%",
|
||
textStyle: {
|
||
fontSize: 16,
|
||
color: "#ffffff",
|
||
},
|
||
},
|
||
grid: {
|
||
left: 10,
|
||
right: 0,
|
||
bottom: 20,
|
||
top: 70,
|
||
containLabel: true,
|
||
},
|
||
xAxis: [
|
||
{
|
||
type: "category",
|
||
data: data.xxname,
|
||
axisLine: {
|
||
show: false,
|
||
},
|
||
offset: 10,
|
||
|
||
axisTick: {
|
||
show: false,
|
||
},
|
||
axisLabel: {
|
||
show: true,
|
||
color: "#fff",
|
||
fontSize: 16,
|
||
// formatter: function (value) {
|
||
// return value.length > 3 ? value.slice(0, 2) + "..." : value;
|
||
// },
|
||
},
|
||
},
|
||
{
|
||
type: "category",
|
||
data: data.xxname,
|
||
axisLine: {
|
||
show: false,
|
||
},
|
||
offset: 10,
|
||
|
||
axisTick: {
|
||
show: false,
|
||
},
|
||
axisLabel: {
|
||
show: false,
|
||
color: "#fff",
|
||
fontSize: 16,
|
||
},
|
||
},
|
||
],
|
||
yAxis: {
|
||
min: 0,
|
||
max: data.Max,
|
||
// interval: 100,
|
||
type: "value",
|
||
axisLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
color: "rgba(255, 255, 255, .16)",
|
||
},
|
||
},
|
||
splitLine: {
|
||
show: true,
|
||
lineStyle: {
|
||
type: "dashed",
|
||
color: "rgba(255, 255, 255, .16)",
|
||
},
|
||
},
|
||
axisTick: {
|
||
show: false,
|
||
},
|
||
axisLabel: {
|
||
show: true,
|
||
fontSize: 16,
|
||
color: "#fff",
|
||
},
|
||
},
|
||
series: [
|
||
//阴影部分
|
||
{
|
||
type: "custom",
|
||
renderItem: function (params, api) {
|
||
// console.log(api);
|
||
const location = api.coord([api.value(0), api.value(1)]);
|
||
return {
|
||
type: "group",
|
||
children: [
|
||
{
|
||
type: "CubeBottom_1",
|
||
shape: {
|
||
api,
|
||
x: location[0],
|
||
y: location[1],
|
||
xAxisPoint: api.coord([api.value(0), 0]),
|
||
},
|
||
style: {
|
||
fill: "rgba(103, 180, 233, .16)",
|
||
},
|
||
},
|
||
{
|
||
type: "CubeLeft_1",
|
||
shape: {
|
||
api,
|
||
x: location[0],
|
||
y: location[1],
|
||
xAxisPoint: api.coord([api.value(0), 0]),
|
||
},
|
||
style: {
|
||
fill: "rgba(103, 180, 233, .04)",
|
||
},
|
||
},
|
||
{
|
||
type: "CubeFront_1",
|
||
shape: {
|
||
api,
|
||
x: location[0],
|
||
y: location[1],
|
||
xAxisPoint: api.coord([api.value(0), 0]),
|
||
},
|
||
style: {
|
||
fill: "rgba(103, 180, 233, .16)",
|
||
},
|
||
},
|
||
{
|
||
type: "CubeRight_1",
|
||
shape: {
|
||
api,
|
||
x: location[0],
|
||
y: location[1],
|
||
xAxisPoint: api.coord([api.value(0), 0]),
|
||
},
|
||
style: {
|
||
fill: "rgba(103, 180, 233, .08)",
|
||
},
|
||
},
|
||
{
|
||
type: "CubeTop_1",
|
||
shape: {
|
||
api,
|
||
x: location[0],
|
||
y: location[1],
|
||
xAxisPoint: api.coord([api.value(0), 0]),
|
||
},
|
||
style: {
|
||
fill: "rgba(103, 180, 233, .26)",
|
||
},
|
||
},
|
||
],
|
||
};
|
||
},
|
||
data: maxList.value,
|
||
},
|
||
{
|
||
name:'两慢病免费用药情况',
|
||
type: "custom",
|
||
itemStyle: {
|
||
color:'#0efdff',
|
||
},
|
||
renderItem: (params, api) => {
|
||
const location = api.coord([api.value(0), api.value(1)]);
|
||
|
||
return {
|
||
type: "group",
|
||
children: [
|
||
{
|
||
type: "CubeBottom_1",
|
||
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: colors[`${params.dataIndexInside % 3}`]["bottom"],
|
||
},
|
||
},
|
||
{
|
||
type: "CubeLeft_1",
|
||
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: colors[`${params.dataIndexInside % 3}`]["left"],
|
||
},
|
||
},
|
||
{
|
||
type: "CubeFront_1",
|
||
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: colors[`${params.dataIndexInside % 3}`]["front"],
|
||
},
|
||
},
|
||
{
|
||
type: "CubeRight_1",
|
||
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: colors[`${params.dataIndexInside % 3}`]["right"],
|
||
},
|
||
},
|
||
{
|
||
type: "CubeTop_1",
|
||
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: colors[`${params.dataIndexInside % 3}`]["top"],
|
||
},
|
||
},
|
||
],
|
||
};
|
||
},
|
||
|
||
data: data.valueList,
|
||
},
|
||
//顶部字体
|
||
{
|
||
type: "bar",
|
||
xAxisIndex: 1,
|
||
label: {
|
||
show: true,
|
||
fontSize: 18,
|
||
position: "top",
|
||
color: "#ffffff",
|
||
formatter: function (data) {
|
||
return data.value - 5;
|
||
},
|
||
},
|
||
itemStyle: {
|
||
color: "rgba(221, 242, 255, 0)",
|
||
},
|
||
|
||
data: data.valueList.map((item) => parseInt(item) + 5),
|
||
barWidth: 20,
|
||
},
|
||
],
|
||
};
|
||
};
|
||
const setChart = () => {
|
||
var myChart = echarts.init(chart.value);
|
||
myChart.setOption(data.option);
|
||
};
|
||
const getMaxCeilingValue = (arr) => {
|
||
let max = Math.max(...arr); // 找到数组中的最大值
|
||
return Math.ceil(max / 100) * 100; // 将最大值向上取整到最近的100的倍数
|
||
};
|
||
const setChart1 = () => {
|
||
data.valueList = [];
|
||
data.xxname = [];
|
||
if (data.list.length !== 0) {
|
||
data.list.forEach((item) => {
|
||
data.xxname.push(item.name); //信息名
|
||
data.valueList.push(item.num); //信息数
|
||
});
|
||
}
|
||
};
|
||
|
||
onBeforeMount(() => {
|
||
setTimeout(() => {
|
||
data.list = props.list;
|
||
setChart1();
|
||
data.Max = getMaxCeilingValue(data.valueList);
|
||
maxList.value = data.valueList.map((item) => parseInt(data.Max) * 0.9); // 生成新的数组,将每个值都替换为 data.Max 的90%
|
||
getOption();
|
||
setChart();
|
||
}, 800);
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped></style>
|