| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 |
- <template>
- <div>
- <!-- ECharts 图表容器 -->
- <div class="section">
- <el-input
- size="small"
- v-model="xiaoval"
- placeholder="请输入查询范围"
- @input="handleInput"
- ></el-input>
- <span>—</span>
- <el-input
- size="small"
- v-model="daval"
- placeholder="请输入查询范围"
- @input="handleInput"
- ></el-input>
- <el-button size="small" @click="chaxun">确定</el-button>
- <div v-if="PXshow" class="eigenvalue">
- <el-checkbox-group v-model="checkedValues" @change="handleCheckChange">
- <el-checkbox
- v-for="(item, index) in PXcheckList"
- :key="index"
- :label="item.val"
- >
- {{ item.val }}
- </el-checkbox>
- </el-checkbox-group>
- </div>
- <!-- 光标 -->
- <!-- <div v-if="BGshow" class="eigenvalue">
- <el-checkbox-group v-model="checkedGB" @change="handlecursor">
- <el-checkbox v-for="(item, index) in GBcheckList" :key="index" :label="item.val" :disabled="item.disabled">
- {{ item.val }}
- </el-checkbox>
- </el-checkbox-group>
- </div> -->
- </div>
- <div class="line-chart" ref="chart"></div>
- </div>
- </template>
- <script>
- import * as echarts from "echarts"; // 导入 echarts 库
- import axios from "axios";
- import Bdgb from "./envelopecharts/Bdgb";
- import Xdgb from "./envelopecharts/Xdgb";
- import Tjgb from "./envelopecharts/Tjgb";
- import cursorReferenceMixin from "./envelopecharts/cursorReferenceMixin";
- export default {
- name: "TimedomainCharts", // 组件名称
- mixins: [cursorReferenceMixin, Bdgb, Xdgb, Tjgb],
- props: {
- // 可以通过 props 接收外部传入的数据
- currentIndex: {
- type: Number,
- default: 0,
- },
- ids: {
- type: Array,
- default: () => [],
- },
- activeIndex: {
- type: Number,
- default: 0,
- },
- envelopeListTwo: {
- type: Object,
- default: () => ({}),
- },
- currentRow: {
- type: Object,
- default: () => ({}),
- },
- windCode: {
- type: String,
- default: "",
- },
- },
- data() {
- return {
- chartInstance: null,
- option: null,
- xiaoval: "",
- daval: "",
- envelopeList: {},
- TZshow: false,
- BGshow: false,
- PXshow: false,
- GBcheckList: [
- { val: "添加光标", checked: false, disabled: false },
- { val: "谐波光标", checked: false, disabled: false },
- { val: "边带光标", checked: false, disabled: false },
- { val: "移动峰值", checked: false, disabled: false },
- ],
- PXcheckList: [
- { val: "Fr", checked: false },
- { val: "BPFI", checked: false },
- { val: "BPFO", checked: false },
- { val: "BSF", checked: false },
- { val: "FTF", checked: false },
- { val: "3P", checked: false },
- ],
- Fr: [],
- BPFI: [],
- BPFO: [],
- BSF: [],
- FTF: [],
- B3P: [],
- checkedGB: [],
- checkedValues: [],
- // 添加光标
- cursorPoints: [], // 存储参考点数据
- };
- },
- watch: {
- // 移除 envelopeList 的监听
- envelopeListTwo: {
- handler(newValue) {
- this.updateChart(newValue.y, newValue.x); // 更新图表
- },
- deep: true, // 确保监听对象的深层次变化
- },
- },
- mounted() {
- this.initializeChart();
- this.$nextTick(() => {
- if (this.chartInstance) {
- this.chartInstance.getZr().on("dblclick", this.handleDoubleClick);
- }
- });
- },
- beforeDestroy() {
- if (this.chartInstance) {
- this.chartInstance.getZr().off("dblclick", this.handleDoubleClick);
- this.chartInstance
- .getZr()
- .off("mousemove", this.handleSidebandCursorMove);
- this.chartInstance.dispose();
- }
- },
- methods: {
- handlecursor() {
- // 特殊光标类型数组
- const specialCursors = ["添加光标", "移动峰值", "边带光标", "谐波光标"];
- // 检查是否有多个特殊光标被选中
- const selectedSpecials = specialCursors.filter((type) =>
- this.checkedGB.includes(type)
- );
- // 如果多于1个,则只保留第一个
- if (selectedSpecials.length > 1) {
- this.checkedGB = [
- ...this.checkedGB.filter((val) => !specialCursors.includes(val)),
- selectedSpecials[0], // 保留第一个选中的
- ];
- }
- // 其余逻辑保持不变...
- const isMoveChecked = this.checkedGB.includes("移动峰值");
- const isSidebandChecked = this.checkedGB.includes("边带光标");
- const isHarmonicChecked = this.checkedGB.includes("谐波光标");
- isMoveChecked ? this.handleMoveCursor() : this.removeCursor();
- isSidebandChecked
- ? this.enableSidebandCursor()
- : this.disableSidebandCursor();
- isHarmonicChecked
- ? this.enableHarmonicCursor()
- : this.disableHarmonicCursor();
- // 设置互斥disabled状态
- this.GBcheckList = this.GBcheckList.map((item) => ({
- ...item,
- disabled:
- specialCursors.includes(item.val) &&
- this.checkedGB.some(
- (val) => val !== item.val && specialCursors.includes(val)
- ),
- }));
- },
- // 。。。。。。。。。。。。。。。
- handleInput() {
- this.$emit("update:modelValue", {
- xiaoval: this.xiaoval,
- daval: this.daval,
- });
- },
- chaxun() {
- this.$emit("handleLoading", null, true, this.activeIndex);
- const params = {
- ids: this.ids,
- windCode: this.windCode,
- analysisType: "envelope",
- fmin: this.xiaoval,
- fmax: this.daval,
- };
- axios
- .post("/WJapi/analysis/envelope", params)
- .then((res) => {
- this.envelopeList = JSON.parse(res.data);
- const XrmsValue = this.envelopeList?.Xrms;
- this.$emit("updateXrms", XrmsValue);
- this.PXcheckList.forEach((item) => {
- if (item.checked) {
- switch (item.val) {
- case "Fr":
- this.Fr = this.envelopeList.fn_Gen;
- break;
- case "BPFI":
- this.BPFI = this.envelopeList.BPFI;
- break;
- case "BPFO":
- this.BPFO = this.envelopeList.BPFO;
- break;
- case "BSF":
- this.BSF = this.envelopeList.BSF;
- break;
- case "FTF":
- this.FTF = this.envelopeList.FTF;
- break;
- case "3P":
- this.B3P = Array.isArray(this.envelopeList.B3P)
- ? this.envelopeList.B3P
- : [{ Xaxis: this.envelopeList.B3P, val: "3P" }];
- break;
- default:
- break;
- }
- }
- });
- const defaultData =
- this.envelopeList.y || this.envelopeListTwo.y || [];
- const defaultLabels =
- this.envelopeList.x || this.envelopeListTwo.x || [];
- // 这里是数据采样,减少数据量
- const sampleData = defaultData.filter((_, index) => index % 50 === 0); // 每隔50个数据点采样一次
- const sampleLabels = defaultLabels.filter(
- (_, index) => index % 50 === 0
- ); // 同样对 X 数据进行采样
- // 直接调用 updateChart 方法
- this.updateChart(sampleData, sampleLabels);
- })
- .catch((error) => {
- console.error(error);
- })
- .finally(() => {
- this.$emit("handleLoading", this.currentRow, false, this.activeIndex);
- });
- },
- handleCheckChange() {
- this.PXcheckList.forEach((item) => {
- item.checked = this.checkedValues.includes(item.val);
- });
- // 构建新的特征频率数据
- const newFeatureLines = {
- Fr: this.checkedValues.includes("Fr") ? this.envelopeList.fn_Gen : [],
- BPFI: this.checkedValues.includes("BPFI") ? this.envelopeList.BPFI : [],
- BPFO: this.checkedValues.includes("BPFO") ? this.envelopeList.BPFO : [],
- BSF: this.checkedValues.includes("BSF") ? this.envelopeList.BSF : [],
- FTF: this.checkedValues.includes("FTF") ? this.envelopeList.FTF : [],
- B3P: this.checkedValues.includes("3P")
- ? Array.isArray(this.envelopeList.B3P)
- ? this.envelopeList.B3P
- : [{ Xaxis: this.envelopeList.B3P, val: "3P" }]
- : [],
- };
- // 仅更新 `series`,避免重新渲染整个 ECharts 组件
- if (this.chartInstance) {
- this.chartInstance.setOption(
- {
- series: this.generateSeries(newFeatureLines),
- },
- { replaceMerge: ["series"] }
- );
- }
- },
- generateSeries(featureLines) {
- const createMarkLine = (dataSource, color) => ({
- type: "line",
- markLine: {
- silent: false,
- lineStyle: { color, type: "dashed", width: 1 },
- symbol: ["arrow", "none"],
- label: {
- show: true,
- position: "end",
- formatter: ({ data }) => data.val,
- },
- emphasis: {
- lineStyle: { color: "#FF6A00", width: 2 },
- label: {
- show: true,
- formatter: ({ value }) => `特征值: ${value}`,
- color: "#000",
- },
- },
- data: dataSource.map(({ Xaxis, val }) => ({ xAxis: Xaxis, val })),
- },
- });
- const markLines = [
- { data: featureLines.Fr, color: "#A633FF" },
- { data: featureLines.BPFI, color: "#23357e" },
- { data: featureLines.BPFO, color: "#42a0ae" },
- { data: featureLines.BSF, color: "#008080" },
- { data: featureLines.FTF, color: "#af254f" },
- { data: featureLines.B3P, color: "#FFD700" },
- ].map(({ data, color }) => createMarkLine(data, color));
- return [
- {
- name: "数据系列",
- type: "line",
- data: this.envelopeList.x.map((x, i) => [x, this.envelopeList.y[i]]),
- symbol: "none",
- lineStyle: { color: "#162961", width: 1 },
- itemStyle: { color: "#162961", borderColor: "#fff", borderWidth: 1 },
- large: true,
- },
- ...markLines,
- ];
- },
- initializeChart() {
- // 获取图表容器
- const chartDom = this.$refs.chart;
- // 初始化图表实例
- this.chartInstance = echarts.init(chartDom);
- // 初始化时使用空数据
- const defaultData = [];
- const defaultLabels = [];
- this.updateChart(defaultData, defaultLabels);
- },
- updateChart(data, labels) {
- // 获取 x 数组中的最大值
- const maxX = Math.max(...labels);
- // 计算最大值的下一个 5 的倍数
- const maxAxisValue = Math.ceil(maxX / 5) * 5;
- // 生成从 0 到 maxAxisValue 的刻度数组,间隔为 5
- const ticks = [];
- for (let i = 0; i <= maxAxisValue; i += 5) {
- ticks.push(i);
- }
- const option = {
- title: {
- text: this.envelopeList.title || this.envelopeListTwo.title,
- left: "center",
- },
- toolbox: {
- feature: {
- dataZoom: { yAxisIndex: "none" },
- restore: {},
- saveAsImage: {},
- myCustomTool: {
- show: true,
- title: "上一条",
- icon: `image://${require("@/assets/analyse/08.png")}`,
- onclick: () => this.previousRow(),
- },
- myCustomTool2: {
- show: true,
- title: "下一条",
- icon: `image://${require("@/assets/analyse/09.png")}`,
- onclick: () => this.nextRow(),
- },
- // myCustomTool4: {
- // show: true,
- // title: "光标",
- // icon: `image://${require("@/assets/analyse/12.png")}`,
- // onclick: () => this.Show("2"),
- // },
- myCustomTool3: {
- show: true,
- title: "特征频率",
- icon: `image://${require("@/assets/analyse/13.png")}`,
- onclick: () => this.Show("3"),
- },
- },
- },
- dataZoom: [
- {
- type: "slider", // 使用滑动条
- start: 0, // 起始比例
- end: 10, // 结束比例
- },
- {
- type: "inside", // 鼠标滚轮缩放
- },
- ],
- xAxis: {
- type: "value", // 使用数值型 x 轴,确保每个 x 值都有展示
- name: this.envelopeList.xaxis || this.envelopeListTwo.xaxis, // 设置 X 轴标题
- nameLocation: "center", // 标题位置:可选 "start" | "center" | "end"
- nameTextStyle: {
- fontSize: 14,
- color: "#333", // 标题颜色
- padding: [10, 0, 0, 0], // 上、右、下、左的间距
- },
- axisLabel: {
- formatter: (value) => {
- // 格式化显示刻度为 5 的倍数
- return value;
- },
- },
- axisTick: {
- show: true, // 显示刻度线
- },
- axisLine: {
- show: true, // 显示轴线
- },
- data: ticks, // 设置刻度
- },
- yAxis: {
- type: "value",
- name: this.envelopeList.yaxis || this.envelopeListTwo.yaxis,
- },
- tooltip: {
- trigger: "axis",
- formatter: (params) => {
- // 获取原始的 x 数值和对应的 y 值
- const xValue = params[0].value[0]; // 获取原始的 x 数值
- const yValue = params[0].value[1]; // 获取对应的 y 数值
- return `X: ${xValue}<br/>Y: ${yValue}`; // 显示原始的 x 和 y 值
- },
- axisPointer: {
- type: "line", // 显示十字线
- },
- },
- series: [
- {
- name: "数据系列",
- type: "line", // 折线图
- data: labels.map((item, index) => [item, data[index]]), // 修改为 [x, y] 数组
- symbol: "none", // 数据点的样式
- symbolSize: 8, // 数据点的大小
- lineStyle: {
- color: "#162961",
- width: 1, // 线条宽度
- },
- itemStyle: {
- color: "#162961",
- borderColor: "#fff",
- borderWidth: 1,
- },
- },
- ],
- };
- // 使用更新的配置更新图表
- this.chartInstance.setOption(option);
- },
- previousRow() {
- this.$emit("update-previous-row", 3, this.activeIndex);
- },
- // 触发下一条
- nextRow() {
- this.$emit("update-next-row", 3, this.activeIndex);
- },
- Show(value) {
- const stateMap = {
- 1: { TZshow: true, BGshow: false, PXshow: false },
- 2: { TZshow: false, BGshow: true, PXshow: false },
- 3: { TZshow: false, BGshow: false, PXshow: true },
- };
- if (stateMap[value]) {
- this.TZshow = value === "1" ? !this.TZshow : false;
- this.BGshow = value === "2" ? !this.BGshow : false;
- this.PXshow = value === "3" ? !this.PXshow : false;
- }
- // this.TZshow = !this.TZshow;
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .line-chart {
- width: 100%;
- height: 260px;
- }
- .eigenvalue {
- position: absolute;
- top: 60px;
- right: 0;
- font-size: 10px;
- width: 100px;
- border: 1px solid black;
- padding: 5px;
- background: #fff;
- z-index: 99;
- h5 {
- line-height: 16px;
- height: 16px;
- }
- }
- .section {
- position: relative;
- display: flex;
- // line-height: 32px;
- .el-input {
- width: 150px;
- }
- .el-button {
- margin-left: 10px;
- }
- }
- </style>
|