|
|
@@ -1,4 +1,4 @@
|
|
|
-<template>
|
|
|
+<!-- <template>
|
|
|
<div>
|
|
|
<div ref="chart" style="width: 100%; height: 400px"></div>
|
|
|
</div>
|
|
|
@@ -50,16 +50,16 @@ export default {
|
|
|
hovertemplate: `机组:` + ` %{x} <br> ` + `故障次数:` + "%{y} 次<br>",
|
|
|
};
|
|
|
|
|
|
- // 故障时长的散点图数据(右侧 Y 轴)
|
|
|
- const scatterFaultDurations = {
|
|
|
- x: this.faultTypes.slice(0, 10),
|
|
|
- y: this.faultDurations.slice(0, 10),
|
|
|
- mode: "markers", // 散点图
|
|
|
- marker: { color: "#1A295D", size: 10 }, // 红色散点
|
|
|
- name: "故障时长",
|
|
|
- yaxis: "y2", // 使用第二个 Y 轴(右侧)
|
|
|
- hovertemplate: `机组:` + ` %{x} <br> ` + `故障时长:` + "%{y} 分钟<br>",
|
|
|
- };
|
|
|
+ // // 故障时长的散点图数据(右侧 Y 轴)
|
|
|
+ // const scatterFaultDurations = {
|
|
|
+ // x: this.faultTypes.slice(0, 10),
|
|
|
+ // y: this.faultDurations.slice(0, 10),
|
|
|
+ // mode: "markers", // 散点图
|
|
|
+ // marker: { color: "#1A295D", size: 10 }, // 红色散点
|
|
|
+ // name: "故障时长",
|
|
|
+ // yaxis: "y2", // 使用第二个 Y 轴(右侧)
|
|
|
+ // hovertemplate: `机组:` + ` %{x} <br> ` + `故障时长:` + "%{y} 分钟<br>",
|
|
|
+ // };
|
|
|
|
|
|
// 布局配置,设置双 Y 轴
|
|
|
const layout = {
|
|
|
@@ -94,20 +94,20 @@ export default {
|
|
|
tickcolor: "rgb(255,255,255)",
|
|
|
backgroundcolor: "#e5ecf6",
|
|
|
},
|
|
|
- yaxis2: {
|
|
|
- title: "故障时长(秒)",
|
|
|
- titlefont: { color: "#1A295D" },
|
|
|
- tickfont: { color: "#1A295D" },
|
|
|
- showgrid: false, // 隐藏 Y 轴网格线
|
|
|
- overlaying: "y", // 在第一个 Y 轴上方绘制
|
|
|
- side: "right", // 右侧的 Y 轴
|
|
|
- position: 1, // 调整右侧轴的位置
|
|
|
- showline: true,
|
|
|
+ // yaxis2: {
|
|
|
+ // title: "故障时长(秒)",
|
|
|
+ // titlefont: { color: "#1A295D" },
|
|
|
+ // tickfont: { color: "#1A295D" },
|
|
|
+ // showgrid: false, // 隐藏 Y 轴网格线
|
|
|
+ // overlaying: "y", // 在第一个 Y 轴上方绘制
|
|
|
+ // side: "right", // 右侧的 Y 轴
|
|
|
+ // position: 1, // 调整右侧轴的位置
|
|
|
+ // showline: true,
|
|
|
|
|
|
- // tickvals: this.faultTypes.slice(0, 10), // 保证这里是字符串数组
|
|
|
- // ticktext: this.faultTypes.slice(0, 10), // 确保 ticktext 使用相同的标签
|
|
|
- linecolor: "#1A295D", // 设置右侧轴线颜色
|
|
|
- },
|
|
|
+ // // tickvals: this.faultTypes.slice(0, 10), // 保证这里是字符串数组
|
|
|
+ // // ticktext: this.faultTypes.slice(0, 10), // 确保 ticktext 使用相同的标签
|
|
|
+ // linecolor: "#1A295D", // 设置右侧轴线颜色
|
|
|
+ // },
|
|
|
plot_bgcolor: "#e5ecf6",
|
|
|
gridcolor: "#fff",
|
|
|
bgcolor: "#e5ecf6", // 设置背景颜色
|
|
|
@@ -119,11 +119,7 @@ export default {
|
|
|
};
|
|
|
|
|
|
// 渲染图表
|
|
|
- Plotly.newPlot(
|
|
|
- this.$refs.chart,
|
|
|
- [scatterFaultCounts, scatterFaultDurations],
|
|
|
- layout
|
|
|
- );
|
|
|
+ Plotly.newPlot(this.$refs.chart, [scatterFaultCounts], layout);
|
|
|
},
|
|
|
},
|
|
|
};
|
|
|
@@ -131,4 +127,205 @@ export default {
|
|
|
|
|
|
<style scoped>
|
|
|
/* 你可以根据需要添加样式 */
|
|
|
+</style> -->
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div ref="chart" style="width: 100%; height: 500px"></div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import Plotly from "plotly.js-dist";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "faultAll",
|
|
|
+ props: {
|
|
|
+ faultTypes: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
+ faultCounts: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
+ faultDurations: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ faultCounts: {
|
|
|
+ deep: true,
|
|
|
+ handler() {
|
|
|
+ this.renderChart();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.renderChart();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // renderChart() {
|
|
|
+ // // 步骤 1:归一化 faultCounts 用于 marker.size 显示
|
|
|
+ // const rawSizes = this.faultCounts;
|
|
|
+ // const minSize = 8; // 最小圆点大小
|
|
|
+ // const maxSize = 30; // 最大圆点大小
|
|
|
+
|
|
|
+ // const sizeRange = maxSize - minSize;
|
|
|
+ // const minValue = Math.min(...rawSizes);
|
|
|
+ // const maxValue = Math.max(...rawSizes);
|
|
|
+ // const normalizedSizes = rawSizes.map((val) => {
|
|
|
+ // if (maxValue === minValue) return (minSize + maxSize) / 2;
|
|
|
+ // return ((val - minValue) / (maxValue - minValue)) * sizeRange + minSize;
|
|
|
+ // });
|
|
|
+ // console.log("durationHour", this.faultTypes);
|
|
|
+ // // 步骤 2:生成每个散点(使用归一化后的 size)
|
|
|
+ // const data = this.faultTypes.map((name, i) => {
|
|
|
+ // const durationHour = this.faultDurations.map((s) => {
|
|
|
+ // // console.log(s, "s");
|
|
|
+ // return (s / 3600).toFixed(2);
|
|
|
+ // });
|
|
|
+ // const count = this.faultCounts[i];
|
|
|
+
|
|
|
+ // return {
|
|
|
+ // x: [name],
|
|
|
+ // y: [durationHour[i]],
|
|
|
+ // mode: "markers",
|
|
|
+ // type: "scatter",
|
|
|
+ // name: name,
|
|
|
+ // marker: {
|
|
|
+ // size: normalizedSizes[i],
|
|
|
+ // sizemode: "area",
|
|
|
+ // sizeref: 1,
|
|
|
+ // sizemin: 4,
|
|
|
+ // showscale: false,
|
|
|
+ // },
|
|
|
+ // hovertemplate: `机组: ${name}<br>故障时长: ${durationHour[i]} 小时<br>故障次数: ${count} 次<extra></extra>`,
|
|
|
+ // };
|
|
|
+ // });
|
|
|
+
|
|
|
+ // const layout = {
|
|
|
+ // title: {
|
|
|
+ // text: "机组故障时长与故障次数分析",
|
|
|
+ // font: { size: 16, weight: "bold" },
|
|
|
+ // },
|
|
|
+ // xaxis: {
|
|
|
+ // title: "故障机组",
|
|
|
+ // type: "category",
|
|
|
+ // tickangle: 30,
|
|
|
+ // tickfont: { size: 12 },
|
|
|
+ // gridcolor: "rgb(255,255,255)", // 网格线颜色
|
|
|
+ // tickcolor: "rgb(255,255,255)",
|
|
|
+ // backgroundcolor: "#e5ecf6",
|
|
|
+ // showbackground: true, // 显示背景
|
|
|
+ // },
|
|
|
+ // yaxis: {
|
|
|
+ // title: "故障时长(小时)",
|
|
|
+ // tickfont: { size: 12 },
|
|
|
+ // gridcolor: "rgb(255,255,255)", // 网格线颜色
|
|
|
+ // tickcolor: "rgb(255,255,255)",
|
|
|
+ // backgroundcolor: "#e5ecf6",
|
|
|
+ // showbackground: true, // 显示背景
|
|
|
+ // },
|
|
|
+ // plot_bgcolor: "#e5ecf6",
|
|
|
+ // gridcolor: "#fff", // 设置网格线颜色
|
|
|
+ // margin: { t: 80, b: 120 },
|
|
|
+ // showlegend: true,
|
|
|
+ // legendgroup: "same",
|
|
|
+ // legend: {
|
|
|
+ // itemsizing: "constant", // ✅ 统一图例 marker 大小
|
|
|
+ // font: {
|
|
|
+ // size: 12,
|
|
|
+ // },
|
|
|
+ // },
|
|
|
+ // };
|
|
|
+
|
|
|
+ // Plotly.newPlot(this.$refs.chart, data, layout);
|
|
|
+ // },
|
|
|
+ renderChart() {
|
|
|
+ // 步骤 1:预处理,将数据打包成对象数组以便排序
|
|
|
+ const combined = this.faultTypes.map((name, i) => ({
|
|
|
+ name,
|
|
|
+ count: this.faultCounts[i],
|
|
|
+ durationHour: (this.faultDurations[i] / 3600).toFixed(2),
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 步骤 2:按 name 字符串排序
|
|
|
+ combined.sort((a, b) => a.name.localeCompare(b.name)); // 按字典序排序
|
|
|
+
|
|
|
+ // 步骤 3:归一化故障次数用于散点大小
|
|
|
+ const rawSizes = combined.map((d) => d.count);
|
|
|
+ const minSize = 8;
|
|
|
+ const maxSize = 30;
|
|
|
+ const sizeRange = maxSize - minSize;
|
|
|
+ const minValue = Math.min(...rawSizes);
|
|
|
+ const maxValue = Math.max(...rawSizes);
|
|
|
+ const normalizedSizes = rawSizes.map((val) => {
|
|
|
+ if (maxValue === minValue) return (minSize + maxSize) / 2;
|
|
|
+ return ((val - minValue) / (maxValue - minValue)) * sizeRange + minSize;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 步骤 4:生成散点图数据
|
|
|
+ const data = combined.map((d, i) => ({
|
|
|
+ x: [d.name],
|
|
|
+ y: [d.durationHour],
|
|
|
+ mode: "markers",
|
|
|
+ type: "scatter",
|
|
|
+ name: d.name,
|
|
|
+ marker: {
|
|
|
+ size: normalizedSizes[i],
|
|
|
+ sizemode: "area",
|
|
|
+ sizeref: 1,
|
|
|
+ sizemin: 4,
|
|
|
+ showscale: false,
|
|
|
+ },
|
|
|
+ hovertemplate: `机组: ${d.name}<br>故障时长: ${d.durationHour} 小时<br>故障次数: ${d.count} 次<extra></extra>`,
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 其他布局配置保持不变
|
|
|
+ const layout = {
|
|
|
+ title: {
|
|
|
+ text: "机组故障时长与故障次数分析",
|
|
|
+ font: { size: 16, weight: "bold" },
|
|
|
+ },
|
|
|
+ xaxis: {
|
|
|
+ title: "故障机组",
|
|
|
+ type: "category",
|
|
|
+ tickangle: 30,
|
|
|
+ tickfont: { size: 12 },
|
|
|
+ gridcolor: "rgb(255,255,255)",
|
|
|
+ tickcolor: "rgb(255,255,255)",
|
|
|
+ backgroundcolor: "#e5ecf6",
|
|
|
+ showbackground: true,
|
|
|
+ },
|
|
|
+ yaxis: {
|
|
|
+ title: "故障时长(小时)",
|
|
|
+ tickfont: { size: 12 },
|
|
|
+ gridcolor: "rgb(255,255,255)",
|
|
|
+ tickcolor: "rgb(255,255,255)",
|
|
|
+ backgroundcolor: "#e5ecf6",
|
|
|
+ showbackground: true,
|
|
|
+ },
|
|
|
+ plot_bgcolor: "#e5ecf6",
|
|
|
+ gridcolor: "#fff",
|
|
|
+ margin: { t: 80, b: 120 },
|
|
|
+ showlegend: true,
|
|
|
+ legendgroup: "same",
|
|
|
+ legend: {
|
|
|
+ itemsizing: "constant",
|
|
|
+ font: {
|
|
|
+ size: 12,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ Plotly.newPlot(this.$refs.chart, data, layout);
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+/* 可添加样式 */
|
|
|
</style>
|