2025-06-04 11:18:40 +08:00

605 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<canvas
v-if="canvasId"
:id="canvasId"
:canvasId="canvasId"
:style="{
width: cWidth * pixelRatio + 'px',
height: cHeight * pixelRatio + 'px',
transform: 'scale(' + 1 / pixelRatio + ')',
'margin-left': (-cWidth * (pixelRatio - 1)) / 2 + 'px',
'margin-top': (-cHeight * (pixelRatio - 1)) / 2 + 'px',
}"
:ontouch="true"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
@error="error"
>
</canvas>
</template>
<script>
// import { min } from "moment";
import uCharts from "./u-charts.js";
var canvases = {};
export default {
props: {
chartType: {
required: true,
type: String,
default: "column",
},
opts: {
required: true,
type: Object,
default() {
return null;
},
},
canvasId: {
type: String,
default: "u-canvas",
},
cWidth: {
default: uni.upx2px(375),
},
cHeight: {
default: uni.upx2px(250),
},
pixelRatio: {
type: Number,
default: 1,
},
legends: {
type: Boolean,
default: true,
},
},
data() {
return {
colors: [
"#5181F6",
"#00DBB6",
"#F67F51",
"#FF515A",
"#8B5CFF",
"#00CA69",
],
_opts: {}
};
},
mounted() {
// this.$nextTick(() => {
// this.init();
// })
},
watch: {
_opts: {
handler(newVal, oldVal) {
// console.log("发生改变了123", newVal)
this.init();
this.changeData(this.canvasId, newVal);
},
// deep: true,
// immediate: true,
},
opts: {
handler(newVal, oldVal) {
// console.log("发生改变了", newVal)
this._opts = newVal;
// // this.init();
// // console.log('canvases')
// console.log(canvases)
// if (canvases = {}) {
// // this.$nextTick(() => {
// // this.init();
// // })
// setTimeout(()=>{
// this.init();
// this.changeData(this.canvasId, newVal);
// },600)
// } else {
// }
},
deep: true,
immediate: true,
},
},
methods: {
init() {
console.log("图表初始化");
switch (this.chartType) {
case "column":
this.$nextTick(() => {
console.log("图表初始化1");
this.initColumnChart();
});
break;
case "line":
this.$nextTick(() => {
console.log("图表初始化2");
this.initLineChart();
});
break;
case "arcbar": //半圆
console.log("图表初始化3");
setTimeout(() => {
this.initArcbarChart();
}, 1200);
break;
case "ring": //圆环
this.$nextTick(() => {
console.log("图表初始化4");
this.initRingChart();
});
case "columnar": //柱状图
this.$nextTick(() => {
console.log("图表初始化5");
this.initColumnarChart();
});
break;
case "pie": //圆环
this.$nextTick(() => {
console.log("图表初始化6");
this.initPieChart();
});
break;
case "mix": //混合图
this.$nextTick(() => {
console.log("图表初始化7");
this.initMixChart();
});
break;
default:
break;
}
},
initColumnChart() {
// console.log(3333, structuredClone(this._opts.series[0]))
// .data.sort((a, b) => { a - b})[0] + 20
console.log(2222222, uni.upx2px(11));
canvases[this.canvasId] = new uCharts({
// $this: this,
// canvasId: this.canvasId,
context: uni.createCanvasContext(this.canvasId, this),
type: "column",
legend: {
show: false,
},
padding: [uni.upx2px(30), 0, uni.upx2px(20), uni.upx2px(20)],
colors: this.colors,
fontSize: uni.upx2px(22),
background: "#FFFFFF",
pixelRatio: this.pixelRatio,
// animation: true,
categories: this._opts.categories,
series: this._opts.series,
enableScroll: true,
textDataTitle: this._opts.textDataTitle ? this._opts.textDataTitle : '',
textLabelX: this._opts.textDataX ? true : false,
textDataX: this._opts.textDataX,
animation: false,
update: true,
duration: 0,
xAxis: {
disableGrid: true,
itemCount: 4,
labelCount: this._opts.categories.length,
fontSize: uni.upx2px(22),
lineHeight: uni.upx2px(40),
scrollShow: true,
// rotateLabel: true,
},
yAxis: {
format: (val) => {
if ((val + "").indexOf(".") != -1) {
return val.toFixed(0); //保留小数后1位
} else {
return val;
}
},
// data:{
// }
// axisLine:false
//disabled:true
},
dataLabel: true,
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
column: {
type: "group",
width: uni.upx2px(28),
},
},
scales: {
xAxis: [
{
stacked: true,
ticks: {
fontColor: "red", // X轴样式
},
},
],
},
});
},
initLineChart() {
canvases[this.canvasId] = new uCharts({
context: uni.createCanvasContext(this.canvasId, this),
type: "line",
fontSize: uni.upx2px(22),
legend: {
show: this.legends,
},
dataLabel: false,
dataPointShape: true,
colors: this.colors,
background: "#FFFFFF",
pixelRatio: this.pixelRatio,
categories: this._opts.categories,
series: this._opts.series,
animation: true,
enableScroll: true,
xAxis: {
type: "grid",
axisLine: false,
gridColor: "#fff",
gridType: "dash",
dashLength: 8,
itemCount: 4,
scrollShow: true,
fontSize: uni.upx2px(22),
},
yAxis: {
axisLine: false,
// gridType: 'dash',
gridColor: "rgba(42, 43, 91, 0.1)",
// dashLength: 8,
// splitNumber: 5,
min: 0,
// max: 180,
// format: (val) => {
// return val.toFixed(0) + '元'
// }
},
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
line: {
type: "curve",
},
},
});
},
//半圆
initArcbarChart() {
let winWidth = 0;
uni.getSystemInfo({
success: function (res) {
winWidth = res.windowWidth / 2 - 10;
},
});
canvases[this.canvasId] = new uCharts({
context: uni.createCanvasContext(this.canvasId, this),
type: "arcbar",
fontSize: 11,
legend: {
show: false,
},
background: "#FFFFFF",
pixelRatio: 1,
series: this._opts.series,
animation: true,
width: this.cWidth,
height: this.cHeight,
dataLabel: true,
subtitle: {
name: this._opts.series[0].name,
color: "#000",
fontSize: 25,
offsetY: -12,
},
extra: {
arcbar: {
type: "default",
width: 12,
startAngle: 1,
endAngle: 0,
gap: 5,
radius: 90,
center: {
y: 100,
x: winWidth,
},
},
},
});
},
//圆环
initRingChart() {
console.log("this.canvasId", this.canvasId);
var dataLabel = false,
legend = false;
var radius = 0;
if (this.canvasId == "integritySafety") {
dataLabel = legend = true;
}
if (this.canvasId == "qualityPieChart") {
radius = 30;
}
canvases[this.canvasId] = new uCharts({
context: uni.createCanvasContext(this.canvasId, this),
type: "ring",
fontSize: uni.upx2px(22),
title: this._opts.title,
legend: {
show: legend,
},
extra: {
ring: {
ringWidth: uni.upx2px(24),
offsetAngle: -90,
activeRadius: radius,
},
tooltip: {
showBox: false,
},
},
width: this.cWidth,
height: this.cHeight,
background: "#FFFFFF",
series: this._opts.series,
dataLabel: dataLabel,
});
},
// 饼图
initPieChart() {
console.log("我是饼图", this.canvasId);
// return
canvases[this.canvasId] = new uCharts({
context: uni.createCanvasContext(this.canvasId, this),
type: "pie",
fontSize: uni.upx2px(26),
title: this._opts.title,
legend: {
show: this.legends,
position: "right",
lineHeight: uni.upx2px(60),
fontSize: uni.upx2px(26),
lineHeight: uni.upx2px(44),
itemGap: uni.upx2px(20),
padding: uni.upx2px(10),
margin: uni.upx2px(10),
},
extra: {
pie: {
activeOpacity: uni.upx2px(1),
activeRadius: uni.upx2px(20),
offsetAngle: 0,
lableWidth: uni.upx2px(30),
border: true,
borderWidth: uni.upx2px(6),
borderColor: "#FFFFFF",
linearType: "custom",
},
tooltip: {
showBox: true,
dashLength: uni.upx2px(8),
boxPadding: uni.upx2px(6),
fontSize: uni.upx2px(26),
lineHeight: uni.upx2px(40),
},
markLine: {
dashLength: uni.upx2px(8),
}
},
width: this.cWidth,
height: this.cHeight,
background: "#FFFFFF",
series: this._opts.series,
dataLabel: true,
});
},
// 条状图
initColumnarChart() {
canvases[this.canvasId] = new uCharts({
context: uni.createCanvasContext(this.canvasId, this),
type: "bar",
fontSize: 11,
legend: {
show: this.legends,
},
dataLabel: false,
dataPointShape: true,
colors: this.colors,
background: "#FFFFFF",
pixelRatio: this.pixelRatio,
categories: this._opts.categories,
series: this._opts.series,
animation: true,
enableScroll: true,
textLabelX: this._opts.textDataX ? true : false,
textDataX: this._opts.textDataX,
xAxis: {
// min: 0,
// boundaryGap: "justify",
disableGrid: true,
// type: "grid",
axisLine: false,
gridColor: "#fff",
gridType: "dash",
dashLength: 8,
},
yAxis: {
// itemCount: 4,
// scrollShow: true,
// scrollShow: true,
// itemCount: 4,
// axisLine: false,
// // gridType: 'dash',
// gridColor: "rgba(42, 43, 91, 0.1)",
// // dashLength: 8,
// // splitNumber: 5,
// min: 0,
// max: 180,
// format: (val) => {
// return val.toFixed(0) + '元'
// }
},
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
bar: {
type: "group",
width: 30,
meterBorde: 1,
meterFillColor: "#FFFFFF",
activeBgColor: "#000000",
activeBgOpacity: 0.08,
categoryGap: 2,
},
tooltip: {
formatter: function (item, category, seriesName, dataIndex) {
console.log(66666, item, category, seriesName, dataIndex);
return `${seriesName} ${category}:${dataIndex}`;
},
},
},
});
},
// 混合图
initMixChart() {
canvases[this.canvasId] = new uCharts({
context: uni.createCanvasContext(this.canvasId, this),
type: "mix",
fontSize: uni.upx2px(22),
legend: {
show: this.legends,
},
dataLabel: false,
dataPointShape: true,
colors: this.colors,
background: "#FFFFFF",
pixelRatio: this.pixelRatio,
categories: this._opts.categories,
series: this._opts.series,
enableScroll: true,
animation: false,
update: true,
legend: {
itemGap: uni.upx2px(10),
},
xAxis: {
disableGrid: true,
// type: "grid",
axisLine: false,
gridColor: "#fff",
gridType: "dash",
dashLength: 7,
itemCount: 6,
fontSize: uni.upx2px(23),
lineHeight: uni.upx2px(40),
// scrollShow: true,
},
yAxis: {
disabled: false,
disableGrid: false,
splitNumber: 5,
gridType: "dash",
dashLength: uni.upx2px(8),
gridColor: "#CCCCCC",
padding: uni.upx2px(20),
showTitle: true,
data: [
{
position: "left",
title: "累计",
titleFontSize: uni.upx2px(26),
titleOffsetY: uni.upx2px(-5),
},
{
position: "right",
title: "当期",
textAlign: "left",
titleFontSize: uni.upx2px(26),
titleOffsetY: uni.upx2px(-5),
},
],
},
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
mix: {
column: {
width: uni.upx2px(20),
},
line: {
width: uni.upx2px(4),
}
},
},
});
},
// 这里仅作为示例传入两个参数cid为canvas-id,newdata为更新的数据需要更多参数请自行修改
changeData(cid, newdata) {
console.log("updateData", newdata);
console.log(canvases[cid], canvases, cid);
if (!canvases[cid]) return;
var xData = newdata.categories;
if (xData) {
for (var i = 0; i < xData.length; i++) {
if (xData[i].length > 5) {
xData[i] = xData[i].substring(0, 5) + "...";
}
}
}
canvases[cid].updateData({
series: newdata.series,
categories: xData,
title: newdata.title,
});
},
touchStart(e) {
// canvases[this.canvasId].showToolTip(e, {
// format: function (item, category) {
// return category + " " + item.name + ":" + item.data;
// },
// });
canvases[this.canvasId].scrollStart(e);
},
touchMove(e) {
canvases[this.canvasId].scroll(e);
},
touchEnd(e) {
canvases[this.canvasId].scrollEnd(e);
},
error(e) {
console.log(e);
},
},
};
</script>
<style scoped>
.charts {
width: 100%;
height: 100%;
flex: 1;
background-color: #ffffff;
}
</style>