|
|
@@ -1,401 +0,0 @@
|
|
|
-<!--
|
|
|
- * @Author: your name
|
|
|
- * @Date: 2025-01-17 17:22:04
|
|
|
- * @LastEditTime: 2025-02-24 09:19:53
|
|
|
- * @LastEditors: bogon
|
|
|
- * @Description: In User Settings Edit
|
|
|
- * @FilePath: /performance-test/src/views/performance/components/chartsCom/NoColourBandTwoDMarkerChart.vue
|
|
|
--->
|
|
|
-<template>
|
|
|
- <div style="height: 400px">
|
|
|
- <!-- 2D散点图 没色带 -->
|
|
|
- <template>
|
|
|
- <div style="display: flex; align-items: center; margin-top: 20px">
|
|
|
- <div style="margin-right: 20px; display: flex; align-items: center">
|
|
|
- <!-- <el-color-picker
|
|
|
- size="small"
|
|
|
- v-model="color1"
|
|
|
- show-alpha
|
|
|
- @change="updateChartColor"
|
|
|
- ></el-color-picker>
|
|
|
- <span style="margin-left: 10px">自定义颜色</span> -->
|
|
|
- <el-select
|
|
|
- size="small"
|
|
|
- v-model="color1"
|
|
|
- @change="updateChartColor"
|
|
|
- placeholder="选择配色方案"
|
|
|
- style="width: 200px"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="(scheme, index) in colorSchemes"
|
|
|
- :key="index"
|
|
|
- :label="scheme.label"
|
|
|
- :value="scheme.colors"
|
|
|
- :style="getOptionStyle(scheme.colors)"
|
|
|
- ></el-option>
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <!-- 图表类型切换按钮 -->
|
|
|
- <!-- <div>
|
|
|
- <el-button size="small" @click="setChartType('scatter')"
|
|
|
- >散点图</el-button
|
|
|
- >
|
|
|
- <el-button size="small" @click="setChartType('line')"
|
|
|
- >折线图</el-button
|
|
|
- >
|
|
|
- </div> -->
|
|
|
- </div>
|
|
|
- <!-- 点大小控制 -->
|
|
|
- <div style="display: flex; align-items: center">
|
|
|
- <!-- <span style="margin-right: 10px">点大小</span> -->
|
|
|
- <el-slider
|
|
|
- v-model="pointSize"
|
|
|
- :min="1"
|
|
|
- :max="15"
|
|
|
- :step="1"
|
|
|
- label="点的大小"
|
|
|
- show-stops
|
|
|
- style="width: 150px"
|
|
|
- @change="updateChartColor"
|
|
|
- ></el-slider>
|
|
|
- </div>
|
|
|
- <div v-loading="loading" ref="plotlyChart" style="height: 400px">
|
|
|
- <el-empty v-if="isError" description="请求失败"></el-empty>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-import Plotly from "plotly.js-dist";
|
|
|
-import axios from "axios";
|
|
|
-import { colorSchemes } from "@/views/overview/js/colors";
|
|
|
-import { myMixin } from "@/mixins/chartRequestMixin";
|
|
|
-
|
|
|
-export default {
|
|
|
- mixins: [myMixin],
|
|
|
- props: {
|
|
|
- fileAddr: {
|
|
|
- default: "",
|
|
|
- type: String,
|
|
|
- },
|
|
|
- index: {
|
|
|
- type: String,
|
|
|
- },
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- pointSize: 5, // 默认点大小
|
|
|
- color1: colorSchemes[0].colors, // 默认颜色
|
|
|
- // 配色方案列表(每个方案是一个颜色数组)
|
|
|
- colorSchemes: [...colorSchemes],
|
|
|
- chartData: {},
|
|
|
- chartType: "scatter", // 初始化为散点图 (scatter)
|
|
|
-
|
|
|
- selectedPoints: [],
|
|
|
- originalColors: [],
|
|
|
- originalSizes: [],
|
|
|
- };
|
|
|
- },
|
|
|
- async mounted() {
|
|
|
- this.getData();
|
|
|
- },
|
|
|
- methods: {
|
|
|
- // 根据配色方案设置每个选项的样式
|
|
|
- getOptionStyle(scheme) {
|
|
|
- return {
|
|
|
- background: `linear-gradient(to right, ${scheme.join(", ")})`,
|
|
|
- color: "#fff",
|
|
|
- height: "30px",
|
|
|
- lineHeight: "30px",
|
|
|
- borderRadius: "4px",
|
|
|
- };
|
|
|
- },
|
|
|
- async getData() {
|
|
|
- if (this.fileAddr !== "") {
|
|
|
- try {
|
|
|
- this.loading = true;
|
|
|
- this.cancelToken = axios.CancelToken.source();
|
|
|
- console.log(this.cancelToken);
|
|
|
- const resultChartsData = await axios.get(this.fileAddr, {
|
|
|
- cancelToken: this.cancelToken.token,
|
|
|
- });
|
|
|
- this.chartData = resultChartsData.data;
|
|
|
- this.drawChart();
|
|
|
- this.isError = false;
|
|
|
- this.loading = false;
|
|
|
- } catch (error) {
|
|
|
- this.isError = true;
|
|
|
- this.loading = false;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- drawChart() {
|
|
|
- const data = this.chartData.data && this.chartData.data[0];
|
|
|
- let trace = {};
|
|
|
- // 保存原始颜色和大小
|
|
|
- this.originalColors = [...data.yData];
|
|
|
- this.originalSizes = new Array(data.xData.length).fill(6); // 初始点大小
|
|
|
- if (this.chartType === "scatter") {
|
|
|
- // 绘制 2D 散点图
|
|
|
- console.log("重新绘制图表", this.color1);
|
|
|
- trace = {
|
|
|
- x: data.xData,
|
|
|
- y: data.yData,
|
|
|
- mode: "markers",
|
|
|
- type: "scattergl", // 这里改为 scattergl
|
|
|
- text: data.engineName, // 提示文本
|
|
|
- marker: {
|
|
|
- color: data.yData, // 根据 yData 的值设置颜色
|
|
|
- // colorscale: "Viridis", // 使用的颜色区间
|
|
|
- colorscale: this.color1
|
|
|
- ? [
|
|
|
- [0, "#F9FDD2"], // 颜色从 this.color1 开始
|
|
|
- [1, this.color1], // 结束颜色为其他颜色
|
|
|
- ]
|
|
|
- : [
|
|
|
- [0, "#F9FDD2"],
|
|
|
- [0.15, "#E9F6BD"],
|
|
|
- [0.3, "#C2E3B9"],
|
|
|
- [0.45, "#8AC8BE"],
|
|
|
- [0.6, "#5CA8BF"],
|
|
|
- [0.75, "#407DB3"],
|
|
|
- [0.9, "#2E4C9A"],
|
|
|
- [1, "#1B2973"],
|
|
|
- ],
|
|
|
- // colorbar: {
|
|
|
- // title: data.colorbartitle, // 色标标题
|
|
|
- // },
|
|
|
- size: new Array(data.xData.length).fill(this.pointSize), // 初始点大小
|
|
|
- },
|
|
|
- hovertemplate:
|
|
|
- `${this.chartData.xaixs}:` +
|
|
|
- ` %{x} <br> ` +
|
|
|
- `${this.chartData.yaixs}:` +
|
|
|
- "%{y} <br> <extra></extra>", // 在 hover 中显示格式化后的时间
|
|
|
- // customdata: data.colorbar || data.color, // 将格式化后的时间存入 customdata
|
|
|
- };
|
|
|
- } else if (this.chartType === "line") {
|
|
|
- // 折线图
|
|
|
- trace = {
|
|
|
- x: data.xData,
|
|
|
- y: data.yData,
|
|
|
- mode: "lines",
|
|
|
- type: "scattergl", // 折线图
|
|
|
- text: data.engineName,
|
|
|
- line: {
|
|
|
- color: this.color1, // 使用自定义颜色
|
|
|
- },
|
|
|
- };
|
|
|
- } else if (this.chartType === "bar") {
|
|
|
- // 柱状图
|
|
|
- trace = {
|
|
|
- x: data.xData,
|
|
|
- y: data.yData,
|
|
|
- type: "bar", // 柱状图
|
|
|
- marker: {
|
|
|
- color: this.color1, // 使用自定义颜色
|
|
|
- },
|
|
|
- };
|
|
|
- }
|
|
|
- // 图表布局;
|
|
|
- const layout = {
|
|
|
- title: data.title,
|
|
|
- xaxis: {
|
|
|
- title: this.chartData.xaixs,
|
|
|
- showline: false, // 隐藏x轴轴线
|
|
|
- zeroline: false, // 隐藏零轴
|
|
|
- gridcolor: "#fff", // 设置x轴网格线颜色
|
|
|
- gridcolor: "rgb(255,255,255)", // 网格线颜色
|
|
|
- tickcolor: "rgb(255,255,255)",
|
|
|
- backgroundcolor: "#e5ecf6",
|
|
|
- showbackground: true, // 显示背景
|
|
|
- },
|
|
|
- yaxis: {
|
|
|
- showline: false, // 隐藏x轴轴线
|
|
|
- zeroline: false, // 隐藏零轴
|
|
|
- gridcolor: "#fff", // 设置x轴网格线颜色
|
|
|
- title: this.chartData.yaixs,
|
|
|
- line: {
|
|
|
- show: false,
|
|
|
- },
|
|
|
- gridcolor: "rgb(255,255,255)", // 网格线颜色
|
|
|
- tickcolor: "rgb(255,255,255)",
|
|
|
- backgroundcolor: "#e5ecf6",
|
|
|
- showbackground: true, // 显示背景
|
|
|
- },
|
|
|
- showlegend: false,
|
|
|
- plot_bgcolor: "#e5ecf6",
|
|
|
- gridcolor: "#fff", // 设置网格线颜色
|
|
|
- };
|
|
|
- const config = {
|
|
|
- modeBarButtonsToAdd: [
|
|
|
- {
|
|
|
- name: "选择",
|
|
|
- icon: Plotly.Icons.pencil,
|
|
|
- click: (gd) => this.handleSelectClick(gd),
|
|
|
- },
|
|
|
- {
|
|
|
- name: "清除选中",
|
|
|
- icon: Plotly.Icons.undo,
|
|
|
- click: (gd) => this.handleClearSelect(gd),
|
|
|
- },
|
|
|
- {
|
|
|
- name: "下载CSV文件",
|
|
|
- icon: Plotly.Icons.disk,
|
|
|
- click: (gd) => this.handleDownloadCSV(gd),
|
|
|
- },
|
|
|
- ],
|
|
|
- modeBarButtonsToRemove: [
|
|
|
- // 移除不需要的工具按钮
|
|
|
- "lasso2d",
|
|
|
- ],
|
|
|
- displaylogo: false,
|
|
|
- editable: true,
|
|
|
- scrollZoom: false,
|
|
|
- };
|
|
|
- // 使用 Plotly 绘制图表
|
|
|
- Plotly.react(this.$refs.plotlyChart, [trace], layout, config).then(() => {
|
|
|
- // 确保在图表加载完成后设置工具栏按钮
|
|
|
- const plotElement = this.$refs.plotlyChart;
|
|
|
- Plotly.relayout(plotElement, layout); // 使用 relayout 来确保自定义按钮应用
|
|
|
- });
|
|
|
- },
|
|
|
- handleSelectClick(gd) {
|
|
|
- // 绑定 plotly_click 事件
|
|
|
- gd.on("plotly_click", (data) => {
|
|
|
- const pointIndex = data.points[0].pointIndex;
|
|
|
- const xClick = data.points[0].x;
|
|
|
- const yClick = data.points[0].y;
|
|
|
-
|
|
|
- // 将点击的点添加到选中的点数组
|
|
|
- this.selectedPoints.push({
|
|
|
- x: xClick, // 点击点的 x 坐标
|
|
|
- y: yClick, // 点击点的 y 坐标
|
|
|
- index: pointIndex, // 点击点的索引
|
|
|
- time: data.points[0].text, // 点击点的时间信息
|
|
|
- });
|
|
|
-
|
|
|
- // 初始化颜色和大小数组
|
|
|
- let newColors = [...this.originalColors];
|
|
|
- let newSize = [...this.originalSizes];
|
|
|
-
|
|
|
- // 如果选中的点数大于等于3,进行多边形选择区域的处理
|
|
|
- if (this.selectedPoints.length >= 3) {
|
|
|
- const xv = this.selectedPoints.map((p) => p.x);
|
|
|
- const yv = this.selectedPoints.map((p) => p.y);
|
|
|
-
|
|
|
- // 判断点是否在多边形内
|
|
|
- function inPolygon(x, y, xv, yv) {
|
|
|
- let inside = false;
|
|
|
- for (let i = 0, j = xv.length - 1; i < xv.length; j = i++) {
|
|
|
- const intersect =
|
|
|
- yv[i] > y !== yv[j] > y &&
|
|
|
- x < ((xv[j] - xv[i]) * (y - yv[i])) / (yv[j] - yv[i]) + xv[i];
|
|
|
- if (intersect) inside = !inside;
|
|
|
- }
|
|
|
- return inside;
|
|
|
- }
|
|
|
-
|
|
|
- // 用于跟踪已添加的 (x, y) 组合
|
|
|
- const addedPoints = {};
|
|
|
-
|
|
|
- // 遍历图表数据中的所有点,检查是否在多边形内
|
|
|
- gd.data[0].x.forEach((xVal, i) => {
|
|
|
- const yVal = gd.data[0].y[i];
|
|
|
- if (inPolygon(xVal, yVal, xv, yv)) {
|
|
|
- const pointKey = `${xVal}-${yVal}`;
|
|
|
- if (!addedPoints[pointKey]) {
|
|
|
- this.selectedPoints.push({
|
|
|
- x: gd.data[0].x[i],
|
|
|
- y: gd.data[0].y[i],
|
|
|
- time: gd.data[0].text[i],
|
|
|
- });
|
|
|
-
|
|
|
- newColors[i] = "red"; // 高亮选择的点
|
|
|
- newSize[i] = 10; // 设置点的大小
|
|
|
- addedPoints[pointKey] = true;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- // 更新选中点的颜色和大小
|
|
|
- this.selectedPoints.forEach((point) => {
|
|
|
- newColors[point.index] = "red";
|
|
|
- newSize[point.index] = 10;
|
|
|
- });
|
|
|
-
|
|
|
- // 使用 Plotly.restyle 更新颜色和大小
|
|
|
- Plotly.restyle(gd, {
|
|
|
- "marker.color": [newColors],
|
|
|
- "marker.size": [newSize],
|
|
|
- });
|
|
|
-
|
|
|
- // 处理选中的数据
|
|
|
- this.getSelectData(this.selectedPoints, gd.layout);
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- handleClearSelect(gd) {
|
|
|
- this.selectedPoints = [];
|
|
|
- Plotly.restyle(gd, {
|
|
|
- "marker.color": [this.originalColors],
|
|
|
- "marker.size": [this.originalSizes],
|
|
|
- });
|
|
|
- },
|
|
|
- getSelectData(selectedPoints, layout) {
|
|
|
- // 在这里处理选中的数据,您可以将其展示或导出等
|
|
|
- console.log("选中的点数据:", selectedPoints);
|
|
|
- console.log("布局信息:", layout);
|
|
|
- },
|
|
|
- handleDownloadCSV(gd) {
|
|
|
- if (this.selectedPoints.length === 0) {
|
|
|
- alert("没有选中的数据");
|
|
|
- return;
|
|
|
- }
|
|
|
- this.downloadCSV();
|
|
|
- },
|
|
|
-
|
|
|
- downloadCSV() {
|
|
|
- const headers = [this.chartData.xaixs, this.chartData.yaixs];
|
|
|
- const csvRows = [headers]; // 保存标头
|
|
|
- // 使用 Set 或 Map 去重
|
|
|
- const uniquePoints = [];
|
|
|
- this.selectedPoints.forEach((point) => {
|
|
|
- if (!uniquePoints.some((p) => p.x === point.x && p.y === point.y)) {
|
|
|
- uniquePoints.push(point);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 将去重后的点加入 CSV 数据
|
|
|
- uniquePoints.forEach((point) => {
|
|
|
- csvRows.push(`${point.x},${point.y}`);
|
|
|
- });
|
|
|
-
|
|
|
- const csvString = csvRows.join("\n");
|
|
|
- const blob = new Blob([csvString], { type: "text/csv; charset=utf-8" });
|
|
|
- const url = URL.createObjectURL(blob);
|
|
|
- const a = document.createElement("a");
|
|
|
- a.href = url;
|
|
|
- a.download = "selected_data.csv";
|
|
|
- a.click();
|
|
|
- URL.revokeObjectURL(url);
|
|
|
- },
|
|
|
- setChartType(type) {
|
|
|
- // 切换图表类型
|
|
|
- this.chartType = type;
|
|
|
- this.drawChart(); // 重新绘制图表
|
|
|
- },
|
|
|
-
|
|
|
- updateChartColor(color) {
|
|
|
- // 更新图表颜色
|
|
|
- // this.color1 = color;
|
|
|
- console.log(this.color1, "this.color1");
|
|
|
- this.drawChart();
|
|
|
- },
|
|
|
- },
|
|
|
-};
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped></style>
|