kd-lane-chart-v3 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -342,7 +342,7 @@ const _sfc_main$e = {
342
342
  document.body.addEventListener("keyup", this.onEscKeyRelease);
343
343
  },
344
344
  beforeUnmount() {
345
- document.removeEventListener("keyup", this.onEscKeyRelease);
345
+ document.body.removeEventListener("keyup", this.onEscKeyRelease);
346
346
  }
347
347
  };
348
348
  const _hoisted_1$d = {
@@ -371,7 +371,7 @@ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
371
371
  ])
372
372
  ]);
373
373
  }
374
- const VueSimpleContextMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e], ["__scopeId", "data-v-5e769d89"]]);
374
+ const VueSimpleContextMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e], ["__scopeId", "data-v-25d746bb"]]);
375
375
  class CustomStrategy {
376
376
  constructor(strategy) {
377
377
  this.strategy = strategy;
@@ -2607,7 +2607,312 @@ const ACTION_TYPE = {
2607
2607
  UPSERT_LINE: "upsertLine",
2608
2608
  DELETE_LINE: "delLine"
2609
2609
  };
2610
+ const LOG_AXIS_MIN_POSITIVE = 0.1;
2611
+ const LOG_AXIS_BASE = 10;
2612
+ function isLogScaleFlag(val) {
2613
+ return val === true || val === "true" || val === 1 || val === "1";
2614
+ }
2615
+ function isLaneLogScale(lane) {
2616
+ return !!(lane && isLogScaleFlag(lane.isLogScale));
2617
+ }
2618
+ function isLogAxisLabelVisible(formCache) {
2619
+ if (!formCache) return true;
2620
+ return formCache.showLogAxis !== false && formCache.showLogAxis !== "false" && formCache.showLogAxis !== 0 && formCache.showLogAxis !== "0";
2621
+ }
2622
+ function normalizeLogRange(min, max) {
2623
+ let lo = Number(min);
2624
+ let hi = Number(max);
2625
+ if (!Number.isFinite(lo) || lo <= 0) lo = LOG_AXIS_MIN_POSITIVE;
2626
+ if (!Number.isFinite(hi) || hi <= 0) hi = lo * LOG_AXIS_BASE;
2627
+ if (hi <= lo) hi = lo * LOG_AXIS_BASE;
2628
+ return { min: lo, max: hi };
2629
+ }
2630
+ function toLogDisplayValue(raw, digits = 3) {
2631
+ const n = Number(raw);
2632
+ if (!Number.isFinite(n) || n <= 0) return null;
2633
+ const logv = Math.log10(n);
2634
+ if (!Number.isFinite(logv)) return null;
2635
+ return Number(logv.toFixed(digits));
2636
+ }
2637
+ function toLogPlotX(raw) {
2638
+ const n = Number(raw);
2639
+ if (!Number.isFinite(n) || n <= 0) return null;
2640
+ const logv = Math.log10(n);
2641
+ return Number.isFinite(logv) ? logv : null;
2642
+ }
2643
+ function toLaneDrawX(plotX, lane, xAx, digits = 3) {
2644
+ if (!isLaneLogScale(lane)) return plotX;
2645
+ const n = Number(plotX);
2646
+ if (!Number.isFinite(n)) return plotX;
2647
+ return Number(n.toFixed(digits));
2648
+ }
2649
+ function axisIndexOf$1(val) {
2650
+ const n = Array.isArray(val) ? val[0] : val;
2651
+ return Number(n ?? 0);
2652
+ }
2653
+ function findLogTrendSeries(chart, paramId) {
2654
+ try {
2655
+ const list = chart.getModel().getSeries() || [];
2656
+ for (let i = 0; i < list.length; i++) {
2657
+ const sm = list[i];
2658
+ const opt = sm && sm.option || {};
2659
+ const type = sm && sm.subType || (Array.isArray(opt.type) ? opt.type[0] : opt.type);
2660
+ if (type !== "line") continue;
2661
+ const name = Array.isArray(sm.name) ? sm.name[0] : sm.name;
2662
+ if (name === "helper" || name === "log-grid") continue;
2663
+ const pid = Array.isArray(opt.paramId) ? opt.paramId[0] : opt.paramId;
2664
+ if (String(pid) === String(paramId)) return opt;
2665
+ }
2666
+ } catch (e) {
2667
+ }
2668
+ return null;
2669
+ }
2670
+ function pixelToLogTrendData(chart, paramId, offsetX, offsetY, lane, lineRange, digits = 3) {
2671
+ if (!chart || !isLaneLogScale(lane)) return null;
2672
+ const series = findLogTrendSeries(chart, paramId);
2673
+ const xAxisIndex = series ? axisIndexOf$1(series.xAxisIndex) : 0;
2674
+ const yAxisIndex = series ? axisIndexOf$1(series.yAxisIndex) : 0;
2675
+ const plot = resolveLaneLogPlotRange(lane, lineRange);
2676
+ const extent = toLogAxisExtent(plot.min, plot.max);
2677
+ let x0;
2678
+ let x1;
2679
+ let depth;
2680
+ try {
2681
+ x0 = chart.convertToPixel({ xAxisIndex }, extent.min);
2682
+ x1 = chart.convertToPixel({ xAxisIndex }, extent.max);
2683
+ } catch (e) {
2684
+ return null;
2685
+ }
2686
+ try {
2687
+ depth = chart.convertFromPixel({ yAxisIndex }, offsetY);
2688
+ } catch (e) {
2689
+ depth = null;
2690
+ }
2691
+ if (!Number.isFinite(x0) || !Number.isFinite(x1) || x1 === x0) return null;
2692
+ if (!Number.isFinite(depth)) return null;
2693
+ const lg = extent.min + (offsetX - x0) / (x1 - x0) * (extent.max - extent.min);
2694
+ if (!Number.isFinite(lg)) return null;
2695
+ return {
2696
+ value: Number(lg.toFixed(digits)),
2697
+ depth,
2698
+ xAxisIndex,
2699
+ yAxisIndex
2700
+ };
2701
+ }
2702
+ function seriesLogXAtDepth(chart, paramId, depth, digits = 3) {
2703
+ const series = findLogTrendSeries(chart, paramId);
2704
+ if (!series || !series.data || !Number.isFinite(Number(depth))) return null;
2705
+ let best = null;
2706
+ series.data.forEach((pt) => {
2707
+ const x = Array.isArray(pt) ? Number(pt[0]) : Number(pt && pt.value && pt.value[0]);
2708
+ const y = Array.isArray(pt) ? Number(pt[1]) : Number(pt && pt.value && pt.value[1]);
2709
+ if (!Number.isFinite(x) || !Number.isFinite(y)) return;
2710
+ const dist = Math.abs(y - Number(depth));
2711
+ if (!best || dist < best.dist) best = { x, dist };
2712
+ });
2713
+ if (!best) return null;
2714
+ return Number(best.x.toFixed(digits));
2715
+ }
2716
+ function logTrendDataToPixel(chart, paramId, lg, depth) {
2717
+ if (!chart) return null;
2718
+ const series = findLogTrendSeries(chart, paramId);
2719
+ const xAxisIndex = series ? axisIndexOf$1(series.xAxisIndex) : 0;
2720
+ const yAxisIndex = series ? axisIndexOf$1(series.yAxisIndex) : 0;
2721
+ try {
2722
+ const px = chart.convertToPixel({ xAxisIndex, yAxisIndex }, [lg, depth]);
2723
+ if (px && Number.isFinite(px[0]) && Number.isFinite(px[1])) return px;
2724
+ } catch (e) {
2725
+ }
2726
+ try {
2727
+ const x = chart.convertToPixel({ xAxisIndex }, lg);
2728
+ const y = chart.convertToPixel({ yAxisIndex }, depth);
2729
+ if (Number.isFinite(x) && Number.isFinite(y)) return [x, y];
2730
+ } catch (e) {
2731
+ return null;
2732
+ }
2733
+ return null;
2734
+ }
2735
+ function toLogAxisExtent(min, max) {
2736
+ const range = normalizeLogRange(min, max);
2737
+ return {
2738
+ min: Math.log10(range.min),
2739
+ max: Math.log10(range.max)
2740
+ };
2741
+ }
2742
+ function mapSeriesDataXToLog(data) {
2743
+ return (data || []).map((item) => {
2744
+ if (Array.isArray(item)) {
2745
+ return [toLogPlotX(item[0]), item[1], item[2]];
2746
+ }
2747
+ if (item && Array.isArray(item.value)) {
2748
+ return {
2749
+ ...item,
2750
+ value: [toLogPlotX(item.value[0]), item.value[1]]
2751
+ };
2752
+ }
2753
+ return item;
2754
+ });
2755
+ }
2756
+ function formatLanePointValue(raw, isLog, digits = 3) {
2757
+ if (raw === null || raw === void 0 || raw === "") return null;
2758
+ return toLogDisplayValue(raw, digits);
2759
+ }
2760
+ function niceLogDecadeRange(min, max) {
2761
+ const range = normalizeLogRange(min, max);
2762
+ let niceMin = 10 ** Math.floor(Math.log10(range.min) + 1e-9);
2763
+ let niceMax = 10 ** Math.ceil(Math.log10(range.max) - 1e-9);
2764
+ if (!Number.isFinite(niceMin) || niceMin <= 0) niceMin = LOG_AXIS_MIN_POSITIVE;
2765
+ if (!Number.isFinite(niceMax) || niceMax <= niceMin) {
2766
+ niceMax = niceMin * LOG_AXIS_BASE;
2767
+ }
2768
+ return { min: niceMin, max: niceMax };
2769
+ }
2770
+ function resolveLaneLogPlotRange(lane, lineRange = {}) {
2771
+ let lo = Infinity;
2772
+ let hi = -Infinity;
2773
+ (lane && lane.lines || []).forEach((line) => {
2774
+ if (!line) return;
2775
+ const r = lineRange[line.lineId] || {};
2776
+ const cfgMin = Number(line.min);
2777
+ const cfgMax = Number(line.max);
2778
+ const useMin = Number.isFinite(cfgMin) && cfgMin > 0 ? cfgMin : Number(r.min);
2779
+ const useMax = Number.isFinite(cfgMax) && cfgMax > 0 ? cfgMax : Number(r.max);
2780
+ if (Number.isFinite(useMin) && useMin > 0) lo = Math.min(lo, useMin);
2781
+ if (Number.isFinite(useMax) && useMax > 0) hi = Math.max(hi, useMax);
2782
+ });
2783
+ return niceLogDecadeRange(
2784
+ Number.isFinite(lo) ? lo : LOG_AXIS_MIN_POSITIVE,
2785
+ Number.isFinite(hi) ? hi : LOG_AXIS_MIN_POSITIVE * LOG_AXIS_BASE
2786
+ );
2787
+ }
2788
+ function buildLogLaneTenLineValues(min, max) {
2789
+ const range = niceLogDecadeRange(min, max);
2790
+ const ratio = range.max / range.min;
2791
+ const values = [];
2792
+ for (let m = 1; m <= 10; m++) {
2793
+ values.push(range.min * ratio ** Math.log10(m));
2794
+ }
2795
+ return values;
2796
+ }
2797
+ function buildLogLaneTenLineLgValues(min, max) {
2798
+ return buildLogLaneTenLineValues(min, max).map((v) => Math.log10(v)).filter((v) => Number.isFinite(v));
2799
+ }
2800
+ function buildLogDecadeTickMarks(min, max) {
2801
+ const range = niceLogDecadeRange(min, max);
2802
+ const loExp = Math.round(Math.log10(range.min));
2803
+ const hiExp = Math.round(Math.log10(range.max));
2804
+ const marks = [];
2805
+ for (let e = loExp; e <= hiExp; e++) {
2806
+ const value = 10 ** e;
2807
+ marks.push({
2808
+ value,
2809
+ label: String(e),
2810
+ percent: logValueToPercent(value, range.min, range.max)
2811
+ });
2812
+ }
2813
+ return marks;
2814
+ }
2815
+ function logValueToPercent(value, min, max) {
2816
+ const range = normalizeLogRange(min, max);
2817
+ const v = Number(value);
2818
+ if (!Number.isFinite(v) || v <= 0) return 0;
2819
+ const clamped = Math.max(range.min, Math.min(range.max, v));
2820
+ const span = Math.log(range.max) - Math.log(range.min);
2821
+ if (span <= 0) return 0;
2822
+ return (Math.log(clamped) - Math.log(range.min)) / span * 100;
2823
+ }
2824
+ function buildLogXAxisOption({
2825
+ gridIndex = 0,
2826
+ min,
2827
+ max,
2828
+ showSplitLine = true,
2829
+ splitLineColor
2830
+ } = {}) {
2831
+ const range = niceLogDecadeRange(min, max);
2832
+ const extent = toLogAxisExtent(range.min, range.max);
2833
+ const lineStyle = {
2834
+ color: splitLineColor,
2835
+ type: "dashed",
2836
+ width: 1
2837
+ };
2838
+ return {
2839
+ gridIndex,
2840
+ show: true,
2841
+ type: "value",
2842
+ min: extent.min,
2843
+ max: extent.max,
2844
+ minorTick: { show: false },
2845
+ minorSplitLine: {
2846
+ show: false,
2847
+ lineStyle
2848
+ },
2849
+ splitLine: {
2850
+ show: showSplitLine,
2851
+ showMaxLine: false,
2852
+ showMinLine: false,
2853
+ lineStyle
2854
+ },
2855
+ axisLabel: { show: false },
2856
+ axisLine: { show: false },
2857
+ axisTick: { show: false }
2858
+ };
2859
+ }
2610
2860
  const _sfc_main$9 = {
2861
+ name: "LogAxisRuler",
2862
+ props: {
2863
+ min: {
2864
+ type: [Number, String],
2865
+ default: 0.1
2866
+ },
2867
+ max: {
2868
+ type: [Number, String],
2869
+ default: 100
2870
+ },
2871
+ visible: {
2872
+ type: Boolean,
2873
+ default: true
2874
+ },
2875
+ // top:曲线上方;bottom:表头底沿。8.22对数轴
2876
+ placement: {
2877
+ type: String,
2878
+ default: "top"
2879
+ }
2880
+ },
2881
+ computed: {
2882
+ // 刻度随量程重算,标 lg;边控关显示时整尺隐藏。8.24
2883
+ marks() {
2884
+ return buildLogDecadeTickMarks(this.min, this.max);
2885
+ }
2886
+ },
2887
+ methods: {
2888
+ // 两端刻度贴边,避免 translateX(-50%) 被裁掉。8.22对数轴
2889
+ tickStyle(mark) {
2890
+ if (mark.percent <= 2) {
2891
+ return { left: "2px", transform: "none" };
2892
+ }
2893
+ if (mark.percent >= 98) {
2894
+ return { left: "auto", right: "2px", transform: "none" };
2895
+ }
2896
+ return { left: mark.percent + "%" };
2897
+ }
2898
+ }
2899
+ };
2900
+ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
2901
+ return $props.visible && $options.marks.length ? (openBlock(), createElementBlock("div", {
2902
+ key: 0,
2903
+ class: normalizeClass(["kd-log-axis-ruler", { "kd-log-axis-ruler--top": $props.placement === "top" }])
2904
+ }, [
2905
+ (openBlock(true), createElementBlock(Fragment, null, renderList($options.marks, (mark) => {
2906
+ return openBlock(), createElementBlock("span", {
2907
+ key: String(mark.value),
2908
+ class: "kd-log-axis-ruler__tick",
2909
+ style: normalizeStyle($options.tickStyle(mark))
2910
+ }, toDisplayString(mark.label), 5);
2911
+ }), 128))
2912
+ ], 2)) : createCommentVNode("", true);
2913
+ }
2914
+ const LogAxisRuler = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9], ["__scopeId", "data-v-17ebb571"]]);
2915
+ const _sfc_main$8 = {
2611
2916
  name: "HeaderItem",
2612
2917
  props: {
2613
2918
  lineRange: {
@@ -2654,6 +2959,11 @@ const _sfc_main$9 = {
2654
2959
  headerData: {
2655
2960
  type: Object,
2656
2961
  default: () => ({})
2962
+ },
2963
+ // 泳道开了对数轴时,表头当前值出 lg。8.24
2964
+ isLogScale: {
2965
+ type: [Boolean, String, Number],
2966
+ default: false
2657
2967
  }
2658
2968
  },
2659
2969
  methods: {
@@ -2684,7 +2994,11 @@ const _sfc_main$9 = {
2684
2994
  let max = -Infinity;
2685
2995
  let min = Infinity;
2686
2996
  for (let i = 0; i < data.length; i++) {
2687
- const v = Number(data[i][key]);
2997
+ const raw = data[i][key];
2998
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") {
2999
+ continue;
3000
+ }
3001
+ const v = Number(raw);
2688
3002
  if (!Number.isFinite(v)) continue;
2689
3003
  if (v > max) max = v;
2690
3004
  if (v < min) min = v;
@@ -2692,7 +3006,7 @@ const _sfc_main$9 = {
2692
3006
  if (!Number.isFinite(max)) return false;
2693
3007
  return max > this.line.max || min < this.line.min;
2694
3008
  },
2695
- // 显示当前数据最新值
3009
+ // 显示当前数据最新值;对数道出 lg(x)。8.24
2696
3010
  getCurrentData() {
2697
3011
  if (this.formCache.displayType == "float") {
2698
3012
  return "";
@@ -2703,7 +3017,15 @@ const _sfc_main$9 = {
2703
3017
  )) {
2704
3018
  return "--";
2705
3019
  }
2706
- return this.headerData[this.line.paramId] !== null && this.headerData[this.line.paramId] !== void 0 && this.headerData[this.line.paramId] !== "" ? typeof +this.headerData[this.line.paramId] === "number" ? Number(Number(this.headerData[this.line.paramId]).toFixed(3)) : this.headerData[this.line.paramId] : "--";
3020
+ const raw = this.headerData[this.line.paramId];
3021
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") {
3022
+ return "--";
3023
+ }
3024
+ if (isLogScaleFlag(this.isLogScale)) {
3025
+ const lg = formatLanePointValue(raw);
3026
+ return lg == null ? "--" : lg;
3027
+ }
3028
+ return typeof +raw === "number" ? Number(Number(raw).toFixed(3)) : raw;
2707
3029
  },
2708
3030
  getParamName(line) {
2709
3031
  const nameConfig = this.paramsNameMap[line.paramId];
@@ -2792,7 +3114,7 @@ const _hoisted_1$8 = { class: "kd-lane-chart-container-text-container" };
2792
3114
  const _hoisted_2$7 = { class: "left" };
2793
3115
  const _hoisted_3$6 = { class: "center" };
2794
3116
  const _hoisted_4$6 = { class: "right" };
2795
- function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
3117
+ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
2796
3118
  return openBlock(), createElementBlock("div", {
2797
3119
  class: normalizeClass(["kd-lane-chart-container-header-item", { "kd-lane-chart-container-header-item_warning": $options.isShowWarning() }]),
2798
3120
  style: normalizeStyle($options.headerItemStyle),
@@ -2819,8 +3141,8 @@ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
2819
3141
  ])
2820
3142
  ], 6);
2821
3143
  }
2822
- const HeaderItem = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$9], ["__scopeId", "data-v-3a2fbd9e"]]);
2823
- const _sfc_main$8 = {
3144
+ const HeaderItem = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8], ["__scopeId", "data-v-c4185947"]]);
3145
+ const _sfc_main$7 = {
2824
3146
  name: "LegendItem",
2825
3147
  props: {
2826
3148
  lineRange: {
@@ -2867,6 +3189,11 @@ const _sfc_main$8 = {
2867
3189
  headerData: {
2868
3190
  type: Object,
2869
3191
  default: () => ({})
3192
+ },
3193
+ // 泳道开了对数轴时,表头当前值出 lg。8.24
3194
+ isLogScale: {
3195
+ type: [Boolean, String, Number],
3196
+ default: false
2870
3197
  }
2871
3198
  },
2872
3199
  methods: {
@@ -2884,7 +3211,13 @@ const _sfc_main$8 = {
2884
3211
  if (!Object.prototype.hasOwnProperty.call(this.headerData, paramId)) {
2885
3212
  return "--";
2886
3213
  }
2887
- return this.headerData[paramId] !== null && this.headerData[paramId] !== void 0 && this.headerData[paramId] !== "" ? typeof +this.headerData[paramId] === "number" ? Number(Number(this.headerData[paramId]).toFixed(3)) : this.headerData[paramId] : "--";
3214
+ const raw = this.headerData[paramId];
3215
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") return "--";
3216
+ if (isLogScaleFlag(this.isLogScale)) {
3217
+ const lg = formatLanePointValue(raw);
3218
+ return lg == null ? "--" : lg;
3219
+ }
3220
+ return typeof +raw === "number" ? Number(Number(raw).toFixed(3)) : raw;
2888
3221
  },
2889
3222
  toggleLegend(label) {
2890
3223
  const temp = { ...this.line };
@@ -2945,7 +3278,7 @@ const _hoisted_7$3 = {
2945
3278
  class: "legend-data"
2946
3279
  };
2947
3280
  const _hoisted_8$2 = { class: "scale-right" };
2948
- function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3281
+ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
2949
3282
  return openBlock(), createElementBlock("div", {
2950
3283
  class: "kd-lane-chart-container-legend-item",
2951
3284
  style: normalizeStyle($options.legendItemStyle)
@@ -2979,7 +3312,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
2979
3312
  ])
2980
3313
  ], 4);
2981
3314
  }
2982
- const LegendItem = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8], ["__scopeId", "data-v-9206b887"]]);
3315
+ const LegendItem = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7], ["__scopeId", "data-v-9fa6fff3"]]);
2983
3316
  const TREND_LINE_STYLE = {
2984
3317
  stroke: "#FF9800",
2985
3318
  lineWidth: 2,
@@ -3302,481 +3635,232 @@ function applyEchoMirrorMeta(seg, first, knots) {
3302
3635
  seg.lithType = "mudstone";
3303
3636
  seg.mirrorLithType = "sandstone";
3304
3637
  }
3305
- }
3306
- }
3307
- function mergeMainMirrorKnots(mainLines, mirrorLines) {
3308
- const mainKnots = linesToKnots(mainLines);
3309
- if (!mirrorLines || !mirrorLines.length) return mainKnots;
3310
- const mirrorKnots = linesToKnots(mirrorLines);
3311
- return mainKnots.map((k, idx) => {
3312
- const hit = mirrorKnots.find((m) => Math.abs(Number(m.depth) - Number(k.depth)) < 0.05) || mirrorKnots[idx];
3313
- if (!hit || !Number.isFinite(Number(hit.value))) return k;
3314
- const next = { ...k, mirrorValue: Number(hit.value) };
3315
- if (hit.plotValue != null && Number.isFinite(Number(hit.plotValue))) {
3316
- next.plotMirrorValue = Number(hit.plotValue);
3317
- }
3318
- return next;
3319
- });
3320
- }
3321
- function optionScalar(val) {
3322
- return Array.isArray(val) ? val[0] : val;
3323
- }
3324
- function seriesTypeName(series) {
3325
- return optionScalar(series && series.type);
3326
- }
3327
- function seriesParamId(series) {
3328
- return optionScalar(series && series.paramId);
3329
- }
3330
- function seriesDisplayName(series) {
3331
- return optionScalar(series && series.name);
3332
- }
3333
- function findSeriesForDepth(chart, paramId, depth) {
3334
- const option = chart.getOption() || {};
3335
- const series = option.series || [];
3336
- const yAxes = option.yAxis || [];
3337
- let fallback = null;
3338
- for (let i = 0; i < series.length; i++) {
3339
- const s = series[i];
3340
- if (!s || seriesTypeName(s) !== "line" || seriesDisplayName(s) === "helper") continue;
3341
- if (String(seriesParamId(s)) !== String(paramId)) continue;
3342
- const info = {
3343
- seriesIndex: i,
3344
- xAxisIndex: axisIndexOf$1(s.xAxisIndex),
3345
- yAxisIndex: axisIndexOf$1(s.yAxisIndex)
3346
- };
3347
- fallback = info;
3348
- const yAx = yAxes[info.yAxisIndex];
3349
- if (!yAx) continue;
3350
- const min = Math.min(Number(yAx.min), Number(yAx.max));
3351
- const max = Math.max(Number(yAx.min), Number(yAx.max));
3352
- if (Number.isFinite(depth) && depth >= min && depth <= max) return info;
3353
- }
3354
- return fallback || { seriesIndex: 0, xAxisIndex: 0, yAxisIndex: 0 };
3355
- }
3356
- function eventOffsetInChart(chart, evt) {
3357
- var _a, _b;
3358
- const zr = chart.getZr();
3359
- const rect = (_b = (_a = chart.getDom()) == null ? void 0 : _a.getBoundingClientRect) == null ? void 0 : _b.call(_a);
3360
- let offsetX = 0;
3361
- let offsetY = 0;
3362
- const native = (evt == null ? void 0 : evt.event) || evt;
3363
- if (rect && Number.isFinite(native == null ? void 0 : native.clientX) && Number.isFinite(native == null ? void 0 : native.clientY)) {
3364
- offsetX = native.clientX - rect.left;
3365
- offsetY = native.clientY - rect.top;
3366
- } else if (Number.isFinite(evt == null ? void 0 : evt.offsetX) && Number.isFinite(evt == null ? void 0 : evt.offsetY)) {
3367
- offsetX = evt.offsetX;
3368
- offsetY = evt.offsetY;
3369
- }
3370
- offsetX = Math.max(0, Math.min(offsetX, zr.getWidth()));
3371
- offsetY = Math.max(0, Math.min(offsetY, zr.getHeight()));
3372
- return { offsetX, offsetY };
3373
- }
3374
- function isPointerInAnyGrid(chart, offsetX, offsetY) {
3375
- const option = chart.getOption() || {};
3376
- const gridCount = option.grid && option.grid.length || 1;
3377
- for (let i = 0; i < gridCount; i++) {
3378
- try {
3379
- if (chart.containPixel({ gridIndex: i }, [offsetX, offsetY])) return true;
3380
- } catch (e) {
3381
- }
3382
- }
3383
- return false;
3384
- }
3385
- function axisIndexOf$1(val) {
3386
- const n = Array.isArray(val) ? val[0] : val;
3387
- return Number(n ?? 0);
3388
- }
3389
- function pixelToData(chart, paramId, offsetX, offsetY, loose = false) {
3390
- const option = chart.getOption() || {};
3391
- const gridCount = option.grid && option.grid.length || 1;
3392
- const matchParam = (s) => s && seriesTypeName(s) === "line" && seriesDisplayName(s) !== "helper" && String(seriesParamId(s)) === String(paramId);
3393
- for (let g = 0; g < gridCount; g++) {
3394
- try {
3395
- if (!loose && !chart.containPixel({ gridIndex: g }, [offsetX, offsetY])) continue;
3396
- const seriesList = (option.series || []).filter(matchParam);
3397
- const series = seriesList.find((s) => axisIndexOf$1(s.yAxisIndex) === g) || seriesList[0];
3398
- const finders = [];
3399
- if (series) {
3400
- finders.push({
3401
- xAxisIndex: axisIndexOf$1(series.xAxisIndex),
3402
- yAxisIndex: axisIndexOf$1(series.yAxisIndex)
3403
- });
3404
- const seriesIndex = (option.series || []).indexOf(series);
3405
- if (seriesIndex >= 0) finders.push({ seriesIndex });
3406
- }
3407
- finders.push({ gridIndex: g });
3408
- for (const finder of finders) {
3409
- try {
3410
- const val = chart.convertFromPixel(finder, [offsetX, offsetY]);
3411
- if (val && Number.isFinite(val[0]) && Number.isFinite(val[1])) {
3412
- return {
3413
- value: val[0],
3414
- depth: val[1],
3415
- xAxisIndex: finder.xAxisIndex ?? 0,
3416
- yAxisIndex: finder.yAxisIndex ?? g
3417
- };
3418
- }
3419
- } catch (e) {
3420
- }
3421
- if (finder.xAxisIndex == null && finder.yAxisIndex == null) continue;
3422
- try {
3423
- const x = chart.convertFromPixel({ xAxisIndex: finder.xAxisIndex ?? 0 }, offsetX);
3424
- const y = chart.convertFromPixel({ yAxisIndex: finder.yAxisIndex ?? g }, offsetY);
3425
- if (Number.isFinite(x) && Number.isFinite(y)) {
3426
- return {
3427
- value: x,
3428
- depth: y,
3429
- xAxisIndex: finder.xAxisIndex ?? 0,
3430
- yAxisIndex: finder.yAxisIndex ?? g
3431
- };
3432
- }
3433
- } catch (e) {
3434
- }
3435
- }
3436
- } catch (e) {
3437
- }
3438
- }
3439
- return null;
3440
- }
3441
- function dataToPixel(chart, paramId, value, depth) {
3442
- const finder = findSeriesForDepth(chart, paramId, depth);
3443
- const finders = [
3444
- { xAxisIndex: finder.xAxisIndex, yAxisIndex: finder.yAxisIndex },
3445
- { seriesIndex: finder.seriesIndex },
3446
- { gridIndex: finder.yAxisIndex ?? 0 }
3447
- ];
3448
- for (const f of finders) {
3449
- try {
3450
- const px = chart.convertToPixel(f, [value, depth]);
3451
- if (px && Number.isFinite(px[0]) && Number.isFinite(px[1])) return px;
3452
- } catch (e) {
3453
- }
3454
- }
3455
- return null;
3456
- }
3457
- function snapDepthToEdge(depth, depthMin, depthMax, tol) {
3458
- if (!Number.isFinite(depth)) return depth;
3459
- const lo = Number.isFinite(depthMin) && Number.isFinite(depthMax) ? Math.min(depthMin, depthMax) : depthMin;
3460
- const hi = Number.isFinite(depthMin) && Number.isFinite(depthMax) ? Math.max(depthMin, depthMax) : depthMax;
3461
- if (!Number.isFinite(lo) || !Number.isFinite(hi)) return depth;
3462
- let d = depth;
3463
- if (Math.abs(d - lo) <= tol) d = lo;
3464
- if (Math.abs(d - hi) <= tol) d = hi;
3465
- return Math.max(lo, Math.min(hi, d));
3466
- }
3467
- function getAxisRange(chart, paramId, depth) {
3468
- const option = chart.getOption() || {};
3469
- const finder = findSeriesForDepth(chart, paramId, depth);
3470
- const xAx = (option.xAxis || [])[finder.xAxisIndex] || {};
3471
- const yAx = (option.yAxis || [])[finder.yAxisIndex] || {};
3472
- const xMin = Number(xAx.min);
3473
- const xMax = Number(xAx.max);
3474
- const yMin = Number(yAx.min);
3475
- const yMax = Number(yAx.max);
3476
- return {
3477
- valueMin: Number.isFinite(xMin) ? xMin : 0,
3478
- valueMax: Number.isFinite(xMax) ? xMax : 100,
3479
- depthMin: Number.isFinite(yMin) ? Math.min(yMin, yMax) : 0,
3480
- depthMax: Number.isFinite(yMax) ? Math.max(yMin, yMax) : 100
3481
- };
3482
- }
3483
- const LOG_AXIS_MIN_POSITIVE = 0.1;
3484
- const LOG_AXIS_BASE = 10;
3485
- function isLogScaleFlag(val) {
3486
- return val === true || val === "true" || val === 1 || val === "1";
3487
- }
3488
- function isLaneLogScale(lane) {
3489
- return !!(lane && isLogScaleFlag(lane.isLogScale));
3490
- }
3491
- function isLogAxisLabelVisible(formCache) {
3492
- if (!formCache) return true;
3493
- return formCache.showLogAxis !== false && formCache.showLogAxis !== "false" && formCache.showLogAxis !== 0 && formCache.showLogAxis !== "0";
3494
- }
3495
- function normalizeLogRange(min, max) {
3496
- let lo = Number(min);
3497
- let hi = Number(max);
3498
- if (!Number.isFinite(lo) || lo <= 0) lo = LOG_AXIS_MIN_POSITIVE;
3499
- if (!Number.isFinite(hi) || hi <= 0) hi = lo * LOG_AXIS_BASE;
3500
- if (hi <= lo) hi = lo * LOG_AXIS_BASE;
3501
- return { min: lo, max: hi };
3638
+ }
3502
3639
  }
3503
- function toLogPlotX(raw) {
3504
- const n = Number(raw);
3505
- if (!Number.isFinite(n) || n <= 0) return null;
3506
- const logv = Math.log10(n);
3507
- return Number.isFinite(logv) ? logv : null;
3640
+ function mergeMainMirrorKnots(mainLines, mirrorLines) {
3641
+ const mainKnots = linesToKnots(mainLines);
3642
+ if (!mirrorLines || !mirrorLines.length) return mainKnots;
3643
+ const mirrorKnots = linesToKnots(mirrorLines);
3644
+ return mainKnots.map((k, idx) => {
3645
+ const hit = mirrorKnots.find((m) => Math.abs(Number(m.depth) - Number(k.depth)) < 0.05) || mirrorKnots[idx];
3646
+ if (!hit || !Number.isFinite(Number(hit.value))) return k;
3647
+ const next = { ...k, mirrorValue: Number(hit.value) };
3648
+ if (hit.plotValue != null && Number.isFinite(Number(hit.plotValue))) {
3649
+ next.plotMirrorValue = Number(hit.plotValue);
3650
+ }
3651
+ return next;
3652
+ });
3508
3653
  }
3509
- function toLaneDrawX(plotX, lane, xAx, digits = 3) {
3510
- if (!isLaneLogScale(lane)) return plotX;
3511
- const n = Number(plotX);
3512
- if (!Number.isFinite(n)) return plotX;
3513
- return Number(n.toFixed(digits));
3654
+ function optionScalar(val) {
3655
+ return Array.isArray(val) ? val[0] : val;
3514
3656
  }
3515
- function axisIndexOf(val) {
3516
- const n = Array.isArray(val) ? val[0] : val;
3517
- return Number(n ?? 0);
3657
+ function seriesTypeName(series) {
3658
+ return optionScalar(series && series.type);
3518
3659
  }
3519
- function findLogTrendSeries(chart, paramId) {
3520
- const option = chart.getOption() || {};
3521
- return (option.series || []).find((s) => {
3522
- if (!s || s.type !== "line") return false;
3523
- const name = Array.isArray(s.name) ? s.name[0] : s.name;
3524
- if (name === "helper" || name === "log-grid") return false;
3525
- return String(s.paramId) === String(paramId);
3526
- }) || null;
3660
+ function seriesParamId(series) {
3661
+ return optionScalar(series && series.paramId);
3527
3662
  }
3528
- function pixelToLogTrendData(chart, paramId, offsetX, offsetY, lane, lineRange, digits = 3) {
3529
- if (!chart || !isLaneLogScale(lane)) return null;
3530
- const series = findLogTrendSeries(chart, paramId);
3531
- const xAxisIndex = series ? axisIndexOf(series.xAxisIndex) : 0;
3532
- const yAxisIndex = series ? axisIndexOf(series.yAxisIndex) : 0;
3533
- const plot = resolveLaneLogPlotRange(lane, lineRange);
3534
- const extent = toLogAxisExtent(plot.min, plot.max);
3535
- let x0;
3536
- let x1;
3537
- let depth;
3663
+ function seriesDisplayName(series) {
3664
+ return optionScalar(series && series.name);
3665
+ }
3666
+ function chartModel(chart) {
3538
3667
  try {
3539
- x0 = chart.convertToPixel({ xAxisIndex }, extent.min);
3540
- x1 = chart.convertToPixel({ xAxisIndex }, extent.max);
3668
+ return chart && !chart.isDisposed() ? chart.getModel() : null;
3541
3669
  } catch (e) {
3542
3670
  return null;
3543
3671
  }
3544
- try {
3545
- depth = chart.convertFromPixel({ yAxisIndex }, offsetY);
3546
- } catch (e) {
3547
- depth = null;
3548
- }
3549
- if (!Number.isFinite(x0) || !Number.isFinite(x1) || x1 === x0) return null;
3550
- if (!Number.isFinite(depth)) return null;
3551
- const lg = extent.min + (offsetX - x0) / (x1 - x0) * (extent.max - extent.min);
3552
- if (!Number.isFinite(lg)) return null;
3553
- return {
3554
- value: Number(lg.toFixed(digits)),
3555
- depth,
3556
- xAxisIndex,
3557
- yAxisIndex
3558
- };
3559
- }
3560
- function seriesLogXAtDepth(chart, paramId, depth, digits = 3) {
3561
- const series = findLogTrendSeries(chart, paramId);
3562
- if (!series || !series.data || !Number.isFinite(Number(depth))) return null;
3563
- let best = null;
3564
- series.data.forEach((pt) => {
3565
- const x = Array.isArray(pt) ? Number(pt[0]) : Number(pt && pt.value && pt.value[0]);
3566
- const y = Array.isArray(pt) ? Number(pt[1]) : Number(pt && pt.value && pt.value[1]);
3567
- if (!Number.isFinite(x) || !Number.isFinite(y)) return;
3568
- const dist = Math.abs(y - Number(depth));
3569
- if (!best || dist < best.dist) best = { x, dist };
3570
- });
3571
- if (!best) return null;
3572
- return Number(best.x.toFixed(digits));
3573
3672
  }
3574
- function logTrendDataToPixel(chart, paramId, lg, depth) {
3575
- if (!chart) return null;
3576
- const series = findLogTrendSeries(chart, paramId);
3577
- const xAxisIndex = series ? axisIndexOf(series.xAxisIndex) : 0;
3578
- const yAxisIndex = series ? axisIndexOf(series.yAxisIndex) : 0;
3673
+ function modelGridCount(model) {
3674
+ if (!model) return 1;
3579
3675
  try {
3580
- const px = chart.convertToPixel({ xAxisIndex, yAxisIndex }, [lg, depth]);
3581
- if (px && Number.isFinite(px[0]) && Number.isFinite(px[1])) return px;
3676
+ const list = model.queryComponents({ mainType: "grid" });
3677
+ if (list && list.length) return list.length;
3582
3678
  } catch (e) {
3583
3679
  }
3680
+ return 1;
3681
+ }
3682
+ function modelAxisOption(model, mainType, index2) {
3683
+ if (!model) return {};
3584
3684
  try {
3585
- const x = chart.convertToPixel({ xAxisIndex }, lg);
3586
- const y = chart.convertToPixel({ yAxisIndex }, depth);
3587
- if (Number.isFinite(x) && Number.isFinite(y)) return [x, y];
3685
+ const comp = model.getComponent(mainType, index2);
3686
+ return comp && comp.option || {};
3588
3687
  } catch (e) {
3589
- return null;
3688
+ return {};
3590
3689
  }
3591
- return null;
3592
- }
3593
- function toLogAxisExtent(min, max) {
3594
- const range = normalizeLogRange(min, max);
3595
- return {
3596
- min: Math.log10(range.min),
3597
- max: Math.log10(range.max)
3598
- };
3599
3690
  }
3600
- function mapSeriesDataXToLog(data) {
3601
- return (data || []).map((item) => {
3602
- if (Array.isArray(item)) {
3603
- return [toLogPlotX(item[0]), item[1], item[2]];
3604
- }
3605
- if (item && Array.isArray(item.value)) {
3606
- return {
3607
- ...item,
3608
- value: [toLogPlotX(item.value[0]), item.value[1]]
3609
- };
3691
+ function listLineSeries(model) {
3692
+ if (!model) return [];
3693
+ try {
3694
+ const list = model.getSeries() || [];
3695
+ const out = [];
3696
+ for (let i = 0; i < list.length; i++) {
3697
+ const sm = list[i];
3698
+ const opt = sm && sm.option || {};
3699
+ const type = sm && sm.subType || seriesTypeName(opt);
3700
+ if (type !== "line") continue;
3701
+ const name = optionScalar(sm && sm.name) || seriesDisplayName(opt);
3702
+ if (name === "helper" || name === "log-grid") continue;
3703
+ out.push({
3704
+ seriesIndex: sm.seriesIndex,
3705
+ xAxisIndex: axisIndexOf(opt.xAxisIndex),
3706
+ yAxisIndex: axisIndexOf(opt.yAxisIndex),
3707
+ paramId: seriesParamId(opt),
3708
+ option: opt
3709
+ });
3610
3710
  }
3611
- return item;
3612
- });
3613
- }
3614
- function formatLogTick(value) {
3615
- const n = Number(value);
3616
- if (n === 0) return "0";
3617
- if (!Number.isFinite(n) || n <= 0) return "";
3618
- const exp = Math.log10(n);
3619
- if (Math.abs(exp - Math.round(exp)) < 1e-6 && (n >= 1e3 || n < 0.01)) {
3620
- return `1e${Math.round(exp)}`;
3621
- }
3622
- if (n >= 1) return String(Number(n.toPrecision(4)));
3623
- return String(Number(n.toPrecision(3)));
3624
- }
3625
- function niceLogDecadeRange(min, max) {
3626
- const range = normalizeLogRange(min, max);
3627
- let niceMin = 10 ** Math.floor(Math.log10(range.min) + 1e-9);
3628
- let niceMax = 10 ** Math.ceil(Math.log10(range.max) - 1e-9);
3629
- if (!Number.isFinite(niceMin) || niceMin <= 0) niceMin = LOG_AXIS_MIN_POSITIVE;
3630
- if (!Number.isFinite(niceMax) || niceMax <= niceMin) {
3631
- niceMax = niceMin * LOG_AXIS_BASE;
3711
+ return out;
3712
+ } catch (e) {
3713
+ return [];
3632
3714
  }
3633
- return { min: niceMin, max: niceMax };
3634
- }
3635
- function resolveLaneLogPlotRange(lane, lineRange = {}) {
3636
- let lo = Infinity;
3637
- let hi = -Infinity;
3638
- (lane && lane.lines || []).forEach((line) => {
3639
- if (!line) return;
3640
- const r = lineRange[line.lineId] || {};
3641
- const cfgMin = Number(line.min);
3642
- const cfgMax = Number(line.max);
3643
- const useMin = Number.isFinite(cfgMin) && cfgMin > 0 ? cfgMin : Number(r.min);
3644
- const useMax = Number.isFinite(cfgMax) && cfgMax > 0 ? cfgMax : Number(r.max);
3645
- if (Number.isFinite(useMin) && useMin > 0) lo = Math.min(lo, useMin);
3646
- if (Number.isFinite(useMax) && useMax > 0) hi = Math.max(hi, useMax);
3647
- });
3648
- return niceLogDecadeRange(
3649
- Number.isFinite(lo) ? lo : LOG_AXIS_MIN_POSITIVE,
3650
- Number.isFinite(hi) ? hi : LOG_AXIS_MIN_POSITIVE * LOG_AXIS_BASE
3651
- );
3652
3715
  }
3653
- function buildLogLaneTenLineValues(min, max) {
3654
- const range = niceLogDecadeRange(min, max);
3655
- const ratio = range.max / range.min;
3656
- const values = [];
3657
- for (let m = 1; m <= 10; m++) {
3658
- values.push(range.min * ratio ** Math.log10(m));
3716
+ function findSeriesForDepth(chart, paramId, depth) {
3717
+ const model = chartModel(chart);
3718
+ const series = listLineSeries(model);
3719
+ let fallback = null;
3720
+ for (let i = 0; i < series.length; i++) {
3721
+ const s = series[i];
3722
+ if (String(s.paramId) !== String(paramId)) continue;
3723
+ const info = {
3724
+ seriesIndex: s.seriesIndex,
3725
+ xAxisIndex: s.xAxisIndex,
3726
+ yAxisIndex: s.yAxisIndex
3727
+ };
3728
+ fallback = info;
3729
+ const yAx = modelAxisOption(model, "yAxis", info.yAxisIndex);
3730
+ const minN = Number(optionScalar(yAx.min));
3731
+ const maxN = Number(optionScalar(yAx.max));
3732
+ const min = Math.min(minN, maxN);
3733
+ const max = Math.max(minN, maxN);
3734
+ if (Number.isFinite(depth) && depth >= min && depth <= max) return info;
3659
3735
  }
3660
- return values;
3661
- }
3662
- function buildLogLaneTenLineLgValues(min, max) {
3663
- return buildLogLaneTenLineValues(min, max).map((v) => Math.log10(v)).filter((v) => Number.isFinite(v));
3736
+ return fallback || { seriesIndex: 0, xAxisIndex: 0, yAxisIndex: 0 };
3664
3737
  }
3665
- function buildLogDecadeTickMarks(min, max) {
3666
- const range = niceLogDecadeRange(min, max);
3667
- const loExp = Math.round(Math.log10(range.min));
3668
- const hiExp = Math.round(Math.log10(range.max));
3669
- const marks = [];
3670
- for (let e = loExp; e <= hiExp; e++) {
3671
- const value = 10 ** e;
3672
- marks.push({
3673
- value,
3674
- label: formatLogTick(value),
3675
- percent: logValueToPercent(value, range.min, range.max)
3676
- });
3738
+ function eventOffsetInChart(chart, evt) {
3739
+ var _a, _b;
3740
+ const zr = chart.getZr();
3741
+ const rect = (_b = (_a = chart.getDom()) == null ? void 0 : _a.getBoundingClientRect) == null ? void 0 : _b.call(_a);
3742
+ let offsetX = 0;
3743
+ let offsetY = 0;
3744
+ const native = (evt == null ? void 0 : evt.event) || evt;
3745
+ if (rect && Number.isFinite(native == null ? void 0 : native.clientX) && Number.isFinite(native == null ? void 0 : native.clientY)) {
3746
+ offsetX = native.clientX - rect.left;
3747
+ offsetY = native.clientY - rect.top;
3748
+ } else if (Number.isFinite(evt == null ? void 0 : evt.offsetX) && Number.isFinite(evt == null ? void 0 : evt.offsetY)) {
3749
+ offsetX = evt.offsetX;
3750
+ offsetY = evt.offsetY;
3677
3751
  }
3678
- return marks;
3679
- }
3680
- function logValueToPercent(value, min, max) {
3681
- const range = normalizeLogRange(min, max);
3682
- const v = Number(value);
3683
- if (!Number.isFinite(v) || v <= 0) return 0;
3684
- const clamped = Math.max(range.min, Math.min(range.max, v));
3685
- const span = Math.log(range.max) - Math.log(range.min);
3686
- if (span <= 0) return 0;
3687
- return (Math.log(clamped) - Math.log(range.min)) / span * 100;
3688
- }
3689
- function buildLogXAxisOption({
3690
- gridIndex = 0,
3691
- min,
3692
- max,
3693
- showSplitLine = true,
3694
- splitLineColor
3695
- } = {}) {
3696
- const range = niceLogDecadeRange(min, max);
3697
- const extent = toLogAxisExtent(range.min, range.max);
3698
- const lineStyle = {
3699
- color: splitLineColor,
3700
- type: "dashed",
3701
- width: 1
3702
- };
3703
- return {
3704
- gridIndex,
3705
- show: true,
3706
- type: "value",
3707
- min: extent.min,
3708
- max: extent.max,
3709
- minorTick: { show: false },
3710
- minorSplitLine: {
3711
- show: false,
3712
- lineStyle
3713
- },
3714
- splitLine: {
3715
- show: showSplitLine,
3716
- showMaxLine: false,
3717
- showMinLine: false,
3718
- lineStyle
3719
- },
3720
- axisLabel: { show: false },
3721
- axisLine: { show: false },
3722
- axisTick: { show: false }
3723
- };
3752
+ offsetX = Math.max(0, Math.min(offsetX, zr.getWidth()));
3753
+ offsetY = Math.max(0, Math.min(offsetY, zr.getHeight()));
3754
+ return { offsetX, offsetY };
3724
3755
  }
3725
- const _sfc_main$7 = {
3726
- name: "LogAxisRuler",
3727
- props: {
3728
- min: {
3729
- type: [Number, String],
3730
- default: 0.1
3731
- },
3732
- max: {
3733
- type: [Number, String],
3734
- default: 100
3735
- },
3736
- visible: {
3737
- type: Boolean,
3738
- default: true
3739
- },
3740
- // top:曲线上方;bottom:表头底沿。8.22对数轴
3741
- placement: {
3742
- type: String,
3743
- default: "top"
3744
- }
3745
- },
3746
- computed: {
3747
- // 刻度随量程重算,边控关显示时整尺隐藏。8.22对数轴
3748
- marks() {
3749
- return buildLogDecadeTickMarks(this.min, this.max);
3756
+ function isPointerInAnyGrid(chart, offsetX, offsetY) {
3757
+ const gridCount = modelGridCount(chartModel(chart));
3758
+ for (let i = 0; i < gridCount; i++) {
3759
+ try {
3760
+ if (chart.containPixel({ gridIndex: i }, [offsetX, offsetY])) return true;
3761
+ } catch (e) {
3750
3762
  }
3751
- },
3752
- methods: {
3753
- // 两端刻度贴边,避免 translateX(-50%) 被裁掉。8.22对数轴
3754
- tickStyle(mark) {
3755
- if (mark.percent <= 2) {
3756
- return { left: "2px", transform: "none" };
3763
+ }
3764
+ return false;
3765
+ }
3766
+ function axisIndexOf(val) {
3767
+ const n = Array.isArray(val) ? val[0] : val;
3768
+ return Number(n ?? 0);
3769
+ }
3770
+ function pixelToData(chart, paramId, offsetX, offsetY, loose = false) {
3771
+ const model = chartModel(chart);
3772
+ const gridCount = modelGridCount(model);
3773
+ const matched = listLineSeries(model).filter(
3774
+ (s) => String(s.paramId) === String(paramId)
3775
+ );
3776
+ for (let g = 0; g < gridCount; g++) {
3777
+ try {
3778
+ if (!loose && !chart.containPixel({ gridIndex: g }, [offsetX, offsetY])) continue;
3779
+ const series = matched.find((s) => s.yAxisIndex === g) || matched[0];
3780
+ const finders = [];
3781
+ if (series) {
3782
+ finders.push({
3783
+ xAxisIndex: series.xAxisIndex,
3784
+ yAxisIndex: series.yAxisIndex
3785
+ });
3786
+ if (series.seriesIndex >= 0) finders.push({ seriesIndex: series.seriesIndex });
3757
3787
  }
3758
- if (mark.percent >= 98) {
3759
- return { left: "auto", right: "2px", transform: "none" };
3788
+ finders.push({ gridIndex: g });
3789
+ for (const finder of finders) {
3790
+ try {
3791
+ const val = chart.convertFromPixel(finder, [offsetX, offsetY]);
3792
+ if (val && Number.isFinite(val[0]) && Number.isFinite(val[1])) {
3793
+ return {
3794
+ value: val[0],
3795
+ depth: val[1],
3796
+ xAxisIndex: finder.xAxisIndex ?? 0,
3797
+ yAxisIndex: finder.yAxisIndex ?? g
3798
+ };
3799
+ }
3800
+ } catch (e) {
3801
+ }
3802
+ if (finder.xAxisIndex == null && finder.yAxisIndex == null) continue;
3803
+ try {
3804
+ const x = chart.convertFromPixel({ xAxisIndex: finder.xAxisIndex ?? 0 }, offsetX);
3805
+ const y = chart.convertFromPixel({ yAxisIndex: finder.yAxisIndex ?? g }, offsetY);
3806
+ if (Number.isFinite(x) && Number.isFinite(y)) {
3807
+ return {
3808
+ value: x,
3809
+ depth: y,
3810
+ xAxisIndex: finder.xAxisIndex ?? 0,
3811
+ yAxisIndex: finder.yAxisIndex ?? g
3812
+ };
3813
+ }
3814
+ } catch (e) {
3815
+ }
3760
3816
  }
3761
- return { left: mark.percent + "%" };
3817
+ } catch (e) {
3762
3818
  }
3763
3819
  }
3764
- };
3765
- function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3766
- return $props.visible && $options.marks.length ? (openBlock(), createElementBlock("div", {
3767
- key: 0,
3768
- class: normalizeClass(["kd-log-axis-ruler", { "kd-log-axis-ruler--top": $props.placement === "top" }])
3769
- }, [
3770
- (openBlock(true), createElementBlock(Fragment, null, renderList($options.marks, (mark) => {
3771
- return openBlock(), createElementBlock("span", {
3772
- key: String(mark.value),
3773
- class: "kd-log-axis-ruler__tick",
3774
- style: normalizeStyle($options.tickStyle(mark))
3775
- }, toDisplayString(mark.label), 5);
3776
- }), 128))
3777
- ], 2)) : createCommentVNode("", true);
3820
+ return null;
3821
+ }
3822
+ function dataToPixel(chart, paramId, value, depth) {
3823
+ const finder = findSeriesForDepth(chart, paramId, depth);
3824
+ const finders = [
3825
+ { xAxisIndex: finder.xAxisIndex, yAxisIndex: finder.yAxisIndex },
3826
+ { seriesIndex: finder.seriesIndex },
3827
+ { gridIndex: finder.yAxisIndex ?? 0 }
3828
+ ];
3829
+ for (const f of finders) {
3830
+ try {
3831
+ const px = chart.convertToPixel(f, [value, depth]);
3832
+ if (px && Number.isFinite(px[0]) && Number.isFinite(px[1])) return px;
3833
+ } catch (e) {
3834
+ }
3835
+ }
3836
+ return null;
3837
+ }
3838
+ function snapDepthToEdge(depth, depthMin, depthMax, tol) {
3839
+ if (!Number.isFinite(depth)) return depth;
3840
+ const lo = Number.isFinite(depthMin) && Number.isFinite(depthMax) ? Math.min(depthMin, depthMax) : depthMin;
3841
+ const hi = Number.isFinite(depthMin) && Number.isFinite(depthMax) ? Math.max(depthMin, depthMax) : depthMax;
3842
+ if (!Number.isFinite(lo) || !Number.isFinite(hi)) return depth;
3843
+ let d = depth;
3844
+ if (Math.abs(d - lo) <= tol) d = lo;
3845
+ if (Math.abs(d - hi) <= tol) d = hi;
3846
+ return Math.max(lo, Math.min(hi, d));
3847
+ }
3848
+ function getAxisRange(chart, paramId, depth) {
3849
+ const model = chartModel(chart);
3850
+ const finder = findSeriesForDepth(chart, paramId, depth);
3851
+ const xAx = modelAxisOption(model, "xAxis", finder.xAxisIndex);
3852
+ const yAx = modelAxisOption(model, "yAxis", finder.yAxisIndex);
3853
+ const xMin = Number(optionScalar(xAx.min));
3854
+ const xMax = Number(optionScalar(xAx.max));
3855
+ const yMin = Number(optionScalar(yAx.min));
3856
+ const yMax = Number(optionScalar(yAx.max));
3857
+ return {
3858
+ valueMin: Number.isFinite(xMin) ? xMin : 0,
3859
+ valueMax: Number.isFinite(xMax) ? xMax : 100,
3860
+ depthMin: Number.isFinite(yMin) ? Math.min(yMin, yMax) : 0,
3861
+ depthMax: Number.isFinite(yMax) ? Math.max(yMin, yMax) : 100
3862
+ };
3778
3863
  }
3779
- const LogAxisRuler = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7], ["__scopeId", "data-v-d5ed1748"]]);
3780
3864
  class TrendLineManager {
3781
3865
  constructor(host) {
3782
3866
  this.host = host;
@@ -3791,15 +3875,27 @@ class TrendLineManager {
3791
3875
  this._zoomPending = false;
3792
3876
  this._zoomEndTimer = null;
3793
3877
  this._graphicIds = /* @__PURE__ */ Object.create(null);
3878
+ this._zrElCache = /* @__PURE__ */ new WeakMap();
3794
3879
  this._ignoreClickUntil = 0;
3795
3880
  }
3796
3881
  destroy() {
3797
3882
  this._clearClickTimer();
3798
3883
  this._endDrag();
3799
3884
  Array.from(this.binds.keys()).forEach((laneId) => this.unbindChart(laneId));
3800
- if (this._raf) cancelAnimationFrame(this._raf);
3801
- if (this._zoomRaf) cancelAnimationFrame(this._zoomRaf);
3802
- if (this._zoomEndTimer) clearTimeout(this._zoomEndTimer);
3885
+ if (this._raf) {
3886
+ cancelAnimationFrame(this._raf);
3887
+ this._raf = null;
3888
+ }
3889
+ if (this._zoomRaf) {
3890
+ cancelAnimationFrame(this._zoomRaf);
3891
+ this._zoomRaf = null;
3892
+ }
3893
+ if (this._zoomEndTimer) {
3894
+ clearTimeout(this._zoomEndTimer);
3895
+ this._zoomEndTimer = null;
3896
+ }
3897
+ this.store = /* @__PURE__ */ Object.create(null);
3898
+ this._graphicIds = /* @__PURE__ */ Object.create(null);
3803
3899
  }
3804
3900
  /** 从模板 line.trendSegments 回显;已有 store 的曲线不覆盖,避免编辑中被模板刷新冲掉。8.21 */
3805
3901
  hydrateFromTemplate(template) {
@@ -3897,10 +3993,13 @@ class TrendLineManager {
3897
3993
  zr.on("mousedown", onZrDown);
3898
3994
  zr.on("mousemove", onZrMove);
3899
3995
  zr.on("dblclick", onDblClick);
3900
- const onZoom = () => this.scheduleZoomRender();
3996
+ const onZoom = () => {
3997
+ if (this.host && typeof this.host.startChartZoom === "function") {
3998
+ this.host.startChartZoom();
3999
+ }
4000
+ this.scheduleZoomRender();
4001
+ };
3901
4002
  if (typeof chart.on === "function") chart.on("datazoom", onZoom);
3902
- chart.getZr().on("mousewheel", onZoom);
3903
- if (dom) dom.addEventListener("wheel", onZoom, { passive: true });
3904
4003
  this.binds.set(laneId, { chart, onMouseDown, onZrDown, onZrMove, onDblClick, onZoom, dom });
3905
4004
  this.updateCursor(laneId);
3906
4005
  }
@@ -3949,9 +4048,18 @@ class TrendLineManager {
3949
4048
  this.renderAll();
3950
4049
  });
3951
4050
  }
4051
+ // 没有控制点就不跟缩放重画,省一轮 graphic。8.25
4052
+ hasAnyKnots() {
4053
+ const store = this.store;
4054
+ for (const key in store) {
4055
+ const segs = store[key] && store[key].segments;
4056
+ if (segs && segs.some((s) => s.knots && s.knots.length)) return true;
4057
+ }
4058
+ return false;
4059
+ }
3952
4060
  /** 缩放过程用 ZR 就地改像素,结束后再整层重画,避免 replaceMerge 把线冲掉。8.22 */
3953
4061
  scheduleZoomRender() {
3954
- if (this.dragSession) return;
4062
+ if (this.dragSession || !this.hasAnyKnots()) return;
3955
4063
  this._zoomPending = true;
3956
4064
  if (this._zoomEndTimer) clearTimeout(this._zoomEndTimer);
3957
4065
  this._zoomEndTimer = setTimeout(() => {
@@ -4045,18 +4153,35 @@ class TrendLineManager {
4045
4153
  });
4046
4154
  return patches;
4047
4155
  }
4048
- _findGraphicZrEl(chart, id) {
4049
- let found = null;
4156
+ _invalidateZrElCache(chart) {
4157
+ if (chart && this._zrElCache) this._zrElCache.delete(chart);
4158
+ }
4159
+ _indexGraphicZrEls(chart, map) {
4050
4160
  const zr = chart.getZr();
4051
- if (!zr || !zr.storage || typeof zr.storage.traverse !== "function") return null;
4161
+ if (!zr || !zr.storage || typeof zr.storage.traverse !== "function") return;
4052
4162
  zr.storage.traverse((el) => {
4053
- if (found) return;
4054
4163
  const elId = el.id ?? el.anid ?? el.name ?? el.__ecGraphicId;
4055
- if (elId === id || String(elId) === String(id) || String(elId).endsWith(id)) {
4056
- found = el;
4057
- }
4164
+ if (elId == null) return;
4165
+ map.set(String(elId), el);
4058
4166
  });
4059
- return found;
4167
+ }
4168
+ _findGraphicZrEl(chart, id) {
4169
+ if (!chart || id == null) return null;
4170
+ let map = this._zrElCache.get(chart);
4171
+ if (!map) {
4172
+ map = /* @__PURE__ */ new Map();
4173
+ this._zrElCache.set(chart, map);
4174
+ this._indexGraphicZrEls(chart, map);
4175
+ }
4176
+ const key = String(id);
4177
+ if (map.has(key)) return map.get(key);
4178
+ map.clear();
4179
+ this._indexGraphicZrEls(chart, map);
4180
+ if (map.has(key)) return map.get(key);
4181
+ for (const [elId, el] of map) {
4182
+ if (elId.endsWith(key)) return el;
4183
+ }
4184
+ return null;
4060
4185
  }
4061
4186
  _graphicPixel(el) {
4062
4187
  const cx = el.shape && el.shape.cx || 0;
@@ -4163,14 +4288,14 @@ class TrendLineManager {
4163
4288
  el.setShape(shape);
4164
4289
  applied += 1;
4165
4290
  });
4166
- if (applied > 0 && chart.getZr() && typeof chart.getZr().refreshImmediately === "function") {
4167
- chart.getZr().refreshImmediately();
4168
- }
4291
+ const zr = chart.getZr && chart.getZr();
4292
+ if (applied > 0 && zr && typeof zr.refresh === "function") zr.refresh();
4169
4293
  return applied > 0;
4170
4294
  }
4171
4295
  // 只 merge 新图形,不动已有线。8.24
4172
4296
  _addGraphicElements(chart, elements) {
4173
4297
  if (!elements.length) return;
4298
+ this._invalidateZrElCache(chart);
4174
4299
  chart.setOption(
4175
4300
  {
4176
4301
  graphic: elements.map((el) => ({ ...el, $action: "merge" }))
@@ -4181,6 +4306,7 @@ class TrendLineManager {
4181
4306
  // 按 id 删除,不 replaceMerge 整层 graphic。8.24
4182
4307
  _removeGraphicIds(chart, ids) {
4183
4308
  if (!ids.length) return;
4309
+ this._invalidateZrElCache(chart);
4184
4310
  chart.setOption(
4185
4311
  {
4186
4312
  graphic: ids.map((id) => ({ id, $action: "remove" }))
@@ -4382,6 +4508,9 @@ class TrendLineManager {
4382
4508
  /** 指针靠近控制点时先停地应力平移,按下时才来得及拖点。8.22 */
4383
4509
  onZrHover(e, laneId) {
4384
4510
  if (this.dragSession) return;
4511
+ if (this.host && typeof this.host.isChartBusy === "function" && this.host.isChartBusy()) {
4512
+ return;
4513
+ }
4385
4514
  const chart = this.getChart(laneId);
4386
4515
  const target = this.getTargetByLane(laneId);
4387
4516
  if (!chart || !target || !target.editable) {
@@ -5133,12 +5262,16 @@ const _sfc_main$6 = {
5133
5262
  }
5134
5263
  if (this.resizeObserver) {
5135
5264
  this.resizeObserver.disconnect();
5265
+ this.resizeObserver = null;
5136
5266
  }
5137
5267
  if (this.resizeObserverContainer) {
5138
5268
  this.resizeObserverContainer.disconnect();
5269
+ this.resizeObserverContainer = null;
5139
5270
  }
5140
5271
  },
5141
5272
  methods: {
5273
+ isLaneLogScale,
5274
+ // 模板里判断对数道。8.24
5142
5275
  initStrategy() {
5143
5276
  if (!this.config || !this.config.caseId) {
5144
5277
  return;
@@ -5183,6 +5316,10 @@ const _sfc_main$6 = {
5183
5316
  });
5184
5317
  },
5185
5318
  setupResizeObserver() {
5319
+ if (this.resizeObserver) {
5320
+ this.resizeObserver.disconnect();
5321
+ this.resizeObserver = null;
5322
+ }
5186
5323
  const container = this.$refs.targetDom;
5187
5324
  if (container) {
5188
5325
  this.resizeObserver = new ResizeObserver(() => {
@@ -6324,16 +6461,18 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
6324
6461
  line,
6325
6462
  paramsNameMap: $options.paramsNameMap
6326
6463
  }, { ref_for: true }, _ctx.$props, {
6464
+ "is-log-scale": $options.isLaneLogScale(lane),
6327
6465
  onContextmenu: withModifiers(($event) => $options.showContextMenu($event, line), ["prevent"]),
6328
6466
  onUpdateLine: $options.upsertLine
6329
- }), null, 16, ["line", "paramsNameMap", "onContextmenu", "onUpdateLine"])) : (openBlock(), createBlock(_component_LegendItem, mergeProps({
6467
+ }), null, 16, ["line", "paramsNameMap", "is-log-scale", "onContextmenu", "onUpdateLine"])) : (openBlock(), createBlock(_component_LegendItem, mergeProps({
6330
6468
  key: 1,
6331
6469
  line,
6332
6470
  paramsNameMap: $options.paramsNameMap
6333
6471
  }, { ref_for: true }, _ctx.$props, {
6472
+ "is-log-scale": $options.isLaneLogScale(lane),
6334
6473
  onContextmenu: withModifiers(($event) => $options.showContextMenu($event, line), ["prevent"]),
6335
6474
  onUpdateLine: $options.upsertLine
6336
- }), null, 16, ["line", "paramsNameMap", "onContextmenu", "onUpdateLine"]))
6475
+ }), null, 16, ["line", "paramsNameMap", "is-log-scale", "onContextmenu", "onUpdateLine"]))
6337
6476
  ], 2);
6338
6477
  }), 128))
6339
6478
  ]),
@@ -6440,16 +6579,18 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
6440
6579
  line,
6441
6580
  paramsNameMap: $options.paramsNameMap
6442
6581
  }, { ref_for: true }, _ctx.$props, {
6582
+ "is-log-scale": $options.isLaneLogScale(lane),
6443
6583
  onContextmenu: withModifiers(($event) => $options.showContextMenu($event, line), ["prevent"]),
6444
6584
  onUpdateLine: $options.upsertLine
6445
- }), null, 16, ["line", "paramsNameMap", "onContextmenu", "onUpdateLine"])) : (openBlock(), createBlock(_component_LegendItem, mergeProps({
6585
+ }), null, 16, ["line", "paramsNameMap", "is-log-scale", "onContextmenu", "onUpdateLine"])) : (openBlock(), createBlock(_component_LegendItem, mergeProps({
6446
6586
  key: 1,
6447
6587
  line,
6448
6588
  paramsNameMap: $options.paramsNameMap
6449
6589
  }, { ref_for: true }, _ctx.$props, {
6590
+ "is-log-scale": $options.isLaneLogScale(lane),
6450
6591
  onContextmenu: withModifiers(($event) => $options.showContextMenu($event, line), ["prevent"]),
6451
6592
  onUpdateLine: $options.upsertLine
6452
- }), null, 16, ["line", "paramsNameMap", "onContextmenu", "onUpdateLine"]))
6593
+ }), null, 16, ["line", "paramsNameMap", "is-log-scale", "onContextmenu", "onUpdateLine"]))
6453
6594
  ], 2);
6454
6595
  }), 128))
6455
6596
  ]),
@@ -6550,7 +6691,7 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
6550
6691
  }, 8, ["modelValue", "onClose"])
6551
6692
  ], 544);
6552
6693
  }
6553
- const KdLaneContainerComponent = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6], ["__scopeId", "data-v-afde8956"]]);
6694
+ const KdLaneContainerComponent = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6], ["__scopeId", "data-v-9d96e270"]]);
6554
6695
  const SLIDER_GROUP_ID = "depthSliderGroup";
6555
6696
  function pad2(n) {
6556
6697
  return n < 10 ? "0" + n : "" + n;
@@ -6683,10 +6824,12 @@ const _sfc_main$5 = {
6683
6824
  yName: curveConfig.yName,
6684
6825
  xCode,
6685
6826
  yCode,
6686
- data: this.cachedCurveData.map((item) => ({
6687
- time: item[xCode] || item.timestamp,
6688
- value: item[yCode] || 0
6689
- }))
6827
+ data: markRaw(
6828
+ this.cachedCurveData.map((item) => ({
6829
+ time: item[xCode] || item.timestamp,
6830
+ value: item[yCode] || 0
6831
+ }))
6832
+ )
6690
6833
  };
6691
6834
  })
6692
6835
  };
@@ -6732,24 +6875,28 @@ const _sfc_main$5 = {
6732
6875
  await this.$nextTick();
6733
6876
  if (newVal.type === "replace") {
6734
6877
  this.cachedCurveData = [];
6735
- let processedData = newVal && newVal.data ? Array.isArray(newVal.data) ? [...newVal.data] : [newVal.data] : [];
6878
+ let processedData = newVal && newVal.data ? Array.isArray(newVal.data) ? newVal.data : [newVal.data] : [];
6736
6879
  if (this.formCache.axisType == "time") {
6737
6880
  const axisKey = ((_c = (_b = (_a = this.getCurrentModeConfig()) == null ? void 0 : _a.datas) == null ? void 0 : _b[0]) == null ? void 0 : _c.xCode) || "timestamp";
6738
- processedData = processedData.map((item) => ({
6739
- ...item,
6740
- [axisKey]: this.toMillisecondTimestamp(item[axisKey] || item.timestamp)
6741
- }));
6742
- this.cachedCurveData = processedData;
6881
+ const firstT = processedData[0] && processedData[0][axisKey];
6882
+ if (!(typeof firstT === "number" && firstT > 1e11)) {
6883
+ processedData = processedData.map((item) => ({
6884
+ ...item,
6885
+ [axisKey]: this.toMillisecondTimestamp(item[axisKey] || item.timestamp)
6886
+ }));
6887
+ }
6888
+ this.cachedCurveData = markRaw(processedData);
6743
6889
  } else {
6744
6890
  const axisKey = ((_f = (_e = (_d = this.getCurrentModeConfig()) == null ? void 0 : _d.datas) == null ? void 0 : _e[0]) == null ? void 0 : _f.xCode) || "depth";
6745
- if (processedData[0] && processedData[0].timestamp) {
6891
+ const firstTs = processedData[0] && processedData[0].timestamp;
6892
+ if (firstTs && !(typeof firstTs === "number" && firstTs > 1e11)) {
6746
6893
  processedData = processedData.map((item) => ({
6747
6894
  ...item,
6748
6895
  timestamp: this.toMillisecondTimestamp(item.timestamp)
6749
6896
  }));
6750
- this.cachedCurveData = this.deduplicateByUniqueKey(this.cachedCurveData, processedData, "timestamp");
6897
+ this.cachedCurveData = markRaw(this.deduplicateByUniqueKey([], processedData, "timestamp"));
6751
6898
  } else {
6752
- this.cachedCurveData = this.deduplicateByUniqueKey(this.cachedCurveData, processedData, axisKey);
6899
+ this.cachedCurveData = markRaw(this.deduplicateByUniqueKey([], processedData, axisKey));
6753
6900
  }
6754
6901
  }
6755
6902
  if (this.cachedCurveData.length > 0) {
@@ -6804,11 +6951,11 @@ const _sfc_main$5 = {
6804
6951
  ...item,
6805
6952
  [axisKey]: this.toMillisecondTimestamp(item[axisKey] || item.timestamp)
6806
6953
  }));
6807
- this.cachedCurveData = this.deduplicateByUniqueKey(
6954
+ this.cachedCurveData = markRaw(this.deduplicateByUniqueKey(
6808
6955
  this.cachedCurveData,
6809
6956
  data,
6810
6957
  axisKey
6811
- );
6958
+ ));
6812
6959
  } else {
6813
6960
  data = data.map((item) => ({
6814
6961
  ...item,
@@ -6816,9 +6963,9 @@ const _sfc_main$5 = {
6816
6963
  }));
6817
6964
  if (direction === "top") {
6818
6965
  const tempData = [...data, ...this.cachedCurveData];
6819
- this.cachedCurveData = this.deduplicateByUniqueKey([], tempData, "timestamp");
6966
+ this.cachedCurveData = markRaw(this.deduplicateByUniqueKey([], tempData, "timestamp"));
6820
6967
  } else {
6821
- this.cachedCurveData = this.deduplicateByUniqueKey(this.cachedCurveData, data, "timestamp");
6968
+ this.cachedCurveData = markRaw(this.deduplicateByUniqueKey(this.cachedCurveData, data, "timestamp"));
6822
6969
  }
6823
6970
  }
6824
6971
  if (this.cachedCurveData.length > 0) {
@@ -6829,8 +6976,7 @@ const _sfc_main$5 = {
6829
6976
  this.renderChart();
6830
6977
  }
6831
6978
  },
6832
- immediate: true,
6833
- deep: true
6979
+ immediate: true
6834
6980
  },
6835
6981
  depthTimeChartData: {
6836
6982
  deep: true,
@@ -7406,8 +7552,14 @@ const _sfc_main$5 = {
7406
7552
  ensureVisible() {
7407
7553
  const rows = this.resolvedRows;
7408
7554
  if (!rows.length) return;
7409
- const option = this.chart.getOption();
7410
- const dz = option.dataZoom && option.dataZoom[0] ? option.dataZoom[0] : null;
7555
+ const dz = (() => {
7556
+ try {
7557
+ const m = this.chart.getModel().getComponent("dataZoom", 0);
7558
+ return m && m.option;
7559
+ } catch (e) {
7560
+ return null;
7561
+ }
7562
+ })();
7411
7563
  if (!dz) return;
7412
7564
  const total = rows.length;
7413
7565
  const start = dz.start ?? 0;
@@ -7863,7 +8015,7 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
7863
8015
  ], 512)
7864
8016
  ], 512);
7865
8017
  }
7866
- const DepthTimeChart = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5], ["__scopeId", "data-v-75a3a4e4"]]);
8018
+ const DepthTimeChart = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5], ["__scopeId", "data-v-300010d5"]]);
7867
8019
  const curveExportIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAH+ElEQVRo3u1ZTWxU1xX+zpuxsRvbWLEBx6mFIcEOTWkChYZ00abdgNRKDVJRi1pVTvHYRCy6qsKilbLMoot0YRV7jGRVipSGLpAapV1UqRsSKKi0iAK1cRxIY4gJGNvEP2PPvPN1ce/7sz1vxsbTRJWvNPZ77/68c+4595zvOw9Ya2ttrZWySb6Ow4ePbpaE2/aZC0hOpNPdv17uvGS+DsfR5rqqzMtfb/mYpAhA8yKxF7aREO8ZCTF7RX/fRBjqQ2SNxXNNn3c9M5/E21eabgBYPcUAoK5qFt95+jogQtDal4SRx5ee9o+AntD0nYGEGHXJhc5CowhsV9AvQpC4+2mlvH2laUWWjlWMANSTmOaBEZlUK7kg2OHoXEb6fQUFBAGSYq2DxR7gr8iVunCsYkYAaye1LwRACAhS4Pullc9orhRxHNBIbcaSIg5A164jECrtYuKpJyICKmnfvWK9irCY0riL3T2NKMjIOSMhAoE4pGpo9wEhCQ25oQZC0z++YubZGzyAXvGKCUAIoSoiDmi2WBjspBFbBFS1ziNKqj1DDDbIuiTsCkHgEIAKEQdUNxxMCFVKaVwRANUeL5ciDhjdxpBrGnPRWNQ7jcG9hiOm9QCliJhdspthn3kvkRKdseFPauWl158rKu8t6JcC+VIKrCkPmv/yKjY09O/3WlpaajNZ5zNGELoGo9ba/yUI/umLL7YmcjwWfpZOH38hfJ9Kdb4EyBOlFZF30+nun69a8Ejk0LChZrrtW9s/IAC8cX6HAHghmsBl/7e/9ME366umJQyOF4LbhdfhZx7OFCwG19Nz5XjrUusNAKunGABUV8xh1+ZbAoBvnN+x5Jhtm+5i64Z7DGN6WpgoQpICkbAOhox4ORsWUNODVhQLsYTjMxV461JrCSCVwWtLgtxQAhdVH9xa+BieY4BK1Eq0KnkYw6rovdWCZH2ASF8QeQRIYmnlPPRrhQ8PIumxnRC8ChRkwFYkglKi1i2RYkY+iQs/1JB5VMUHyZ4itKiSFB+EGQWFHswKzl/g1D7+XH3FyIUccJFFGcBHQwS4RJAgNFjHWMbCegkzJMv9PABaStoiZIHlrQ+64egHgGqCwOLzFXiwUKChMkLWdcR1HSQcMplwA0dfddpCD5XnN5kSomavSZp7n9AwoD9hET2eNj5Tiau3GjB0e4OM3q/B9FxZBkBGRJLliVzVww/NSKkshkIGM/Q44q5+RCTF5yXhNjb1EN659rhcGmmcUMrrFL5Z5jgXe9PHb3pjfnL0aN38ZNmXKdxdIleMj04MOcyCSlNkW7y+M8Nb0T/QMpF1E686jr7am+6eXGrd33Z1jQH4q/2VgGiSsfRIlUIb1gih2IDil99sMHA1wVMXn5IrNxv/lkzg+729gXVK0QoVc2iSL2Njh7oe7aWJjH6yDpz09xd2yuDtTX/KZTMHetN9mVKD4AIskiAIt0A+IUgloWpU8YpMqhAl8d77j8ngaEN/bn7uQF9fvFKp1JF97e3tXyypYgzXcWNs5inkxX5V+qWM0cn1OH2tZYKaaCuklF3vCXGSp9vajjSX1mLWEnGQiwz/N9DBuz89tA05dV4+caLrw2KFmqr6tDmxjmc7Oo4+UxqLGYELWiyIgLQuSAHIjydrZPCTR25ns3PdyxFqvO4eLu260JBz5vtTqSP7SmAxPwnHAw/rjuFzpgQGRhsJoK84F1yQ6+ru4p+7/l6RTWZPtbd3fm/VFVMvGsQgD4aCBmwgoUKG72wUunhzpe40UTuGc197tyLzhdlThq2vLh+DUiQuz6lf3wzm5Sgcm65xh4cHzoXHt3d2/oB0KmJeujec/GcqZ3D+6bPYfXHvK4dTnVUn0t2/XKUEHU64+YZ4Xy58CoL7MxXiqtzo7+/PRU2M4xOb79Sqox6nBD2GQJNe7tdO2gK6gFDMVszg7M53sPPqnl+0d3Q25+bnUoXcu2DtXjWe8all0I6lJ/ZzEefcpIhwaqk5/9l9HdlkDlQXqgpVQlXB0DXU5wAAFPPl8zj35BnsvvrMjzdNbKxva2uLzYlOIawY4ckxA1UhrkIIv5aQf45IiDlLLA71xxNQx8X57WfwUd3I/rKydX88ePBg1YrRvRYB7tX7lmvLMyBQWZYBIQ3xErOIwmDkAykq5yuxfmY9ALx78uTJqZVFRQJUQ8pixzBA+V6doyKZkcrkXMOhQx31+TVbSPVkiSHBs6rZajx7+Ruonqk+li4QRAqVBiK0JF9UND+/NEjAgOKGmnHJZBv2AXgtPGfHH3bmtxWBm00f4f1tgxEF6ybqsevynkwyW9aW7u3+3QNixUDwuDzm1eiMWwY5bWvdCAD8MPJCYXMy69SW5fkls4ljjkbFqr+3EXv+9exUWa78+d4ilCqGtsDVRfWKJdIBfEoqtqZIAFsevoV1Zdn9HR0dj/X09AwDQE9Pz2Q8uu+MRLpHbzVh++COUXGd76Z7f3Nh1ZBHAeARKXhSTTVKbZQsT2b5VOO1BCG/Wgny2Hr9cTw58JUbyCX39i5DqYIWG5+txl+GvhpLof8x0ioDt5sXebB39HPqAJDnU6kjP0qnj79W1JcSCrYNtqLpwy2XEw72p3u6ls228yqWzc4OilS2XbuzJe9nGQFeGZl4pK+YTzrqaK5YoRpHHoW4iT9PTowdiAvphd75uWqpVOfPIHguOz93aCWsYBkl7v9tU02eGh6+0rUIY661tbbWPlftv9DKUDsQUF/KAAAAAElFTkSuQmCC";
7868
8020
  const depthSlotIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAFnUlEQVRo3u1ZTWxUVRT+zptOp51pZZpOaWlGCgIFFIRgiCsNJi6MbFyyMRqgPygmJhrXNbJgQQQTSf9mGhaEuGkCK/9iMkhAoxAoJCIBTZEWO0Ch03ZsZzpzPxf3venr0JoZ7LzOkJ7Mz3v3vfvuO/ec7zvn3Assy7IUhUihB9h74MBGI8099jblkq/6OjtvFHLcskIrZii1KVFZ3zEW2AEFYc39S1KRiF4BUNqKAUCiciVGVr/BFAWVk0OoSEQLPqbhlM/TYYyVOYVkIUUc1M5w0lxOquaMYiJOEPBSWIyAOAszZzAGcdgRHWNFghDSQasZTllMtH7ylJEHtameOlZ0Ojo7mXmIw4oVhBX3t7YdFYofAKiwJlstUXKwpaX9LZNWpm/dvPFBJBJJlQDdy/SUf/07sYadUIRMe2ppUX501at8UPPi6wrCVdHzqI7/+cViK1UwV2Ta1eWJD6cnA1sQq9+J+Ip10PQhjK1oxr2VL3PUv1W8U8MJqPThksFYOHz8tjEzddI/9CMIzYRCiGYR7ZYN939CWTp5OhQKRUuKPETUIf/dCwKmrcxD/5NiqBSCIz8gnebhQo1fMMV6enr+cM2Mf+OPXhKQYo9hDdFzUp4cP93X1z1QknQvNA7X3vkeAkUb77Mheh5KyZGSjWO9vZ1ny6ceRKpHr4mFrZqH11AxHb0YDnedL+kALcCXtX+fy6QfwTtfCxQOlXzZcvPm72c2bMAtX+zWOkVIZXzoSijUfaYoFGtpbTsHSNCW+k2Gerq25tI3Eomkmps3H2q4892JtOEBRbryymJa2i6L6CwGABQ5FO7tfmWRLCbB4e0H18x4/JR0AmsvHZkguSXXl4vH4wOfHz02CvzDAx9/djHU3Zlz3/b299b98vwn1akyL8uTY9hx/ejiumKqws9UeY1IetqKsp5c+/p8Pqysq+t3u90TgUAA+fQFgOmKWqZclQAphcGYCJ+0Btm9+81T/68ykLwWF3JXjBRrVeZJJBgMThZ1PeZ0XWWbVAhyd8WcFdPJrCxFMZyZTiuhXlTFBBSQsiQWM6dTCkIeIoQImMfDF00tMb1FCmCxDNU6uuw564jMEwRGXhYDl8gTTQgULI7Neryrv7+/2SF0uSxXLGASLKQYmPI1es9cuH4qC9vZh/PAP7tBSBNFgPYIZo2HykYBXHknBnkGaJAuD/566SOCEEUCYpCk0HxJQodxmqGBBGjjaWUeZt2n+ypo7jWXEJR1TT9Y8KSZx7597zcZhlpjnacNNdbXbZbvIpxT4pMZIuFjFtEvlsGlxWqKIqAo61kwUzTqPU+xlnvMiZpdBNIK20fY29a2zaWM2axfGYPh8PHb8yomrvS7SV+yY6YqASPpQsVDbwTAawDgiQ1KmXsUFGtKYR0DJDQIRO+qMONSYk22FV0tyiZpntC0GoUwiDl9xTI4QIo7OT7LekqOxXwPdyVdM/AmfPAmfR0APl3QFR+tH0V02136Rqrw3Lcbreaf6387OYgiEAWMWMfXmgZw75koNw+9gE3DW3LAmJmWiWBXS2u7uVGCohAB0NLavkd7DCkLJEMLkkd81QQH3r4IpikUkiSgIAqk/sz9AgCVdiwqitlGRQWLAax2ivZdKgqhn23vk7kP5lWTPZTKjDPnes4BWgzR9xMCYxa0NFGdsaoZXAQi9nOdfmnwiBV/aO7+yQIxQfuITtnEgl0mOTD/ZJ5uMm/RUTY/sxOVj7xo/PVZ2MBsiz8UW2zK8JW1vWe7D8w6N3/tHKe3BZkV4Gy5r/VS2VH6atNlxLxjecQxQlwJF6pGqq4AxocoSlHH3Kny7cT8rviYYr6RKtSjEe7JchAyFurtPFuMau1vaR9bfb+JgYk6BMbr/lsxoUR80eoOX7TaKhcGUaRCkROrH6yN2N8dy7IsxSf/Avx35qhCwuXeAAAAAElFTkSuQmCC";
7869
8021
  const refreshIcon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAJgklEQVRo3u1aaVRURxbOj/yYHzknc04E3JClwY1RxyW4EBmXMC5xdIwh4MkEkO5+rxskioqAMJIIykQEFdmCERoaxA0XUIlBwCUmIWJwy5hojGbIDBkzkahRQObcO/dW92PR0BBFWh3eOd+pevXqVd3v3Vu37q3uZ57puXqu/79LluWpTyUxraRDrVaOnTRp0rNPHbHEmNeJnK4iIEDn+FQR++8nA6Eo/Y8YpJdqJUl65akh1vTxQLhLOF/ojuFL/Nk0EwICAn7zxJBgU9PI8hwSPFyS5PVkftlMrOEjV2w84QqM6+VDYeOqeWyanzzWpqnR60cLEpLuypK3FuCm2Hm4I3k6lGROwSMGTzya4wn1x12xgUg1fORCcBXg50F6bR0RnPd4mZhWN01DDiFyqR/uTfOCb4pHEAEXuHPMBVuXltq+2jsKwkPZNHWbrG6abD6kndKoZW/iCeMEvHXUFW4fdUESFBQo91w2455non5MBXXlgyBuxXzUSPJJb2/v56ylpTfIs93anzEFbla44s9HVdAGR1R4i6Dc325+5oI//0L7jQoXLEzxAlmWatgCrERKjo1c4geX9g0HEr4ZNysEmTb1m0fub1Pqyn3NQTd8N9oHSFMlOp2un3UcBDmH+BW+UPvBIBLOGW6Uq/BGuTNyyfckLPxUroIzO0ZDwYZpsPav3ric1k5IsEZA6W/q6wyV+e64OCSwSZJ0UVaLSDSSLiYucj5c+9CVCDnfh/+UukBx+mSMWOIn1gn3V1N8qFYHO9Bm/Dy7+5/KnAWul6kgP2k6kPZr1Gqdh9UcBUcJyxf749XiISSYE9S1xmFnrN4+EgQhra6Y+o5tb4Pmd68WDcHYSF+l7/NW9H4BvSkyr/28YCReP+wEP5Y6ibLOjMJNU5CfqyX9Kx1FHscNY8kk1fWkzaVW36fI/jdnvTsTfyx1ZFJgKh3hOtW3b3gZtZJ8gc2tMyEVaenSgnY02t051IhQiiK+L6E19KGjwA+HnJDLgxkvIUcZGo3GrlNrVKvbaVXTu8dhbN6VPBl/OOQI1z5wFCXjy91DQafT1pOgqicuGqe19Vs9CX+lyJVIOcC/SxyRyFHpgEkxczkyX/REphmSpPdfGz0PiQh8zzjogLWEqvwRwGulMzEd9+FIgj+CRtIHc93qsSDtRcb96ROI0ACobYXU2Fkdaos3WzLjKI0UVOcbloRzYgpwzso89KF6oBxSx8+sRpAdQ3XBUPzXgQGg4LtiBwgJUqMlh8ECU/pS4hu+ETwza8A9px7H5DTCKEMj/J4wOuMaeIdtRO7T7eS8g4KeC9Zr8LviAfjP/fbA4PpnxmEUVejOdRBLpvtGpqBH7m0Yl1sP7rkNMCanwUQsuxGGZzXi77Y0wKvhqfSBdJu713FI0uCI0L9ATTETasH+tPEcrBotbQ8LFoahZ+5N8Mi9g4JYTguxEURsWPZdcNtC5DJvgn9wGAYG6gd1GzGO31aFv441Rf2hpshe4B9UL0iaxBqLtxT5v7q6ECbm3QEPYz2MNzaYNGaox1HZDcimOIw05pZ1F4ZsaYLpbxeCpfEeQWqi/0NchDd+u68/COztjwQwrpvCgsRY2ISLZyZXCWITiFiLxhphpHmNCY2ZiY1PPC3SlXbH0/C5CZ2X/AIC9Q+gaQ573g7zgat7+sFVInR1bz+4sqc/bkvypIhcn2AhAS2dkXIGJhrvIBMbf88aazZFM7GxSed566iwlCatj/kTFqWMg30p40TJWLbIDx8oNFOr1S788hUi9s3ufkoJB9Je5FRjjwVi2bMTykymSGusmZihAUe10VgjDtlyFybFHwNLDkSjlXeWpI8Bnr+1LGGL38QHinp4HyJH0HRxl70gdLmwH17e3RdOGgcCbwPtCiLLPm+EJaCyxsYZW2usAUfcY4qvkdu3dDpFAXbNSeMgIYMix8Wd9sCyPXBiym792BY3uLSrL35NuFzYFxhL3/Jr15PxZBztz9xQiR7KGrvPFBsFMc+1n/J6PdfeXsZriK3ma9P8IEqa/zjJ1NGW0+ExwNZ1E5lYK/SBzNUvixPc9he8frRaXlg/bWMVmyK2dveKKU5cV4Xch/tacGAJ76+Zipd29kWeV5EhL4HXuW7TQ2XN0ct8SfV94OKOPvgVgeuVBhe27zoOki1tF2yyPrRReyV9hh4ZNTgh7VucvK4SX1ueLPIyS6Q4udXTIerJXGdQ5lWwcpkPPtRJljneq63MceHBBb7c3gcZqavEeUV6RwEwuWs1bwFMhE1Uy3Vq6yiU4rEz4rya51VwImsgm2HtQ4divGetj5mJF7b1JkK9QcHpPHsMDfFH3mcexfkKr+Oz+f2b57tgRlqsF6opCOiSnIzN7uMsFf69oDcTBC4JUJE5mJPNW115ykTnih46WVt/+D03mseO5zLPZ0faUiE/62zG3hmtLV0T+Wc8v9UOv6AJvthK4JImPbBpODK5rji9ZU1RYnvrQMrwtnOZ54uLmItdeggkXLhWrt6e6A7n823hXL4dnsuzw/P5dkACwKG0oSazJC/6ILbP5/TsZUND/JpKUt1QjE/gsRVsW+dODkeu7vI0h/ct1kxp+mA4l2cLZ4nY2TxbFkDUP80eAGujZvEXreUk1JLHbG3mWlkO53cSo2dCZbY9jWfbPD6XfH8obQiwCT6y8xU2t0UL/ZuOZtIRdq4tnjGyALZAJZMU9bIMV0iMnmFaCxQDcuQuPCP9CMigs0d/zgD4WZBe08R9y9JdxVhiHGPb8Y68p8JFwf5Nj/yHCq1WO4/JlaQMhtMkxOlcG6jOtcHTRNQEvrfFKkMfKE4eBu/HTcSk6BkQHzFbgIlsprZ9G4fhKUNv0b/5XTGeLVab7w+lDgImFRio7Z4fBPnrsUby176In+fYkCA2IMocKg02yGjT1qqPeEZtAq36KPdKncfuKqf0az2YihdzfOQsPJLhwAKzkAKnBLleojyV3Ytgum+BDbQ8Nz8zv1uR4YRx4XOEo+jWzPr+ozU5nLWXHDMVK9IHkHn1gqqsXlglCJHwDIOp5DbRbjC1NdfpWXmaI25Y6UW/AWjFCdZj8ScXjus4YKWvXPfOsrmQ+zd3KEt3gJNMMEsQEPUWvCDaSlOd0BA/Ft4JmwscBFBeFjNfkno9jifHHBvOUZv++nBlYdACjAz1wTURszAhajomrJiOq8NnY9QSbwzWB4pzf+7L7zxRf0PyCw5+gdN3TiT5VJnBLp/bOrPP9Vw9V8/Vc3X79T8J1TZaWjb6HwAAAABJRU5ErkJggg==";
@@ -9123,27 +9275,31 @@ const _sfc_main$3 = {
9123
9275
  _saveDataZoomState() {
9124
9276
  if (!this.chart || this.chart.isDisposed()) return null;
9125
9277
  try {
9126
- const option = this.chart.getOption();
9127
- if (option && option.dataZoom && option.dataZoom.length > 0) {
9128
- return option.dataZoom.map((dz) => ({
9129
- start: dz.start,
9130
- end: dz.end,
9131
- startValue: dz.startValue,
9132
- endValue: dz.endValue
9133
- }));
9134
- }
9278
+ const model = this.chart.getModel();
9279
+ const list = model.queryComponents({ mainType: "dataZoom" }) || [];
9280
+ if (!list.length) return null;
9281
+ return list.map((m) => {
9282
+ const opt = m.option || {};
9283
+ return {
9284
+ start: opt.start,
9285
+ end: opt.end,
9286
+ startValue: opt.startValue,
9287
+ endValue: opt.endValue
9288
+ };
9289
+ });
9135
9290
  } catch (e) {
9291
+ return null;
9136
9292
  }
9137
- return null;
9138
9293
  },
9139
9294
  // notMerge 刷 option 时把当前趋势线 graphic 带回去,避免先消失再画。8.24
9140
9295
  _preserveGraphic(options) {
9141
9296
  if (!options || options.graphic || !this.chart || this.chart.isDisposed()) return;
9142
9297
  try {
9143
- const current = this.chart.getOption();
9144
- if (current && current.graphic && current.graphic.length) {
9145
- options.graphic = current.graphic;
9146
- }
9298
+ const model = this.chart.getModel();
9299
+ const list = model.queryComponents({ mainType: "graphic" }) || [];
9300
+ if (!list.length) return;
9301
+ const graphic = list.map((m) => m.option).filter((item) => item && (item.id || item.elements || item.type));
9302
+ if (graphic.length) options.graphic = graphic;
9147
9303
  } catch (e) {
9148
9304
  }
9149
9305
  },
@@ -9196,7 +9352,10 @@ const _sfc_main$3 = {
9196
9352
  const next = this.getOptionsWithTheme(options, skipClone);
9197
9353
  this._applySavedDataZoomToOptions(next, savedDataZoom);
9198
9354
  this._preserveGraphic(next);
9199
- this.delegateMethod("setOption", next, notMerge, lazyUpdate);
9355
+ this.delegateMethod("setOption", next, {
9356
+ notMerge: !!notMerge,
9357
+ lazyUpdate: !!lazyUpdate
9358
+ });
9200
9359
  this.$nextTick(() => {
9201
9360
  this._skipWatcher = false;
9202
9361
  });
@@ -9359,7 +9518,9 @@ const _sfc_main$3 = {
9359
9518
  const next = this.getOptionsWithTheme(val);
9360
9519
  this._applySavedDataZoomToOptions(next, savedDataZoom);
9361
9520
  this._preserveGraphic(next);
9362
- this.chart.setOption(next, val !== oldVal);
9521
+ this.chart.setOption(next, {
9522
+ notMerge: this.skipClone || val !== oldVal
9523
+ });
9363
9524
  if (this.group) {
9364
9525
  this.chart.group = this.group;
9365
9526
  }
@@ -9371,8 +9532,15 @@ const _sfc_main$3 = {
9371
9532
  },
9372
9533
  destroy() {
9373
9534
  this._unbindNativeDragGuard();
9535
+ if (this.__unwatchOptions) {
9536
+ this.__unwatchOptions();
9537
+ this.__unwatchOptions = null;
9538
+ }
9374
9539
  if (this.autoresize) {
9375
9540
  removeListener(this.$el, this.__resizeHandler);
9541
+ if (this.__resizeHandler && this.__resizeHandler.cancel) {
9542
+ this.__resizeHandler.cancel();
9543
+ }
9376
9544
  }
9377
9545
  this.dispose();
9378
9546
  this.chart = null;
@@ -9445,17 +9613,35 @@ const _hoisted_1$3 = { class: "echarts" };
9445
9613
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
9446
9614
  return openBlock(), createElementBlock("div", _hoisted_1$3);
9447
9615
  }
9448
- const resizeEcharts = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3], ["__scopeId", "data-v-0df7a705"]]);
9616
+ const resizeEcharts = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3], ["__scopeId", "data-v-c1cce4a1"]]);
9449
9617
  const DRAW_POINT_MIN = 600;
9450
9618
  const DRAW_POINT_MAX = 1800;
9451
9619
  function getSeriesDrawThreshold(laneHeightPx) {
9452
9620
  const h = Number(laneHeightPx) || 400;
9453
9621
  return Math.max(DRAW_POINT_MIN, Math.min(DRAW_POINT_MAX, Math.round(h * 2)));
9454
9622
  }
9623
+ function isMissingCurveValue(raw) {
9624
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") {
9625
+ return true;
9626
+ }
9627
+ const n = Number(raw);
9628
+ return !Number.isFinite(n);
9629
+ }
9630
+ function pointX(pt) {
9631
+ if (Array.isArray(pt)) return pt[0];
9632
+ if (pt && Array.isArray(pt.value)) return pt.value[0];
9633
+ return null;
9634
+ }
9635
+ function pointYRaw(pt) {
9636
+ if (Array.isArray(pt)) return pt[1];
9637
+ if (pt && Array.isArray(pt.value)) return pt.value[1];
9638
+ return null;
9639
+ }
9455
9640
  function getPointXY(pt) {
9456
- if (Array.isArray(pt)) return [Number(pt[0]), Number(pt[1])];
9457
- if (pt && Array.isArray(pt.value)) return [Number(pt.value[0]), Number(pt.value[1])];
9458
- return [NaN, NaN];
9641
+ const x = pointX(pt);
9642
+ const y = pointYRaw(pt);
9643
+ if (isMissingCurveValue(x)) return [NaN, Number(y)];
9644
+ return [Number(x), Number(y)];
9459
9645
  }
9460
9646
  function lttb(data, threshold) {
9461
9647
  const n = data && data.length || 0;
@@ -9488,8 +9674,37 @@ function lttb(data, threshold) {
9488
9674
  return sampled;
9489
9675
  }
9490
9676
  function downsampleSeriesForDraw(data, threshold) {
9491
- if (!data || data.length <= threshold) return data || [];
9492
- return lttb(data, threshold);
9677
+ if (!data || !data.length) return data || [];
9678
+ if (data.length <= threshold) return data;
9679
+ const segments = [];
9680
+ let cur = [];
9681
+ for (let i = 0; i < data.length; i++) {
9682
+ if (isMissingCurveValue(pointX(data[i]))) {
9683
+ if (cur.length) {
9684
+ segments.push(cur);
9685
+ cur = [];
9686
+ }
9687
+ } else {
9688
+ cur.push(data[i]);
9689
+ }
9690
+ }
9691
+ if (cur.length) segments.push(cur);
9692
+ if (segments.length === 1 && segments[0].length === data.length) {
9693
+ return lttb(data, threshold);
9694
+ }
9695
+ if (!segments.length) return data;
9696
+ const totalValid = segments.reduce((n, s) => n + s.length, 0);
9697
+ const out = [];
9698
+ for (let s = 0; s < segments.length; s++) {
9699
+ const seg = segments[s];
9700
+ const share = Math.max(2, Math.round(seg.length / totalValid * threshold));
9701
+ const sampled = seg.length <= share ? seg : lttb(seg, Math.min(share, seg.length));
9702
+ if (out.length) {
9703
+ out.push([null, pointYRaw(sampled[0])]);
9704
+ }
9705
+ for (let i = 0; i < sampled.length; i++) out.push(sampled[i]);
9706
+ }
9707
+ return out;
9493
9708
  }
9494
9709
  function lowerBound(rows, key, target) {
9495
9710
  let lo = 0;
@@ -9806,16 +10021,34 @@ const _sfc_main$2 = {
9806
10021
  this._pointerMetaGen = 0;
9807
10022
  this._lastTipKey = /* @__PURE__ */ new WeakMap();
9808
10023
  this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10024
+ this._laneHasValidPoint = /* @__PURE__ */ Object.create(null);
9809
10025
  this._pendingPointer = null;
9810
10026
  this._pointerRaf = 0;
9811
10027
  this._lastHeaderDataIndex = -1;
10028
+ this._tooltipLaneId = null;
10029
+ this._lastTooltipAxisLabel = "";
10030
+ this._isPanning = false;
10031
+ this._isZooming = false;
10032
+ this._zoomIdleTimer = 0;
10033
+ this._connectDetached = false;
10034
+ this._savedConnectGroups = null;
10035
+ this._tipHtmlBucket = "";
10036
+ this._tipHtmlMap = /* @__PURE__ */ Object.create(null);
10037
+ this._onWindowMouseUp = () => this.endChartPan();
9812
10038
  this._flushPointerSync = () => {
9813
10039
  this._pointerRaf = 0;
9814
10040
  const pending = this._pendingPointer;
9815
10041
  if (!pending || !this.pointerInChartArea) return;
9816
- this._pendingPointer = null;
9817
10042
  const { chart, x, y } = pending;
9818
- if (!chart || chart.isDisposed()) return;
10043
+ if (!chart || chart.isDisposed()) {
10044
+ this._pendingPointer = null;
10045
+ return;
10046
+ }
10047
+ if (this.isChartBusy()) {
10048
+ this.updateCrosshairLine(chart, y);
10049
+ return;
10050
+ }
10051
+ this._pendingPointer = null;
9819
10052
  this.syncAxisPointerAcrossCharts(chart, x, y);
9820
10053
  };
9821
10054
  this.debounceJudgeEdge = debounce(() => {
@@ -9833,25 +10066,47 @@ const _sfc_main$2 = {
9833
10066
  ) && this.currentToolBarConfig.showDateTime == true;
9834
10067
  window.addEventListener("keydown", this.handleKeyDown);
9835
10068
  window.addEventListener("keyup", this.handleKeyUp);
10069
+ window.addEventListener("mouseup", this._onWindowMouseUp);
9836
10070
  this.showTooltip = this.formCache.displayType == "float";
9837
10071
  },
9838
10072
  beforeUnmount() {
10073
+ this._isUnmounted = true;
9839
10074
  window.removeEventListener("keydown", this.handleKeyDown);
9840
10075
  window.removeEventListener("keyup", this.handleKeyUp);
10076
+ window.removeEventListener("mouseup", this._onWindowMouseUp);
10077
+ if (this._zoomIdleTimer) {
10078
+ clearTimeout(this._zoomIdleTimer);
10079
+ this._zoomIdleTimer = 0;
10080
+ }
9841
10081
  if (this.trendLineManager) this.trendLineManager.destroy();
9842
10082
  if (this._pointerRaf) {
9843
10083
  cancelAnimationFrame(this._pointerRaf);
9844
10084
  this._pointerRaf = 0;
9845
10085
  }
10086
+ if (this._connectRaf) {
10087
+ cancelAnimationFrame(this._connectRaf);
10088
+ this._connectRaf = 0;
10089
+ }
10090
+ cancelAnimationFrame(this.animationId);
10091
+ this.animationId = null;
10092
+ if (this.debounceJudgeEdge && this.debounceJudgeEdge.cancel) {
10093
+ this.debounceJudgeEdge.cancel();
10094
+ }
10095
+ if (this.scheduleConnectAllCharts && this.scheduleConnectAllCharts.cancel) {
10096
+ this.scheduleConnectAllCharts.cancel();
10097
+ }
9846
10098
  this._pendingPointer = null;
10099
+ this.attachChartConnect();
9847
10100
  this.unbindChartPointerSync();
9848
10101
  echarts.disConnect(this.group);
9849
10102
  this.clearEcharts();
9850
10103
  if (this.resizeObserver) {
9851
10104
  this.resizeObserver.disconnect();
10105
+ this.resizeObserver = null;
9852
10106
  }
9853
10107
  if (this.resizeTimeout) {
9854
10108
  clearTimeout(this.resizeTimeout);
10109
+ this.resizeTimeout = null;
9855
10110
  }
9856
10111
  },
9857
10112
  methods: {
@@ -9872,7 +10127,11 @@ const _sfc_main$2 = {
9872
10127
  getLaneLogPlotRange(lane) {
9873
10128
  return resolveLaneLogPlotRange(lane, this.lineRange);
9874
10129
  },
9875
- // 整道 10 条竖线,样式跟普通泳道 splitLine 同一套。8.22对数轴
10130
+ // 对数开关变化时重建该道图表,series 才能换成 lg 数据。8.24
10131
+ chartLaneKey(lane) {
10132
+ return `${lane && lane.laneId}-${isLaneLogScale(lane) ? "log" : "lin"}`;
10133
+ },
10134
+ // 对数竖格:整道 10 条同一虚线,和线性纸格一致。8.25
9876
10135
  getLogPaperGridSeries(lane, xAxisIndex, yAxisIndex) {
9877
10136
  const range = this.getLaneLogPlotRange(lane);
9878
10137
  const color = getCssVariable("--kd-lane-container-item-line-color");
@@ -9908,19 +10167,18 @@ const _sfc_main$2 = {
9908
10167
  },
9909
10168
  getLaneChartContentStyle(laneId) {
9910
10169
  const width = this.laneWidthMap && this.laneWidthMap[laneId];
9911
- const gap = this.currentHeaderStyle.itemGap || 0;
9912
10170
  const style = {};
9913
10171
  if (width && Number(width) > 0) {
9914
10172
  Object.assign(style, {
9915
10173
  width: `${width}px`,
9916
- padding: `0 ${gap}px`,
10174
+ padding: "0",
9917
10175
  height: "100%"
9918
10176
  });
9919
10177
  } else {
9920
10178
  Object.assign(style, {
9921
10179
  width: "100%",
9922
10180
  height: "100%",
9923
- padding: `0 ${gap}px`,
10181
+ padding: "0",
9924
10182
  flex: "1"
9925
10183
  });
9926
10184
  }
@@ -9971,8 +10229,14 @@ const _sfc_main$2 = {
9971
10229
  if (!this.isGeomechanical) return;
9972
10230
  this.getConnectedCharts().forEach((chart) => {
9973
10231
  if (!chart || chart.isDisposed()) return;
10232
+ const laneId = this.findLaneIdByChart(chart);
9974
10233
  chart.setOption({
9975
- dataZoom: [this.buildInsideDataZoom(!!enabled)]
10234
+ dataZoom: [
10235
+ this.buildInsideDataZoom(
10236
+ !!enabled,
10237
+ this.dataZoomFilterModeForLane(this.findLaneById(laneId))
10238
+ )
10239
+ ]
9976
10240
  });
9977
10241
  });
9978
10242
  },
@@ -10049,6 +10313,35 @@ const _sfc_main$2 = {
10049
10313
  }
10050
10314
  return 1;
10051
10315
  },
10316
+ // 只读 option 引用,禁止 getOption() 深拷贝整图 series。8.25
10317
+ readChartOptionRefs(chart) {
10318
+ const empty = { grid: [], yAxis: [], xAxis: [], series: [] };
10319
+ if (!chart || chart.isDisposed()) return empty;
10320
+ try {
10321
+ const model = chart.getModel();
10322
+ const collect = (mainType) => {
10323
+ const list = model.queryComponents({ mainType }) || [];
10324
+ const out = [];
10325
+ for (let i = 0; i < list.length; i++) {
10326
+ out.push(list[i].option || {});
10327
+ }
10328
+ return out;
10329
+ };
10330
+ const seriesModels = model.getSeries() || [];
10331
+ const series = [];
10332
+ for (let i = 0; i < seriesModels.length; i++) {
10333
+ series.push(seriesModels[i].option || {});
10334
+ }
10335
+ return {
10336
+ grid: collect("grid"),
10337
+ yAxis: collect("yAxis"),
10338
+ xAxis: collect("xAxis"),
10339
+ series
10340
+ };
10341
+ } catch (e) {
10342
+ return empty;
10343
+ }
10344
+ },
10052
10345
  readGridBounds(chart, gridIndex, width) {
10053
10346
  try {
10054
10347
  const gridModel = chart.getModel().getComponent("grid", gridIndex);
@@ -10092,7 +10385,15 @@ const _sfc_main$2 = {
10092
10385
  bottom: chart.getHeight && chart.getHeight() || 0
10093
10386
  };
10094
10387
  },
10388
+ seriesDataHasValidX(data) {
10389
+ if (!data || !data.length) return false;
10390
+ for (let i = 0; i < data.length; i++) {
10391
+ if (this.isValidTooltipX(this.pointXY(data[i]).x)) return true;
10392
+ }
10393
+ return false;
10394
+ },
10095
10395
  collectTooltipSeries(chart, seriesByGrid) {
10396
+ let hasAnyValidPlotPoint = false;
10096
10397
  try {
10097
10398
  const seriesList = chart.getModel().getSeries();
10098
10399
  for (let s = 0; s < seriesList.length; s++) {
@@ -10115,9 +10416,13 @@ const _sfc_main$2 = {
10115
10416
  seriesIndex: sm.seriesIndex,
10116
10417
  data
10117
10418
  });
10419
+ if (!hasAnyValidPlotPoint) {
10420
+ hasAnyValidPlotPoint = this.seriesDataHasValidX(data);
10421
+ }
10118
10422
  }
10119
10423
  } catch (e) {
10120
10424
  }
10425
+ return hasAnyValidPlotPoint;
10121
10426
  },
10122
10427
  ensurePointerMeta(chart) {
10123
10428
  const width = chart.getWidth && chart.getWidth() || 0;
@@ -10133,14 +10438,18 @@ const _sfc_main$2 = {
10133
10438
  bounds[i] = this.readGridBounds(chart, i, width);
10134
10439
  seriesByGrid[i] = [];
10135
10440
  }
10136
- this.collectTooltipSeries(chart, seriesByGrid);
10441
+ const hasAnyValidPlotPoint = this.collectTooltipSeries(
10442
+ chart,
10443
+ seriesByGrid
10444
+ );
10137
10445
  meta = {
10138
10446
  gen: this._pointerMetaGen,
10139
10447
  width,
10140
10448
  height,
10141
10449
  gridCount,
10142
10450
  bounds,
10143
- seriesByGrid
10451
+ seriesByGrid,
10452
+ hasAnyValidPlotPoint
10144
10453
  };
10145
10454
  this._pointerMeta.set(chart, meta);
10146
10455
  return meta;
@@ -10207,18 +10516,32 @@ const _sfc_main$2 = {
10207
10516
  const item = Array.isArray(tip) ? tip[0] : tip;
10208
10517
  return !!(item && item.show === false);
10209
10518
  },
10210
- // 对数轴曲线 X 用 lg(x);轴是线性 lg 量程,允许负数。8.22对数轴
10519
+ // 对数轴曲线 X 用 lg(x);缺数保持 null,不能 Number(null) 成 0。8.25
10211
10520
  plotX(raw, isLogScale) {
10521
+ if (isMissingCurveValue(raw)) return null;
10212
10522
  return isLogScale ? toLogPlotX(raw) : raw;
10213
10523
  },
10214
10524
  plotSeries(data, isLogScale) {
10215
- return isLogScale ? mapSeriesDataXToLog(data) : data;
10525
+ if (!data || !data.length) return data || [];
10526
+ if (isLogScale) return mapSeriesDataXToLog(data);
10527
+ return data.map((item) => {
10528
+ if (Array.isArray(item)) {
10529
+ if (!isMissingCurveValue(item[0])) return item;
10530
+ return [null, item[1], item[2]];
10531
+ }
10532
+ if (item && Array.isArray(item.value)) {
10533
+ if (!isMissingCurveValue(item.value[0])) return item;
10534
+ return {
10535
+ ...item,
10536
+ value: [null, item.value[1]]
10537
+ };
10538
+ }
10539
+ return item;
10540
+ });
10216
10541
  },
10217
10542
  // null / '' 不能当有数:Number(null) === 0,会误打到空的第一条线。8.22
10218
10543
  isValidTooltipX(raw) {
10219
- if (raw === null || raw === void 0 || raw === "") return false;
10220
- const n = Number(raw);
10221
- return Number.isFinite(n);
10544
+ return !isMissingCurveValue(raw);
10222
10545
  },
10223
10546
  pointY(pt) {
10224
10547
  if (Array.isArray(pt)) return Number(pt[1]);
@@ -10297,7 +10620,74 @@ const _sfc_main$2 = {
10297
10620
  };
10298
10621
  }
10299
10622
  }
10300
- return best;
10623
+ return best;
10624
+ },
10625
+ findLaneIdByChart(chart) {
10626
+ const map = this.chartRefMap || {};
10627
+ for (const laneId in map) {
10628
+ const ref = map[laneId];
10629
+ if (ref && ref.chart === chart) return laneId;
10630
+ }
10631
+ return null;
10632
+ },
10633
+ findLaneById(laneId) {
10634
+ if (laneId == null) return null;
10635
+ const lanes = this.currentTemplate && this.currentTemplate.lanes || [];
10636
+ for (let i = 0; i < lanes.length; i++) {
10637
+ if (lanes[i] && lanes[i].laneId == laneId) return lanes[i];
10638
+ }
10639
+ return null;
10640
+ },
10641
+ isMissingTooltipValue(raw) {
10642
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") {
10643
+ return true;
10644
+ }
10645
+ const n = Number(raw);
10646
+ return !Number.isFinite(n);
10647
+ },
10648
+ // 泳道内任一曲线在任意井深有过有效点,才允许出浮窗。8.25
10649
+ laneHasAnyValidPlotPoint(chart, laneId) {
10650
+ if (laneId != null && this._laneHasValidPoint && this._laneHasValidPoint[laneId]) {
10651
+ return true;
10652
+ }
10653
+ const meta = this.ensurePointerMeta(chart);
10654
+ if (meta && typeof meta.hasAnyValidPlotPoint === "boolean") {
10655
+ return meta.hasAnyValidPlotPoint;
10656
+ }
10657
+ const grids = meta && meta.seriesByGrid || [];
10658
+ for (let g = 0; g < grids.length; g++) {
10659
+ const list = grids[g] || [];
10660
+ for (let s = 0; s < list.length; s++) {
10661
+ if (this.seriesDataHasValidX(list[s] && list[s].data)) return true;
10662
+ }
10663
+ }
10664
+ return false;
10665
+ },
10666
+ findHelperTooltipAnchor(chart, yValue, gridIndex) {
10667
+ try {
10668
+ const seriesList = chart.getModel().getSeries();
10669
+ const gi = this.clampGridIndex(
10670
+ this.ensurePointerMeta(chart).gridCount,
10671
+ gridIndex
10672
+ );
10673
+ for (let s = 0; s < seriesList.length; s++) {
10674
+ const sm = seriesList[s];
10675
+ const name = this.unwrapEchartsValue(sm.name);
10676
+ if (name !== "helper") continue;
10677
+ const option = sm.option || {};
10678
+ let yAxisIndex = this.unwrapEchartsValue(option.yAxisIndex);
10679
+ yAxisIndex = yAxisIndex == null || yAxisIndex === "" ? 0 : Number(yAxisIndex);
10680
+ if (!Number.isInteger(yAxisIndex) || yAxisIndex < 0) yAxisIndex = 0;
10681
+ if (yAxisIndex !== gi) continue;
10682
+ const data = option.data;
10683
+ if (!data || !data.length) continue;
10684
+ let dataIndex = this.findNearestDataIndexByY(data, yValue);
10685
+ if (dataIndex < 0) dataIndex = 0;
10686
+ return { seriesIndex: sm.seriesIndex, dataIndex };
10687
+ }
10688
+ } catch (e) {
10689
+ }
10690
+ return null;
10301
10691
  },
10302
10692
  onChartAreaMouseMove(event) {
10303
10693
  const charts = this.getConnectedCharts();
@@ -10343,51 +10733,56 @@ const _sfc_main$2 = {
10343
10733
  this.showSyncedLaneTooltips(hit.yValue, offsetY, hit.gridIndex);
10344
10734
  },
10345
10735
  showSyncedLaneTooltips(yValue, fallbackY, gridIndex) {
10346
- const charts = this.getConnectedCharts();
10736
+ if (this.isChartBusy() || this._showingTips) return;
10737
+ this._showingTips = true;
10347
10738
  const needTip = this.showTooltip;
10348
10739
  const needHeader = this.formCache.displayType === "header";
10349
- for (let c = 0; c < charts.length; c++) {
10350
- const chart = charts[c];
10351
- if (!chart || chart.isDisposed()) continue;
10352
- const meta = this.ensurePointerMeta(chart);
10353
- const targetGridIndex = this.clampGridIndex(meta.gridCount, gridIndex);
10354
- const pos = this.getPixelFromYValue(chart, yValue, targetGridIndex);
10355
- const x = pos && Number.isFinite(pos[0]) ? pos[0] : (meta.width || 80) / 2;
10356
- const y = pos && Number.isFinite(pos[1]) ? pos[1] : fallbackY;
10357
- const axisKey = `${targetGridIndex}:${y | 0}`;
10358
- const group = chart.group;
10359
- chart.group = null;
10360
- if (this._lastAxisPx.get(chart) !== axisKey) {
10361
- this._lastAxisPx.set(chart, axisKey);
10362
- chart.dispatchAction({
10363
- type: "updateAxisPointer",
10364
- currTrigger: "mousemove",
10365
- x,
10366
- y,
10367
- axesInfo: [
10368
- {
10369
- axisDim: "y",
10370
- axisIndex: targetGridIndex,
10371
- value: yValue
10372
- }
10373
- ]
10374
- });
10375
- }
10376
- if (needTip || needHeader) {
10377
- const nearest = this.findNearestTooltipPoint(
10378
- chart,
10379
- yValue,
10380
- targetGridIndex
10381
- );
10382
- if (needHeader && nearest && nearest.rowData && nearest.dataIndex !== this._lastHeaderDataIndex) {
10383
- this._lastHeaderDataIndex = nearest.dataIndex;
10384
- this.headerData = nearest.rowData;
10740
+ const row = this.findRowByAxisValue(yValue);
10741
+ this._lastTooltipAxisLabel = this.formatAxisPointerYLabel(yValue, row);
10742
+ if (needHeader && row && row !== this.headerData) {
10743
+ this.headerData = markRaw(row);
10744
+ }
10745
+ const charts = this.getConnectedCharts();
10746
+ this.detachChartConnect();
10747
+ try {
10748
+ for (let c = 0; c < charts.length; c++) {
10749
+ const chart = charts[c];
10750
+ if (!chart || chart.isDisposed()) continue;
10751
+ const laneId = this.findLaneIdByChart(chart);
10752
+ this._tooltipLaneId = laneId;
10753
+ const lane = this.findLaneById(laneId);
10754
+ const meta = this.ensurePointerMeta(chart);
10755
+ const targetGridIndex = this.clampGridIndex(meta.gridCount, gridIndex);
10756
+ const pos = this.getPixelFromYValue(chart, yValue, targetGridIndex);
10757
+ const x = pos && Number.isFinite(pos[0]) ? pos[0] : (meta.width || 80) / 2;
10758
+ const y = pos && Number.isFinite(pos[1]) ? pos[1] : fallbackY;
10759
+ const axisKey = `${targetGridIndex}:${y | 0}`;
10760
+ const pinAxis = () => {
10761
+ chart.dispatchAction({
10762
+ type: "updateAxisPointer",
10763
+ currTrigger: "mousemove",
10764
+ x,
10765
+ y,
10766
+ axesInfo: [
10767
+ {
10768
+ axisDim: "y",
10769
+ axisIndex: targetGridIndex,
10770
+ value: yValue
10771
+ }
10772
+ ]
10773
+ });
10774
+ };
10775
+ if (this._lastAxisPx.get(chart) !== axisKey) {
10776
+ this._lastAxisPx.set(chart, axisKey);
10777
+ pinAxis();
10385
10778
  }
10386
- if (needTip) {
10387
- const tipKey = nearest ? `${nearest.seriesIndex}:${nearest.dataIndex}` : "";
10779
+ const canShowTip = needTip && lane && lane.lines && lane.lines.length > 0 && this.laneHasAnyValidPlotPoint(chart, laneId);
10780
+ if (canShowTip) {
10781
+ const tipKey = `${axisKey}:${Number(yValue).toFixed(2)}`;
10388
10782
  if (this._lastTipKey.get(chart) !== tipKey) {
10389
- this._lastTipKey.set(chart, tipKey);
10783
+ const nearest = this.findHelperTooltipAnchor(chart, yValue, targetGridIndex) || this.findNearestTooltipPoint(chart, yValue, targetGridIndex);
10390
10784
  if (nearest) {
10785
+ this._lastTipKey.set(chart, tipKey);
10391
10786
  chart.dispatchAction({
10392
10787
  type: "showTip",
10393
10788
  seriesIndex: nearest.seriesIndex,
@@ -10395,13 +10790,16 @@ const _sfc_main$2 = {
10395
10790
  x,
10396
10791
  y
10397
10792
  });
10398
- } else {
10399
- chart.dispatchAction({ type: "hideTip" });
10400
10793
  }
10401
10794
  }
10795
+ } else if (this._lastTipKey.get(chart) != null) {
10796
+ this._lastTipKey.delete(chart);
10797
+ chart.dispatchAction({ type: "hideTip" });
10402
10798
  }
10799
+ pinAxis();
10403
10800
  }
10404
- chart.group = group;
10801
+ } finally {
10802
+ this._showingTips = false;
10405
10803
  }
10406
10804
  },
10407
10805
  isLeavingToTooltip(event) {
@@ -10410,6 +10808,79 @@ const _sfc_main$2 = {
10410
10808
  if (next.nodeType !== 1) return false;
10411
10809
  return !!(next.classList && next.classList.contains("echarts-tooltip") || next.closest && next.closest(".echarts-tooltip"));
10412
10810
  },
10811
+ isChartBusy() {
10812
+ return !!(this._isPanning || this._isZooming);
10813
+ },
10814
+ detachChartConnect() {
10815
+ if (this._connectDetached) return;
10816
+ const charts = this.getConnectedCharts();
10817
+ this._savedConnectGroups = [];
10818
+ for (let i = 0; i < charts.length; i++) {
10819
+ const chart = charts[i];
10820
+ if (!chart || chart.isDisposed()) continue;
10821
+ this._savedConnectGroups.push({ chart, group: chart.group });
10822
+ chart.group = null;
10823
+ }
10824
+ this._connectDetached = true;
10825
+ },
10826
+ attachChartConnect() {
10827
+ if (!this._connectDetached) return;
10828
+ const saved = this._savedConnectGroups || [];
10829
+ for (let i = 0; i < saved.length; i++) {
10830
+ const item = saved[i];
10831
+ if (!item || !item.chart || item.chart.isDisposed()) continue;
10832
+ item.chart.group = item.group;
10833
+ }
10834
+ this._savedConnectGroups = null;
10835
+ this._connectDetached = false;
10836
+ },
10837
+ hideLaneTooltipsForPan() {
10838
+ this._lastTipKey = /* @__PURE__ */ new WeakMap();
10839
+ this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10840
+ this.getConnectedCharts().forEach((chart) => {
10841
+ if (!chart || chart.isDisposed()) return;
10842
+ chart.dispatchAction({ type: "hideTip" });
10843
+ chart.dispatchAction({
10844
+ type: "updateAxisPointer",
10845
+ currTrigger: "leave"
10846
+ });
10847
+ });
10848
+ },
10849
+ restorePointerAfterInteract() {
10850
+ if (this.isChartBusy()) return;
10851
+ const pending = this._pendingPointer;
10852
+ if (!pending || !this.pointerInChartArea) return;
10853
+ const { chart, x, y } = pending;
10854
+ if (!chart || chart.isDisposed()) return;
10855
+ this.syncAxisPointerAcrossCharts(chart, x, y);
10856
+ },
10857
+ startChartPan() {
10858
+ if (!this.isGeomechanical || this._isPanning) return;
10859
+ this._isPanning = true;
10860
+ this.attachChartConnect();
10861
+ this.hideLaneTooltipsForPan();
10862
+ },
10863
+ endChartPan() {
10864
+ if (!this._isPanning) return;
10865
+ this._isPanning = false;
10866
+ this.restorePointerAfterInteract();
10867
+ },
10868
+ startChartZoom() {
10869
+ if (!this.isGeomechanical) return;
10870
+ this.attachChartConnect();
10871
+ if (!this._isZooming) {
10872
+ this._isZooming = true;
10873
+ if (!this._isPanning) this.hideLaneTooltipsForPan();
10874
+ }
10875
+ if (this._zoomIdleTimer) clearTimeout(this._zoomIdleTimer);
10876
+ this._zoomIdleTimer = setTimeout(() => this.endChartZoom(), 160);
10877
+ },
10878
+ endChartZoom() {
10879
+ this._zoomIdleTimer = 0;
10880
+ if (!this._isZooming) return;
10881
+ this._isZooming = false;
10882
+ this.restorePointerAfterInteract();
10883
+ },
10413
10884
  hideAllLaneTooltips(event) {
10414
10885
  if (this.isLeavingToTooltip(event)) return;
10415
10886
  const next = event && event.relatedTarget;
@@ -10417,8 +10888,10 @@ const _sfc_main$2 = {
10417
10888
  if (wrap && next && wrap.contains(next)) return;
10418
10889
  this.pointerInChartArea = false;
10419
10890
  this._lastTooltipY = null;
10891
+ this._lastTooltipAxisLabel = "";
10420
10892
  this._lastTooltipGridIndex = 0;
10421
10893
  this._lastHeaderDataIndex = -1;
10894
+ this._tooltipLaneId = null;
10422
10895
  this._lastTipKey = /* @__PURE__ */ new WeakMap();
10423
10896
  this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10424
10897
  this.crosshairVisible = false;
@@ -10433,6 +10906,7 @@ const _sfc_main$2 = {
10433
10906
  currTrigger: "leave"
10434
10907
  });
10435
10908
  });
10909
+ this.attachChartConnect();
10436
10910
  },
10437
10911
  hideAxisPointerAcrossCharts(event) {
10438
10912
  if (this.isLeavingToTooltip(event)) return;
@@ -10451,9 +10925,10 @@ const _sfc_main$2 = {
10451
10925
  this._pendingPointer = null;
10452
10926
  if (!this._pointerSyncHandlers || this._pointerSyncHandlers.length === 0)
10453
10927
  return;
10454
- this._pointerSyncHandlers.forEach(({ zr, onMove, onOut }) => {
10928
+ this._pointerSyncHandlers.forEach(({ zr, onMove, onDown, onOut }) => {
10455
10929
  if (zr) {
10456
10930
  zr.off("mousemove", onMove);
10931
+ if (onDown) zr.off("mousedown", onDown);
10457
10932
  if (onOut) zr.off("globalout", onOut);
10458
10933
  }
10459
10934
  });
@@ -10466,39 +10941,41 @@ const _sfc_main$2 = {
10466
10941
  const chart = item == null ? void 0 : item.chart;
10467
10942
  if (!chart || chart.isDisposed()) return;
10468
10943
  const zr = chart.getZr();
10944
+ const onDown = (e) => {
10945
+ const native = e.event || e;
10946
+ if (native.button != null && native.button !== 0) return;
10947
+ this.startChartPan();
10948
+ };
10469
10949
  const onMove = (e) => {
10470
10950
  var _a, _b;
10951
+ const native = e.event || e;
10952
+ if (this.isGeomechanical && native.buttons === 1 && !this._isPanning) {
10953
+ this.startChartPan();
10954
+ }
10471
10955
  this.schedulePointerSync(
10472
10956
  chart,
10473
10957
  e.offsetX ?? ((_a = e.event) == null ? void 0 : _a.offsetX),
10474
10958
  e.offsetY ?? ((_b = e.event) == null ? void 0 : _b.offsetY)
10475
10959
  );
10476
10960
  };
10477
- const onOut = () => {
10478
- if (!this.pointerInChartArea || !this.showTooltip) return;
10479
- if (this._lastTooltipY == null) return;
10480
- this.$nextTick(() => {
10481
- if (!this.pointerInChartArea || this._lastTooltipY == null) return;
10482
- this._lastTipKey = /* @__PURE__ */ new WeakMap();
10483
- this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10484
- this.showSyncedLaneTooltips(
10485
- this._lastTooltipY,
10486
- this._lastTooltipOffsetY,
10487
- this._lastTooltipGridIndex
10488
- );
10489
- });
10490
- };
10961
+ zr.on("mousedown", onDown);
10491
10962
  zr.on("mousemove", onMove);
10492
- zr.on("globalout", onOut);
10493
- this._pointerSyncHandlers.push({ zr, onMove, onOut });
10963
+ this._pointerSyncHandlers.push({ zr, onMove, onDown });
10494
10964
  });
10495
10965
  },
10496
10966
  // 联动所有泳道图表的十字准线与 tooltip(贯穿整个泳道区域)
10497
10967
  connectAllCharts() {
10498
10968
  this.$nextTick(() => {
10499
- requestAnimationFrame(() => {
10969
+ if (this._isUnmounted) return;
10970
+ if (this._connectRaf) cancelAnimationFrame(this._connectRaf);
10971
+ this._connectRaf = requestAnimationFrame(() => {
10972
+ this._connectRaf = 0;
10973
+ if (this._isUnmounted) return;
10500
10974
  const charts = this.getConnectedCharts();
10501
10975
  if (charts.length === 0) return;
10976
+ const keepDetached = this._connectDetached || this.pointerInChartArea && !this.isChartBusy();
10977
+ this._connectDetached = false;
10978
+ this._savedConnectGroups = null;
10502
10979
  charts.forEach((chart) => {
10503
10980
  chart.group = this.group;
10504
10981
  });
@@ -10507,6 +10984,7 @@ const _sfc_main$2 = {
10507
10984
  echarts.connect(this.group);
10508
10985
  }
10509
10986
  this.bindChartPointerSync();
10987
+ if (keepDetached) this.detachChartConnect();
10510
10988
  });
10511
10989
  });
10512
10990
  },
@@ -10602,7 +11080,12 @@ const _sfc_main$2 = {
10602
11080
  getXAxisRangeByHeader(lineInfo, validData = []) {
10603
11081
  let headerMin = 0;
10604
11082
  let headerMax = 1;
10605
- const numericValues = (validData || []).map((item) => Number(item[0])).filter((v) => !Number.isNaN(v) && v !== null && v !== void 0);
11083
+ const numericValues = (validData || []).reduce((acc, item) => {
11084
+ const raw = Array.isArray(item) ? item[0] : item && item.value ? item.value[0] : item;
11085
+ if (isMissingCurveValue(raw)) return acc;
11086
+ acc.push(Number(raw));
11087
+ return acc;
11088
+ }, []);
10606
11089
  if (lineInfo && Object.prototype.hasOwnProperty.call(lineInfo, "min")) {
10607
11090
  headerMin = Number(lineInfo.min);
10608
11091
  } else if (numericValues.length > 0) {
@@ -10615,10 +11098,10 @@ const _sfc_main$2 = {
10615
11098
  }
10616
11099
  const min = headerMin;
10617
11100
  const max = headerMax;
10618
- this.lineRange[lineInfo.lineId] = {
10619
- min,
10620
- max
10621
- };
11101
+ const prev = this.lineRange[lineInfo.lineId];
11102
+ if (!prev || prev.min !== min || prev.max !== max) {
11103
+ this.lineRange[lineInfo.lineId] = { min, max };
11104
+ }
10622
11105
  return { min, max };
10623
11106
  },
10624
11107
  // 判断滚动是否到达边界
@@ -10634,7 +11117,7 @@ const _sfc_main$2 = {
10634
11117
  currentData: this.visibleData[0],
10635
11118
  direction: "top"
10636
11119
  };
10637
- if (now - this.latestTopInfo.timestamp > oneMinute || JSON.stringify(data) !== JSON.stringify(this.latestTopInfo.data)) {
11120
+ if (now - this.latestTopInfo.timestamp > oneMinute || !this.isSameScrollEdgePayload(data, this.latestTopInfo.data)) {
10638
11121
  this.latestTopInfo = { data, timestamp: now };
10639
11122
  this.$emit("chart-scroll", data);
10640
11123
  }
@@ -10650,13 +11133,19 @@ const _sfc_main$2 = {
10650
11133
  currentData: this.visibleData[this.visibleData.length - 1],
10651
11134
  direction: "bottom"
10652
11135
  };
10653
- if (now - this.latestBottomInfo.timestamp > oneMinute || JSON.stringify(data) !== JSON.stringify(this.latestBottomInfo.data)) {
11136
+ if (now - this.latestBottomInfo.timestamp > oneMinute || !this.isSameScrollEdgePayload(data, this.latestBottomInfo.data)) {
10654
11137
  this.latestBottomInfo = { data, timestamp: now };
10655
11138
  this.$emit("chart-scroll", data);
10656
11139
  }
10657
11140
  }
10658
11141
  },
10659
- // 更新所有泳道的图表选项
11142
+ // 触顶/触底只比轴值,不要 JSON.stringify 整行。8.25
11143
+ isSameScrollEdgePayload(next, prev) {
11144
+ if (!next || !prev) return false;
11145
+ if (next.direction !== prev.direction) return false;
11146
+ const key = this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType] || this.formCache.axisType;
11147
+ return next.currentData && prev.currentData && next.currentData[key] === prev.currentData[key];
11148
+ },
10660
11149
  updateOptionsByLineId(lineId, option) {
10661
11150
  let index2 = this.allOptions.findIndex((lane) => lane.lineId == lineId);
10662
11151
  if (Object.prototype.hasOwnProperty.call(option, "xAxis") && option.xAxis.length === 0) {
@@ -10675,6 +11164,14 @@ const _sfc_main$2 = {
10675
11164
  });
10676
11165
  }
10677
11166
  this._pointerMetaGen++;
11167
+ this.flushLaneChartOption(lineId, cachedOption);
11168
+ },
11169
+ // skip-clone 浅监听可能不刷 series;对数切换时把 lg 数据直接打进图。8.24
11170
+ flushLaneChartOption(lineId, option) {
11171
+ const ref = this.getChartRefByLaneId(lineId);
11172
+ if (!ref || typeof ref.mergeOptions !== "function") return;
11173
+ if (!ref.chart || ref.chart.isDisposed()) return;
11174
+ ref.mergeOptions(option, true, false, true);
10678
11175
  },
10679
11176
  // 判断指定泳道是否应该显示tooltip内容
10680
11177
  // 地应力模式下:如果没有选中泳道,所有泳道正常显示;如果有选中泳道,只有选中的泳道显示
@@ -10696,7 +11193,6 @@ const _sfc_main$2 = {
10696
11193
  const chart = chartRef.chart;
10697
11194
  chart.setOption({
10698
11195
  tooltip: {
10699
- ...chart.getOption().tooltip,
10700
11196
  showContent: this.shouldShowTooltipContent(lane.laneId)
10701
11197
  }
10702
11198
  });
@@ -10726,6 +11222,77 @@ const _sfc_main$2 = {
10726
11222
  if (!Number.isFinite(min)) return { min: 0, max: 0 };
10727
11223
  return { min, max };
10728
11224
  },
11225
+ /** 井深/时间轴:没有有效轴值时不画 0、1 占位刻度。不改行数据。8.24 */
11226
+ isDepthOrTimeLane(lane) {
11227
+ if (!lane) return false;
11228
+ const axisTypeList = this.currentToolBarConfig.axisTypeList || {
11229
+ depth: "depth",
11230
+ time: "time"
11231
+ };
11232
+ return Object.prototype.hasOwnProperty.call(axisTypeList, "depth") && axisTypeList.depth == lane.laneKey || Object.prototype.hasOwnProperty.call(axisTypeList, "time") && axisTypeList.time == lane.laneKey;
11233
+ },
11234
+ dataZoomFilterModeForLane(lane) {
11235
+ if (!this.isGeomechanical) return "none";
11236
+ if (this.isDepthOrTimeLane(lane)) return "none";
11237
+ return "weakFilter";
11238
+ },
11239
+ shouldShowDepthAxisLabel(rows, axisKey) {
11240
+ if (!rows || !rows.length) return false;
11241
+ for (let i = 0; i < rows.length; i++) {
11242
+ if (Number.isFinite(Number(rows[i][axisKey]))) return true;
11243
+ }
11244
+ return false;
11245
+ },
11246
+ getDepthTimeLabelWidth(lane) {
11247
+ const mapped = Number(this.laneWidthMap && this.laneWidthMap[lane.laneId]);
11248
+ if (Number.isFinite(mapped) && mapped > 8) return mapped;
11249
+ const w = Number(lane && lane.width);
11250
+ if (Number.isFinite(w) && w > 8) return w;
11251
+ return 80;
11252
+ },
11253
+ // 井深/时间刻度与桌面 kd-curve-v3 一致:居中、按数据步长取间隔。8.25
11254
+ buildDepthTimeAxisLabel(lane, group, isTimeLane, dataGroups, groupIndex, groupMin, groupMax, axisKey) {
11255
+ const clientWidth = this.getDepthTimeLabelWidth(lane);
11256
+ const richWidth = Math.max(clientWidth - 6, 24);
11257
+ return {
11258
+ show: this.shouldShowDepthAxisLabel(group, axisKey),
11259
+ width: clientWidth,
11260
+ hideOverlap: true,
11261
+ height: 14,
11262
+ verticalAlign: "middle",
11263
+ color: getCssVariable("--default-text-color"),
11264
+ overflow: "truncate",
11265
+ rich: {
11266
+ center: {
11267
+ align: "center",
11268
+ fontSize: 12,
11269
+ verticalAlign: "middle",
11270
+ width: richWidth,
11271
+ height: 14,
11272
+ textBaseline: "middle",
11273
+ lineHeight: 14
11274
+ },
11275
+ center2: {
11276
+ align: "center",
11277
+ fontSize: 12,
11278
+ backgroundColor: "red",
11279
+ verticalAlign: "middle",
11280
+ width: richWidth,
11281
+ height: 14,
11282
+ textBaseline: "middle",
11283
+ lineHeight: 14
11284
+ }
11285
+ },
11286
+ formatter: this.getYAxisLabelFormatter(
11287
+ isTimeLane,
11288
+ dataGroups,
11289
+ groupIndex,
11290
+ groupMin,
11291
+ groupMax,
11292
+ axisKey
11293
+ )
11294
+ };
11295
+ },
10729
11296
  getGroupAxisExtents(groups, axisKey) {
10730
11297
  const extents = [];
10731
11298
  let totalRange = 0;
@@ -10737,6 +11304,64 @@ const _sfc_main$2 = {
10737
11304
  }
10738
11305
  return { extents, totalRange };
10739
11306
  },
11307
+ // 成图纸格:横竖同一虚线;竖向 5 等分,横向间距跟小格同宽(方格)。8.25
11308
+ getPaperXSplitCount() {
11309
+ return 5;
11310
+ },
11311
+ getChartPlotHeightPx() {
11312
+ const charts = typeof this.getConnectedCharts === "function" ? this.getConnectedCharts() : [];
11313
+ for (let i = 0; i < charts.length; i++) {
11314
+ const chart = charts[i];
11315
+ if (!chart || chart.isDisposed()) continue;
11316
+ const h = chart.getHeight && chart.getHeight();
11317
+ if (h > 40) return h;
11318
+ }
11319
+ const wrap = this.$refs.chartAreaWrap;
11320
+ if (wrap && wrap.clientHeight > 40) return wrap.clientHeight;
11321
+ return 400;
11322
+ },
11323
+ getTypicalCurveLaneWidthPx() {
11324
+ const map = this.laneWidthMap || {};
11325
+ const lanes = this.currentTemplate && this.currentTemplate.lanes || [];
11326
+ const widths = [];
11327
+ for (let i = 0; i < lanes.length; i++) {
11328
+ const lane = lanes[i];
11329
+ if (!lane || !lane.lines || !lane.lines.length) continue;
11330
+ const w = Number(map[lane.laneId]);
11331
+ if (Number.isFinite(w) && w > 60) widths.push(w);
11332
+ }
11333
+ if (!widths.length) return 200;
11334
+ widths.sort((a, b) => a - b);
11335
+ return widths[Math.floor(widths.length / 2)];
11336
+ },
11337
+ getYGridSplitCount() {
11338
+ const xSplits = this.getPaperXSplitCount();
11339
+ const h = this.getChartPlotHeightPx();
11340
+ const w = this.getTypicalCurveLaneWidthPx();
11341
+ const cell = Math.max(6, w / xSplits);
11342
+ return Math.max(8, Math.min(48, Math.round(h / cell)));
11343
+ },
11344
+ // 井深与横向虚线共用:按列高固定条数,缩放后仍铺满且一一对应。8.25
11345
+ getDepthLabelSplitCount(heightPx) {
11346
+ const h = Math.max(80, Number(heightPx) || this.getChartPlotHeightPx());
11347
+ return Math.max(8, Math.min(24, Math.floor(h / 18)));
11348
+ },
11349
+ getPaperGridAxisStyle(show = true, splitNumber = 5) {
11350
+ const color = getCssVariable("--kd-lane-container-item-line-color");
11351
+ const visible = !!show;
11352
+ return {
11353
+ splitNumber,
11354
+ minorTick: { show: false },
11355
+ minorSplitLine: { show: false },
11356
+ splitLine: {
11357
+ show: visible,
11358
+ showMinLine: false,
11359
+ showMaxLine: false,
11360
+ interval: 0,
11361
+ lineStyle: { color, type: "dashed", width: 1 }
11362
+ }
11363
+ };
11364
+ },
10740
11365
  computeUnifiedAxisInterval(groups, axisKey) {
10741
11366
  let total = 0;
10742
11367
  let min = Infinity;
@@ -10749,10 +11374,34 @@ const _sfc_main$2 = {
10749
11374
  if (e.max > max) max = e.max;
10750
11375
  }
10751
11376
  const range = max - min;
11377
+ const splits = this.getYGridSplitCount();
10752
11378
  if (!Number.isFinite(range) || range <= 0) return 5;
10753
11379
  if (this.isGeomechanical || total > 4e3) {
10754
- return range / 10;
11380
+ return range / splits;
11381
+ }
11382
+ let minStep = Infinity;
11383
+ for (let g = 0; g < groups.length; g++) {
11384
+ const group = groups[g];
11385
+ let prev = NaN;
11386
+ for (let i = 0; i < group.length; i++) {
11387
+ const v = Number(group[i][axisKey]);
11388
+ if (!Number.isFinite(v)) continue;
11389
+ if (Number.isFinite(prev)) {
11390
+ const step = Math.abs(v - prev);
11391
+ if (step > 0 && step < minStep) minStep = step;
11392
+ }
11393
+ prev = v;
11394
+ }
10755
11395
  }
11396
+ if (!Number.isFinite(minStep) || minStep <= 0) return range / 10;
11397
+ const intervalCount = Math.max(1, Math.min(12, Math.ceil(range / minStep)));
11398
+ let unified = Math.ceil(range / Math.min(12, intervalCount));
11399
+ return Math.max(minStep, Math.ceil(unified / minStep) * minStep);
11400
+ },
11401
+ // 与桌面 kd-curve-v3 井深轴相同:按最小数据步长、最多 12 段。8.25
11402
+ computeDepthTimeAxisInterval(groups, axisKey) {
11403
+ let min = Infinity;
11404
+ let max = -Infinity;
10756
11405
  let minStep = Infinity;
10757
11406
  for (let g = 0; g < groups.length; g++) {
10758
11407
  const group = groups[g];
@@ -10760,6 +11409,8 @@ const _sfc_main$2 = {
10760
11409
  for (let i = 0; i < group.length; i++) {
10761
11410
  const v = Number(group[i][axisKey]);
10762
11411
  if (!Number.isFinite(v)) continue;
11412
+ if (v < min) min = v;
11413
+ if (v > max) max = v;
10763
11414
  if (Number.isFinite(prev)) {
10764
11415
  const step = Math.abs(v - prev);
10765
11416
  if (step > 0 && step < minStep) minStep = step;
@@ -10767,24 +11418,66 @@ const _sfc_main$2 = {
10767
11418
  prev = v;
10768
11419
  }
10769
11420
  }
11421
+ const range = max - min;
11422
+ if (!Number.isFinite(range) || range <= 0) return 5;
10770
11423
  if (!Number.isFinite(minStep) || minStep <= 0) return range / 10;
10771
11424
  const intervalCount = Math.max(1, Math.min(12, Math.ceil(range / minStep)));
10772
11425
  let unified = Math.ceil(range / Math.min(12, intervalCount));
10773
11426
  return Math.max(minStep, Math.ceil(unified / minStep) * minStep);
10774
11427
  },
10775
- buildInsideDataZoom(moveOnMouseMove) {
11428
+ buildInsideDataZoom(moveOnMouseMove, filterMode) {
10776
11429
  const pan = moveOnMouseMove === void 0 ? this.isGeomechanical && !this._chartPanLocked : !!moveOnMouseMove;
11430
+ const mode = filterMode == null ? this.isGeomechanical ? "weakFilter" : "none" : filterMode;
10777
11431
  return {
10778
11432
  type: "inside",
10779
11433
  orient: "vertical",
10780
- filterMode: "none",
11434
+ // 视窗外的点不画;x 轴仍用表头 min/max,不会跟着被滤掉的点跑偏。8.25
11435
+ filterMode: mode,
10781
11436
  disabled: !this.isGeomechanical,
10782
11437
  zoomOnMouseWheel: true,
10783
11438
  moveOnMouseMove: pan,
10784
11439
  moveOnMouseWheel: false,
10785
- throttle: this.isGeomechanical ? 50 : 100
11440
+ throttle: this.isGeomechanical ? 16 : 100
11441
+ // 地应力跟手;过大 throttle 会拖影。8.25
10786
11442
  };
10787
11443
  },
11444
+ splitPlotDataByGaps(data) {
11445
+ if (!data || !data.length) return [data || []];
11446
+ const segs = [];
11447
+ let cur = [];
11448
+ for (let i = 0; i < data.length; i++) {
11449
+ const pt = data[i];
11450
+ const x = Array.isArray(pt) ? pt[0] : pt && pt.value && pt.value[0];
11451
+ if (isMissingCurveValue(x)) {
11452
+ if (cur.length) {
11453
+ segs.push(cur);
11454
+ cur = [];
11455
+ }
11456
+ } else {
11457
+ cur.push(pt);
11458
+ }
11459
+ }
11460
+ if (cur.length) segs.push(cur);
11461
+ return segs.length ? segs : [[]];
11462
+ },
11463
+ pushGeoLineSeries(option, baseSeries, seriesSource) {
11464
+ const segs = this.splitPlotDataByGaps(seriesSource);
11465
+ const canSplit = this.isGeomechanical && segs.length > 1 && segs.length <= 24;
11466
+ const chunks = canSplit ? segs : [seriesSource];
11467
+ for (let i = 0; i < chunks.length; i++) {
11468
+ const chunk = chunks[i];
11469
+ const series = i === 0 ? Object.assign(baseSeries, { data: chunk }) : {
11470
+ ...baseSeries,
11471
+ data: chunk,
11472
+ markLine: void 0,
11473
+ markArea: void 0,
11474
+ areaStyle: void 0,
11475
+ tooltip: { show: false }
11476
+ };
11477
+ this.applyGeoLineDrawOption(series, chunk && chunk.length || 0);
11478
+ option.series.push(series);
11479
+ }
11480
+ },
10788
11481
  applyGeoLineDrawOption(series, pointCount) {
10789
11482
  if (!this.isGeomechanical || !series) return series;
10790
11483
  series.clip = true;
@@ -10799,11 +11492,16 @@ const _sfc_main$2 = {
10799
11492
  itemStyle: { opacity: 1 }
10800
11493
  };
10801
11494
  series.select = { disabled: true };
11495
+ series.connectNulls = false;
10802
11496
  const area = series.areaStyle;
10803
11497
  const filled = area && Number(area.opacity) > 0;
10804
- if (pointCount >= 2e3 && !filled) {
11498
+ const hasGap = Array.isArray(series.data) && series.data.some((pt) => {
11499
+ const x = Array.isArray(pt) ? pt[0] : pt && pt.value && pt.value[0];
11500
+ return isMissingCurveValue(x);
11501
+ });
11502
+ if (pointCount >= 400 && !filled && !hasGap) {
10805
11503
  series.large = true;
10806
- series.largeThreshold = 2e3;
11504
+ series.largeThreshold = 400;
10807
11505
  series.symbol = "none";
10808
11506
  }
10809
11507
  return series;
@@ -10812,16 +11510,39 @@ const _sfc_main$2 = {
10812
11510
  const h = this.$refs.chartContainer && this.$refs.chartContainer.getLaneHeightPx && this.$refs.chartContainer.getLaneHeightPx() || 400;
10813
11511
  return getSeriesDrawThreshold(h);
10814
11512
  },
10815
- /** 地应力全量进图不抽稀;其它模式只抽稀进图点。8.24 */
11513
+ /** 地应力也只画窗口抽稀点;数值仍从原始行取。8.24 */
10816
11514
  plotSeriesForDraw(data, isLogScale) {
10817
11515
  const plotted = this.plotSeries(data, isLogScale);
10818
- if (this.isGeomechanical) return plotted;
10819
11516
  return downsampleSeriesForDraw(plotted, this.getSeriesDrawThreshold());
10820
11517
  },
11518
+ /** 该道进图点:开了对数就用 lg 后的 X。8.24 */
11519
+ toDrawSeriesData(lane, rawPoints) {
11520
+ return this.plotSeriesForDraw(rawPoints, isLaneLogScale(lane));
11521
+ },
11522
+ getAxisDataKey() {
11523
+ return this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType] || (this.formCache.axisType === "time" ? "time" : "depth");
11524
+ },
10821
11525
  findRowByAxisValue(axisValue) {
10822
- const key = this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType] || (this.formCache.axisType === "time" ? "time" : "depth");
11526
+ const key = this.getAxisDataKey();
10823
11527
  return findNearestRow(this.visibleData, key, axisValue) || findNearestRow(this.realTimeData, key, axisValue);
10824
11528
  },
11529
+ // 十字线标签用最近一条井深/时间,不要用像素反算的长小数。8.25
11530
+ formatAxisPointerYLabel(axisValue, row) {
11531
+ try {
11532
+ const hit = row || this.findRowByAxisValue(axisValue);
11533
+ if (this.formCache.axisType == "time") {
11534
+ const t = hit && (hit.time != null ? hit.time : hit.timestamp);
11535
+ return this.timestampToYMDHMS(t != null ? t : axisValue);
11536
+ }
11537
+ const key = this.getAxisDataKey();
11538
+ const raw = hit && hit[key] != null ? hit[key] : axisValue;
11539
+ const n = Number(raw);
11540
+ if (!Number.isFinite(n)) return "";
11541
+ return String(Number(n.toFixed(3)));
11542
+ } catch (e) {
11543
+ return "";
11544
+ }
11545
+ },
10825
11546
  readChartGridCount(option) {
10826
11547
  const grid = option && option.grid;
10827
11548
  if (Array.isArray(grid)) return grid.length;
@@ -10882,7 +11603,7 @@ const _sfc_main$2 = {
10882
11603
  const ref = this.getChartRefByLaneId(lanes[i].laneId);
10883
11604
  const chart = ref && ref.chart;
10884
11605
  if (!chart || chart.isDisposed()) continue;
10885
- const gridCount = this.readChartGridCount(chart.getOption() || {});
11606
+ const gridCount = this.readGridCount(chart);
10886
11607
  if (!gridCount || gridCount !== groups.length) {
10887
11608
  if (!this.isUpdatingChart) this.updateLanesChartOption();
10888
11609
  return;
@@ -10893,19 +11614,27 @@ const _sfc_main$2 = {
10893
11614
  const ref = this.getChartRefByLaneId(lane.laneId);
10894
11615
  const chart = ref && ref.chart;
10895
11616
  if (!chart || chart.isDisposed()) return;
10896
- const option = chart.getOption() || {};
11617
+ let seriesList = [];
11618
+ try {
11619
+ seriesList = chart.getModel().getSeries() || [];
11620
+ } catch (e) {
11621
+ return;
11622
+ }
10897
11623
  const isLog = isLaneLogScale(lane);
10898
11624
  const yAxis = groups.map((g) => ({ min: g.min, max: g.max }));
10899
- const series = (option.series || []).map((s) => {
10900
- const gi = this.clampGridIndex(groups.length, this.seriesYAxisIndex(s));
11625
+ const series = seriesList.map((sm) => {
11626
+ const opt = sm && sm.option || {};
11627
+ const gi = this.clampGridIndex(groups.length, this.seriesYAxisIndex(opt));
10901
11628
  const group = groups[gi];
10902
- const name = Array.isArray(s.name) ? s.name[0] : s.name;
11629
+ const name = this.unwrapEchartsValue(sm && sm.name);
10903
11630
  if (name === "helper") {
10904
- const x = s.data && s.data[0] && s.data[0][0];
11631
+ const data2 = opt.data;
11632
+ const x = data2 && data2[0] && data2[0][0];
10905
11633
  return { data: [[x, group.min], [x, group.max]] };
10906
11634
  }
10907
- if (name === "log-grid" || s.type !== "line") return {};
10908
- const paramId = Array.isArray(s.paramId) ? s.paramId[0] : s.paramId;
11635
+ const type = sm.subType || this.unwrapEchartsValue(opt.type);
11636
+ if (name === "log-grid" || type !== "line") return {};
11637
+ const paramId = this.unwrapEchartsValue(opt.paramId);
10909
11638
  if (paramId == null) return {};
10910
11639
  const cacheKey = `${gi}:${paramId}:${isLog ? 1 : 0}`;
10911
11640
  let data = groupSeriesCache.get(cacheKey);
@@ -10916,7 +11645,10 @@ const _sfc_main$2 = {
10916
11645
  axisKey,
10917
11646
  paramCodeMap
10918
11647
  );
10919
- data = downsampleSeriesForDraw(this.plotSeries(raw, isLog), threshold);
11648
+ data = downsampleSeriesForDraw(
11649
+ this.plotSeries(raw, isLog),
11650
+ threshold
11651
+ );
10920
11652
  groupSeriesCache.set(cacheKey, data);
10921
11653
  }
10922
11654
  return { data };
@@ -11001,8 +11733,10 @@ const _sfc_main$2 = {
11001
11733
  },
11002
11734
  // 处理鼠标滚轮事件
11003
11735
  handleWheel(e) {
11004
- if (this.trendLineManager) this.trendLineManager.scheduleZoomRender();
11005
- if (this.isGeomechanical) return;
11736
+ if (this.isGeomechanical) {
11737
+ this.startChartZoom();
11738
+ return;
11739
+ }
11006
11740
  e.preventDefault();
11007
11741
  const dataLength = this.realTimeData && this.realTimeData.length || 0;
11008
11742
  this.wheelDelta = Math.sign(e.deltaY);
@@ -11073,7 +11807,7 @@ const _sfc_main$2 = {
11073
11807
  let markLineYValues = [];
11074
11808
  const firstChart = this.getConnectedCharts()[0];
11075
11809
  if (firstChart) {
11076
- const chartOption = firstChart.getOption();
11810
+ const chartOption = this.readChartOptionRefs(firstChart);
11077
11811
  if (chartOption && chartOption.series) {
11078
11812
  chartOption.series.forEach((series) => {
11079
11813
  if (series.markLine && series.markLine.data) {
@@ -11270,28 +12004,29 @@ const _sfc_main$2 = {
11270
12004
  const newItems = newData.filter(
11271
12005
  (item) => !existingKeys.has(item[axisKey])
11272
12006
  );
11273
- this.realTimeData = [...this.realTimeData, ...newItems];
12007
+ const merged = [...this.realTimeData, ...newItems];
11274
12008
  if (axisType === "depth") {
11275
- if (this.realTimeData[0] && this.realTimeData[0].timestamp) {
11276
- this.realTimeData.sort((a, b) => {
12009
+ if (merged[0] && merged[0].timestamp) {
12010
+ merged.sort((a, b) => {
11277
12011
  const timestampA = this.toMillisecondTimestamp(a.timestamp);
11278
12012
  const timestampB = this.toMillisecondTimestamp(b.timestamp);
11279
12013
  return timestampA - timestampB;
11280
12014
  });
11281
12015
  } else {
11282
- this.realTimeData.sort((a, b) => {
12016
+ merged.sort((a, b) => {
11283
12017
  const valA = Number(a[axisKey]);
11284
12018
  const valB = Number(b[axisKey]);
11285
12019
  return valA - valB;
11286
12020
  });
11287
12021
  }
11288
12022
  } else {
11289
- this.realTimeData.sort((a, b) => {
12023
+ merged.sort((a, b) => {
11290
12024
  const valA = Number(a[axisKey]);
11291
12025
  const valB = Number(b[axisKey]);
11292
12026
  return valA - valB;
11293
12027
  });
11294
12028
  }
12029
+ this.realTimeData = markRaw(merged);
11295
12030
  let targetStartValue = Number(startValue);
11296
12031
  if (axisType !== "depth") {
11297
12032
  const str = String(targetStartValue);
@@ -11418,16 +12153,8 @@ const _sfc_main$2 = {
11418
12153
  type: "value",
11419
12154
  inverse: true,
11420
12155
  boundaryGap: false,
11421
- scale: true,
11422
- splitLine: {
11423
- show: true,
11424
- showMinLine: false,
11425
- showMaxLine: false,
11426
- lineStyle: {
11427
- color: getCssVariable("--kd-lane-container-item-line-color"),
11428
- type: "dashed"
11429
- }
11430
- },
12156
+ scale: false,
12157
+ ...this.getPaperGridAxisStyle(true, this.getYGridSplitCount()),
11431
12158
  axisLine: {
11432
12159
  show: false,
11433
12160
  onZero: false
@@ -11470,24 +12197,7 @@ const _sfc_main$2 = {
11470
12197
  backgroundColor: `${getCssVariable("--kd-lane-container-border-color")}99`,
11471
12198
  color: `${getCssVariable("--default-text-color")}`,
11472
12199
  show: true,
11473
- formatter: (params) => {
11474
- var _a;
11475
- try {
11476
- if (this.formCache.displayType == "header") {
11477
- const firstItem = this.getFirstDataIndexItem(
11478
- params && params.seriesData
11479
- );
11480
- this.headerData = ((_a = firstItem == null ? void 0 : firstItem.data) == null ? void 0 : _a.rowData) || this.findRowByAxisValue(params && params.value) || {};
11481
- }
11482
- if (params == null || params.value == null) return "";
11483
- if (this.formCache.axisType == "time") {
11484
- return this.timestampToYMDHMS(params.value);
11485
- }
11486
- return String(params.value);
11487
- } catch (e) {
11488
- return "";
11489
- }
11490
- }
12200
+ formatter: () => this._lastTooltipAxisLabel || ""
11491
12201
  }
11492
12202
  },
11493
12203
  confine: true,
@@ -11496,65 +12206,7 @@ const _sfc_main$2 = {
11496
12206
  textStyle: {
11497
12207
  color: getCssVariable("--default-text-color")
11498
12208
  },
11499
- formatter: (series) => {
11500
- if (!series || !Array.isArray(series)) return "";
11501
- const uniqueMap = /* @__PURE__ */ new Map();
11502
- for (let i = 0; i < series.length; i++) {
11503
- const current = series[i];
11504
- if (!current || current.seriesName === "helper") continue;
11505
- const existingItem = uniqueMap.get(current.seriesName);
11506
- if (!existingItem) {
11507
- uniqueMap.set(current.seriesName, current);
11508
- continue;
11509
- }
11510
- const existingValue = Array.isArray(existingItem.value) ? existingItem.value[0] : existingItem.value;
11511
- const currentValue = Array.isArray(current.value) ? current.value[0] : current.value;
11512
- const existingHasValue = existingValue !== void 0 && existingValue !== null && existingValue !== "";
11513
- const currentHasValue = currentValue !== void 0 && currentValue !== null && currentValue !== "";
11514
- if (!existingHasValue && currentHasValue) {
11515
- continue;
11516
- }
11517
- if (existingHasValue && !currentHasValue) {
11518
- uniqueMap.set(current.seriesName, current);
11519
- } else if (existingHasValue && currentHasValue) {
11520
- if (Number(currentValue) > Number(existingValue)) {
11521
- uniqueMap.set(current.seriesName, current);
11522
- }
11523
- } else {
11524
- uniqueMap.set(current.seriesName, current);
11525
- }
11526
- }
11527
- const uniqueSeries = [];
11528
- uniqueMap.forEach((item) => uniqueSeries.push(item));
11529
- if (this.tooltipFormatter && typeof this.tooltipFormatter === "function") {
11530
- let mousePositionData = null;
11531
- if (uniqueSeries.length > 0) {
11532
- const firstItem = this.getFirstDataIndexItem(uniqueSeries);
11533
- const tip = firstItem || uniqueSeries[0];
11534
- const axisVal = Array.isArray(tip && tip.value) ? tip.value[1] : tip && tip.axisValue;
11535
- mousePositionData = firstItem && firstItem.data && firstItem.data.rowData || this.findRowByAxisValue(
11536
- Number.isFinite(Number(axisVal)) ? axisVal : this._lastTooltipY
11537
- ) || {};
11538
- } else if (this._lastTooltipY != null) {
11539
- mousePositionData = this.findRowByAxisValue(this._lastTooltipY) || {};
11540
- }
11541
- return this.tooltipFormatter({
11542
- series: uniqueSeries,
11543
- mousePositionData
11544
- });
11545
- }
11546
- let html = "<div>";
11547
- for (let i = 0; i < uniqueSeries.length; i++) {
11548
- const params = uniqueSeries[i];
11549
- const { seriesName, value, color } = params;
11550
- let xValue = value;
11551
- if (Array.isArray(value)) xValue = value[0];
11552
- const text = xValue == void 0 || xValue == null ? `${seriesName}:--` : `${seriesName}:${typeof +xValue === "number" ? Number(Number(xValue).toFixed(3)) : xValue}`;
11553
- html += `<div style="display:flex;align-items:center"><div style="height:10px;width:10px;font-size:10px;border-radius:8px;background-color:${color}"></div><span style="margin-left:8px;font-size:12px">${text}</span></div>`;
11554
- }
11555
- html += "</div>";
11556
- return html;
11557
- }
12209
+ formatter: () => this.renderLaneTooltipHtml(this._tooltipLaneId)
11558
12210
  }
11559
12211
  };
11560
12212
  return option;
@@ -11624,6 +12276,7 @@ const _sfc_main$2 = {
11624
12276
  dataIndexMap.set(String(realTimeData[i][axisKey]), realTimeData[i]);
11625
12277
  }
11626
12278
  try {
12279
+ this._laneHasValidPoint = /* @__PURE__ */ Object.create(null);
11627
12280
  for (let laneIndex = 0; laneIndex < lanes.length; laneIndex++) {
11628
12281
  const lane = lanes[laneIndex];
11629
12282
  const axisTypeList = this.currentToolBarConfig.axisTypeList || {
@@ -11633,11 +12286,15 @@ const _sfc_main$2 = {
11633
12286
  const isDepthLane = Object.prototype.hasOwnProperty.call(axisTypeList, "depth") && axisTypeList.depth == lane.laneKey;
11634
12287
  const isTimeLane = Object.prototype.hasOwnProperty.call(axisTypeList, "time") && axisTypeList.time == lane.laneKey;
11635
12288
  const option = this.getDefaultLaneChartOption();
12289
+ if (isDepthLane || isTimeLane) {
12290
+ if (option.dataZoom && option.dataZoom[0]) {
12291
+ option.dataZoom[0].filterMode = "none";
12292
+ }
12293
+ }
11636
12294
  let hasValidLineData = false;
11637
12295
  const seriesDataCache = {};
11638
12296
  if (lane && lane.lines && lane.lines.length > 0) {
11639
12297
  for (const lineInfo of lane.lines) {
11640
- if (lineInfo.isUsed !== "1") continue;
11641
12298
  const seriesData = this.generateSeriesDataCached(
11642
12299
  realTimeData,
11643
12300
  lineInfo,
@@ -11646,9 +12303,7 @@ const _sfc_main$2 = {
11646
12303
  );
11647
12304
  seriesDataCache[lineInfo.lineId] = { full: seriesData };
11648
12305
  if (!hasValidLineData) {
11649
- hasValidLineData = seriesData.some(
11650
- (point) => point[0] !== null && point[0] !== void 0 && point[0] !== ""
11651
- );
12306
+ hasValidLineData = this.seriesDataHasValidX(seriesData);
11652
12307
  }
11653
12308
  if (lineInfo.recommendParamId) {
11654
12309
  const recommendLineInfo = {
@@ -11665,13 +12320,14 @@ const _sfc_main$2 = {
11665
12320
  full: recommendSeriesData
11666
12321
  };
11667
12322
  if (!hasValidLineData) {
11668
- hasValidLineData = recommendSeriesData.some(
11669
- (point) => point[0] !== null && point[0] !== void 0 && point[0] !== ""
12323
+ hasValidLineData = this.seriesDataHasValidX(
12324
+ recommendSeriesData
11670
12325
  );
11671
12326
  }
11672
12327
  }
11673
12328
  }
11674
12329
  }
12330
+ this._laneHasValidPoint[lane.laneId] = hasValidLineData;
11675
12331
  if (dataGroups.length > 0) {
11676
12332
  option.yAxis = [];
11677
12333
  option.series = [];
@@ -11701,9 +12357,12 @@ const _sfc_main$2 = {
11701
12357
  right: 2,
11702
12358
  height: `${groupHeight}%`,
11703
12359
  show: false,
11704
- containLabel: true
12360
+ containLabel: !!(isDepthLane || isTimeLane)
12361
+ // 井深列给刻度留宽,和桌面版一致。8.25
11705
12362
  });
11706
12363
  currentTop += groupHeight;
12364
+ const groupPlotH = this.getChartPlotHeightPx() * (groupHeight / 100);
12365
+ const ySplitCount = this.isGeomechanical ? this.getDepthLabelSplitCount(groupPlotH) : this.getYGridSplitCount();
11707
12366
  option.yAxis.push({
11708
12367
  gridIndex,
11709
12368
  type: "value",
@@ -11711,17 +12370,11 @@ const _sfc_main$2 = {
11711
12370
  max: groupMax,
11712
12371
  inverse: true,
11713
12372
  boundaryGap: false,
11714
- splitLine: {
11715
- show: true,
11716
- showMinLine: false,
11717
- showMaxLine: false,
11718
- lineStyle: {
11719
- color: getCssVariable(
11720
- "--kd-lane-container-item-line-color"
11721
- ),
11722
- type: "dashed"
11723
- }
11724
- },
12373
+ scale: false,
12374
+ ...this.getPaperGridAxisStyle(
12375
+ !isDepthLane && !isTimeLane,
12376
+ ySplitCount
12377
+ ),
11725
12378
  axisLine: { show: false, onZero: false },
11726
12379
  axisTick: { show: false },
11727
12380
  axisLabel: {
@@ -11731,13 +12384,16 @@ const _sfc_main$2 = {
11731
12384
  },
11732
12385
  axisPointer: { show: hasValidLineData }
11733
12386
  });
11734
- if (dataGroups.length > 1) {
11735
- option.yAxis[gridIndex].interval = unifiedInterval;
12387
+ if (this.isGeomechanical) {
12388
+ option.yAxis[gridIndex].splitNumber = ySplitCount;
12389
+ option.yAxis[gridIndex].minInterval = 1;
12390
+ option.yAxis[gridIndex].alignTicks = true;
12391
+ } else if (isDepthLane || isTimeLane) {
12392
+ option.yAxis[gridIndex].interval = this.computeDepthTimeAxisInterval(dataGroups, axisKey);
11736
12393
  } else {
11737
- option.yAxis[gridIndex].splitNumber = 15;
12394
+ option.yAxis[gridIndex].interval = unifiedInterval;
11738
12395
  }
11739
12396
  if (isDepthLane || isTimeLane) {
11740
- const clientWidth = this.laneWidthMap && this.laneWidthMap[lane.laneId];
11741
12397
  option.xAxis.push({
11742
12398
  gridIndex,
11743
12399
  type: "value",
@@ -11752,52 +12408,33 @@ const _sfc_main$2 = {
11752
12408
  type: "line",
11753
12409
  xAxisIndex: option.xAxis.length - 1,
11754
12410
  yAxisIndex: gridIndex,
12411
+ name: "helper",
11755
12412
  nameIndex: groupIndex,
11756
- data: []
12413
+ data: [
12414
+ [0, groupMin],
12415
+ [0, groupMax]
12416
+ ],
12417
+ symbol: "none",
12418
+ silent: true,
12419
+ tooltip: { show: false },
12420
+ lineStyle: { opacity: 0 }
11757
12421
  });
11758
12422
  Object.assign(option.yAxis[gridIndex], {
11759
12423
  splitLine: { show: false },
12424
+ minorSplitLine: { show: false },
11760
12425
  axisPointer: { show: false },
11761
12426
  alignTicks: true,
11762
12427
  boundaryGap: false,
11763
- axisLabel: {
11764
- show: true,
11765
- width: clientWidth,
11766
- hideOverlap: true,
11767
- height: 14,
11768
- verticalAlign: "middle",
11769
- color: getCssVariable("--default-text-color"),
11770
- overflow: "truncate",
11771
- rich: {
11772
- center: {
11773
- align: "center",
11774
- fontSize: 12,
11775
- verticalAlign: "middle",
11776
- width: clientWidth - 6,
11777
- height: 14,
11778
- textBaseline: "middle",
11779
- lineHeight: 14
11780
- },
11781
- center2: {
11782
- align: "center",
11783
- fontSize: 12,
11784
- backgroundColor: "red",
11785
- verticalAlign: "middle",
11786
- width: clientWidth - 6,
11787
- height: 14,
11788
- textBaseline: "middle",
11789
- lineHeight: 14
11790
- }
11791
- },
11792
- formatter: this.getYAxisLabelFormatter(
11793
- isTimeLane,
11794
- dataGroups,
11795
- groupIndex,
11796
- groupMin,
11797
- groupMax,
11798
- axisKey
11799
- )
11800
- }
12428
+ axisLabel: this.buildDepthTimeAxisLabel(
12429
+ lane,
12430
+ group,
12431
+ isTimeLane,
12432
+ dataGroups,
12433
+ groupIndex,
12434
+ groupMin,
12435
+ groupMax,
12436
+ axisKey
12437
+ )
11801
12438
  });
11802
12439
  option.backgroundColor = "transparent";
11803
12440
  delete option.tooltip;
@@ -11854,28 +12491,22 @@ const _sfc_main$2 = {
11854
12491
  }),
11855
12492
  show: !isDepthLane
11856
12493
  } : {
11857
- interval: (max - min) / 5,
11858
- splitNumber: 5,
12494
+ interval: (max - min) / this.getPaperXSplitCount(),
11859
12495
  gridIndex,
11860
12496
  show: !isDepthLane,
11861
12497
  type: "value",
11862
12498
  min,
11863
12499
  max,
11864
- splitLine: {
11865
- show: !isDepthLane,
11866
- showMaxLine: false,
11867
- showMinLine: false,
11868
- lineStyle: {
11869
- color: splitColor,
11870
- type: "dashed"
11871
- }
11872
- },
12500
+ ...this.getPaperGridAxisStyle(
12501
+ !isDepthLane && index2 === 0,
12502
+ this.getPaperXSplitCount()
12503
+ ),
11873
12504
  axisLabel: { show: false },
11874
12505
  axisLine: { show: false },
11875
12506
  axisTick: { show: false }
11876
12507
  }
11877
12508
  );
11878
- const seriesSource = lineInfo.isUsed === "1" ? this.plotSeriesForDraw(groupSeriesData, isLogScale) : [];
12509
+ const seriesSource = lineInfo.isUsed === "1" ? this.toDrawSeriesData(lane, groupSeriesData) : [];
11879
12510
  const baseSeries = {
11880
12511
  laneId: lineInfo.paramId,
11881
12512
  paramId: lineInfo.paramId,
@@ -11893,6 +12524,7 @@ const _sfc_main$2 = {
11893
12524
  type: lineInfo.lineType
11894
12525
  },
11895
12526
  clip: true,
12527
+ connectNulls: false,
11896
12528
  z: lineInfo.lineSort
11897
12529
  };
11898
12530
  if (lane.lines.length - 1 == index2) {
@@ -11931,8 +12563,7 @@ const _sfc_main$2 = {
11931
12563
  max,
11932
12564
  isLogScale
11933
12565
  );
11934
- this.applyGeoLineDrawOption(baseSeries, seriesSource.length);
11935
- option.series.push(baseSeries);
12566
+ this.pushGeoLineSeries(option, baseSeries, seriesSource);
11936
12567
  if (rangeAreaSeries) {
11937
12568
  option.series.push(rangeAreaSeries);
11938
12569
  }
@@ -11975,7 +12606,7 @@ const _sfc_main$2 = {
11975
12606
  axisKey,
11976
12607
  paramCodeMap
11977
12608
  );
11978
- const recommendSource = lineInfo.recommendIsUsed === "1" || lineInfo.recommendIsUsed == 1 ? this.plotSeriesForDraw(recommendGroupSeriesData, isLogScale) : [];
12609
+ const recommendSource = lineInfo.recommendIsUsed === "1" || lineInfo.recommendIsUsed == 1 ? this.toDrawSeriesData(lane, recommendGroupSeriesData) : [];
11979
12610
  const recommendSeries = {
11980
12611
  laneId: lineInfo.recommendParamId,
11981
12612
  data: recommendSource,
@@ -11990,13 +12621,10 @@ const _sfc_main$2 = {
11990
12621
  type: "dashed"
11991
12622
  },
11992
12623
  clip: true,
12624
+ connectNulls: false,
11993
12625
  z: lineInfo.lineSort
11994
12626
  };
11995
- this.applyGeoLineDrawOption(
11996
- recommendSeries,
11997
- recommendSource.length
11998
- );
11999
- option.series.push(recommendSeries);
12627
+ this.pushGeoLineSeries(option, recommendSeries, recommendSource);
12000
12628
  }
12001
12629
  const effectScatterPoint = this.latestLineDataByParamCode[lineInfo.paramId];
12002
12630
  if (effectScatterPoint && lineInfo.latestDataTips) {
@@ -12051,25 +12679,27 @@ const _sfc_main$2 = {
12051
12679
  }).filter(
12052
12680
  (v) => v !== void 0 && v !== null && !Number.isNaN(v)
12053
12681
  );
12682
+ let helperX = 0;
12054
12683
  if (rangeMins.length > 0) {
12055
- const min = Math.max(...rangeMins);
12056
- const helperX = isLogScale ? Math.log10(this.getLaneLogPlotRange(lane).min) : min;
12057
- option.series.unshift({
12058
- name: "helper",
12059
- type: "line",
12060
- xAxisIndex: option.xAxis.length - 1,
12061
- yAxisIndex: gridIndex,
12062
- data: [
12063
- [helperX, groupMin],
12064
- [helperX, groupMax]
12065
- ],
12066
- lineStyle: { opacity: 0 },
12067
- symbol: "none",
12068
- silent: true,
12069
- // 禁用鼠标事件
12070
- tooltip: { show: false }
12071
- });
12684
+ helperX = isLogScale ? Math.log10(this.getLaneLogPlotRange(lane).min) : Math.max(...rangeMins);
12685
+ } else if (isLogScale) {
12686
+ helperX = Math.log10(this.getLaneLogPlotRange(lane).min);
12072
12687
  }
12688
+ if (!Number.isFinite(helperX)) helperX = 0;
12689
+ option.series.unshift({
12690
+ name: "helper",
12691
+ type: "line",
12692
+ xAxisIndex: option.xAxis.length - 1,
12693
+ yAxisIndex: gridIndex,
12694
+ data: [
12695
+ [helperX, groupMin],
12696
+ [helperX, groupMax]
12697
+ ],
12698
+ lineStyle: { opacity: 0 },
12699
+ symbol: "none",
12700
+ silent: true,
12701
+ tooltip: { show: true }
12702
+ });
12073
12703
  if (isLogScale) {
12074
12704
  option.series.unshift(
12075
12705
  this.getLogPaperGridSeries(
@@ -12083,12 +12713,12 @@ const _sfc_main$2 = {
12083
12713
  }
12084
12714
  }
12085
12715
  if (option.tooltip && lane && lane.lines && lane.lines.length) {
12086
- option.tooltip.showContent = this.shouldShowTooltipContent(
12087
- lane.laneId
12088
- );
12716
+ const laneId = lane.laneId;
12717
+ option.tooltip.showContent = this.shouldShowTooltipContent(laneId);
12089
12718
  option.tooltip.triggerOn = "none";
12090
12719
  option.tooltip.enterable = false;
12091
12720
  option.tooltip.extraCssText = "pointer-events: none !important;";
12721
+ option.tooltip.formatter = () => this.renderLaneTooltipHtml(laneId);
12092
12722
  }
12093
12723
  this.updateOptionsByLineId(lane.laneId, option);
12094
12724
  }
@@ -12162,6 +12792,108 @@ const _sfc_main$2 = {
12162
12792
  output.push(data[dataLength - 1]);
12163
12793
  return output;
12164
12794
  },
12795
+ formatTooltipXValue(raw) {
12796
+ if (this.isMissingTooltipValue(raw)) return "--";
12797
+ return Number(Number(raw).toFixed(3));
12798
+ },
12799
+ getLineThemeColor(lineInfo) {
12800
+ if (!lineInfo) return "";
12801
+ if (lineInfo.themeConfig && lineInfo.themeConfig[this.nowTheme]) {
12802
+ if (lineInfo.isGradient && this.linearGradientLineColor && this.linearGradientLineColor[this.nowTheme] && this.linearGradientLineColor[this.nowTheme][lineInfo.paramId]) {
12803
+ return this.linearGradientLineColor[this.nowTheme][lineInfo.paramId];
12804
+ }
12805
+ return lineInfo.themeConfig[this.nowTheme].lineColor;
12806
+ }
12807
+ return lineInfo.lineColor || "";
12808
+ },
12809
+ getTooltipLineName(lineInfo, isRecommend) {
12810
+ if (isRecommend) return "推荐值";
12811
+ if (lineInfo && lineInfo.recommendParamId) return "实际值";
12812
+ const param = (this.params || []).find(
12813
+ (p) => p.paramId == (lineInfo && lineInfo.paramId)
12814
+ );
12815
+ if (param && param.paramName) {
12816
+ return `${param.paramName}${param.paramUnit ? `(${param.paramUnit})` : ""}`;
12817
+ }
12818
+ return lineInfo && (lineInfo.paramName || String(lineInfo.paramId)) || "";
12819
+ },
12820
+ readLineValueFromRow(row, paramId) {
12821
+ if (!row || paramId == null) return null;
12822
+ if (paramId in row) return row[paramId];
12823
+ const strId = String(paramId);
12824
+ if (strId in row) return row[strId];
12825
+ const currentParam = (this.params || []).find((p) => p.paramId == paramId);
12826
+ if (currentParam && currentParam.paramCode) {
12827
+ const codes = String(currentParam.paramCode).split(",");
12828
+ for (let i = 0; i < codes.length; i++) {
12829
+ const code = codes[i];
12830
+ if (code && code in row) return row[code];
12831
+ }
12832
+ }
12833
+ return null;
12834
+ },
12835
+ formatTooltipLineDisplayValue(raw, isLogScale) {
12836
+ if (this.isMissingTooltipValue(raw)) return "--";
12837
+ if (isLogScale) {
12838
+ const lg = formatLanePointValue(raw);
12839
+ return lg == null ? "--" : lg;
12840
+ }
12841
+ return this.formatTooltipXValue(raw);
12842
+ },
12843
+ buildLaneTooltipSeries(lane, row, yValue) {
12844
+ const lines = lane && lane.lines || [];
12845
+ const isLogScale = isLaneLogScale(lane);
12846
+ const items = [];
12847
+ for (let i = 0; i < lines.length; i++) {
12848
+ const lineInfo = lines[i];
12849
+ const raw = this.readLineValueFromRow(row, lineInfo.paramId);
12850
+ items.push({
12851
+ seriesName: this.getTooltipLineName(lineInfo, false),
12852
+ color: this.getLineThemeColor(lineInfo),
12853
+ value: [this.formatTooltipLineDisplayValue(raw, isLogScale), yValue],
12854
+ paramId: lineInfo.paramId,
12855
+ lineId: lineInfo.lineId
12856
+ });
12857
+ if (lineInfo.recommendParamId) {
12858
+ const recRaw = this.readLineValueFromRow(
12859
+ row,
12860
+ lineInfo.recommendParamId
12861
+ );
12862
+ items.push({
12863
+ seriesName: this.getTooltipLineName(lineInfo, true),
12864
+ color: this.getLineThemeColor(lineInfo),
12865
+ value: [
12866
+ this.formatTooltipLineDisplayValue(recRaw, isLogScale),
12867
+ yValue
12868
+ ],
12869
+ paramId: lineInfo.recommendParamId,
12870
+ lineId: lineInfo.lineId
12871
+ });
12872
+ }
12873
+ }
12874
+ return items;
12875
+ },
12876
+ renderLaneTooltipHtml(laneId) {
12877
+ const yValue = this._lastTooltipY;
12878
+ const lane = this.findLaneById(laneId);
12879
+ const row = yValue != null ? this.findRowByAxisValue(yValue) || {} : {};
12880
+ const displaySeries = this.buildLaneTooltipSeries(lane, row, yValue);
12881
+ if (this.tooltipFormatter && typeof this.tooltipFormatter === "function") {
12882
+ return this.tooltipFormatter({
12883
+ series: displaySeries,
12884
+ mousePositionData: row
12885
+ });
12886
+ }
12887
+ let html = "<div>";
12888
+ for (let i = 0; i < displaySeries.length; i++) {
12889
+ const params = displaySeries[i];
12890
+ const { seriesName, value, color } = params;
12891
+ const xValue = Array.isArray(value) ? value[0] : value;
12892
+ html += `<div style="display:flex;align-items:center"><div style="height:10px;width:10px;font-size:10px;border-radius:8px;background-color:${color}"></div><span style="margin-left:8px;font-size:12px">${seriesName}:${xValue}</span></div>`;
12893
+ }
12894
+ html += "</div>";
12895
+ return html;
12896
+ },
12165
12897
  // 生成泳道图表数据
12166
12898
  generateSeriesData(data, lineInfo, axisKey) {
12167
12899
  return data.map((item) => {
@@ -12182,6 +12914,7 @@ const _sfc_main$2 = {
12182
12914
  }
12183
12915
  }
12184
12916
  }
12917
+ if (isMissingCurveValue(value)) value = null;
12185
12918
  return [value, +item[axisKey], item.timestamp];
12186
12919
  });
12187
12920
  },
@@ -12200,6 +12933,7 @@ const _sfc_main$2 = {
12200
12933
  }
12201
12934
  }
12202
12935
  }
12936
+ if (isMissingCurveValue(value)) value = null;
12203
12937
  return [value, +item[axisKey], item.timestamp];
12204
12938
  });
12205
12939
  },
@@ -12218,6 +12952,7 @@ const _sfc_main$2 = {
12218
12952
  }
12219
12953
  }
12220
12954
  }
12955
+ if (isMissingCurveValue(value)) value = null;
12221
12956
  return {
12222
12957
  value: [value, +item[axisKey]],
12223
12958
  rowData: item
@@ -12323,7 +13058,7 @@ const _sfc_main$2 = {
12323
13058
  }
12324
13059
  }
12325
13060
  const chart = chartRef.chart;
12326
- const option = chart.getOption();
13061
+ const option = this.readChartOptionRefs(chart);
12327
13062
  const pointInPixel = [
12328
13063
  e.offsetX || ((_a = e.event) == null ? void 0 : _a.offsetX),
12329
13064
  e.offsetY || ((_b = e.event) == null ? void 0 : _b.offsetY)
@@ -12495,10 +13230,10 @@ const _sfc_main$2 = {
12495
13230
  const filteredPoints = points.filter((point) => {
12496
13231
  if (this.formCache.axisType === "depth" && point.timestamp !== void 0 && point.timestamp !== null) {
12497
13232
  const pointY = point.value[1];
12498
- let findItem = this.visibleData.find(
13233
+ const findItem = this.visibleData.find(
12499
13234
  (d) => d[axisKey] == pointY && d.timestamp == point.timestamp
12500
- ) || {};
12501
- if (JSON.stringify(findItem) == "{}") {
13235
+ );
13236
+ if (!findItem) {
12502
13237
  return false;
12503
13238
  }
12504
13239
  return true;
@@ -12516,7 +13251,7 @@ const _sfc_main$2 = {
12516
13251
  borderWidth: 2
12517
13252
  }
12518
13253
  }));
12519
- const option = chart.getOption();
13254
+ const option = this.readChartOptionRefs(chart);
12520
13255
  const existingIndex = option.series.findIndex(
12521
13256
  (s) => s.id === "selectedPointScatter"
12522
13257
  );
@@ -12613,7 +13348,7 @@ const _sfc_main$2 = {
12613
13348
  e.offsetX || ((_a = e.event) == null ? void 0 : _a.offsetX),
12614
13349
  e.offsetY || ((_b = e.event) == null ? void 0 : _b.offsetY)
12615
13350
  ];
12616
- const option = chart.getOption();
13351
+ const option = this.readChartOptionRefs(chart);
12617
13352
  let clickedPoint = null;
12618
13353
  let minDistance = 15;
12619
13354
  for (let i = 0; i < option.series.length; i++) {
@@ -12761,7 +13496,6 @@ const _sfc_main$2 = {
12761
13496
  findMarkAreaByPoint(point, laneId) {
12762
13497
  const chartRef = this.getChartRefByLaneId(laneId);
12763
13498
  if (!chartRef || !chartRef.chart) return -1;
12764
- chartRef.chart.getOption();
12765
13499
  const yValue = point.value[1];
12766
13500
  for (let i = 0; i < this.markAreaLineData.length; i++) {
12767
13501
  const area = this.markAreaLineData[i];
@@ -13481,7 +14215,7 @@ const _sfc_main$2 = {
13481
14215
  const chartRef = this.getChartRefByLaneId(lane.laneId);
13482
14216
  if (!chartRef || !chartRef.chart) continue;
13483
14217
  const chart = chartRef.chart;
13484
- const currentOption = chart.getOption();
14218
+ const currentOption = this.readChartOptionRefs(chart);
13485
14219
  const axisTypeList = this.currentToolBarConfig.axisTypeList || {
13486
14220
  depth: "depth",
13487
14221
  time: "time"
@@ -13518,13 +14252,15 @@ const _sfc_main$2 = {
13518
14252
  right: 2,
13519
14253
  height: `${groupHeight}%`,
13520
14254
  show: false,
13521
- containLabel: false
14255
+ containLabel: !!isDepthLane
13522
14256
  };
13523
14257
  const currentGrid = currentOption.grid && currentOption.grid[gridIndex];
13524
14258
  if (!currentGrid || currentGrid.top !== gridItem.top || currentGrid.height !== gridItem.height) {
13525
14259
  needUpdate.grid = true;
13526
14260
  }
13527
14261
  newGrid.push(gridItem);
14262
+ const groupPlotH = this.getChartPlotHeightPx() * (groupHeight / 100);
14263
+ const ySplitCount = this.isGeomechanical ? this.getDepthLabelSplitCount(groupPlotH) : this.getYGridSplitCount();
13528
14264
  const yAxisItem = {
13529
14265
  gridIndex,
13530
14266
  type: "value",
@@ -13532,10 +14268,39 @@ const _sfc_main$2 = {
13532
14268
  max: groupMax,
13533
14269
  inverse: true,
13534
14270
  boundaryGap: false,
13535
- interval: unifiedInterval
14271
+ scale: false,
14272
+ ...this.getPaperGridAxisStyle(
14273
+ !isDepthLane,
14274
+ ySplitCount
14275
+ )
13536
14276
  };
14277
+ if (this.isGeomechanical) {
14278
+ yAxisItem.splitNumber = ySplitCount;
14279
+ yAxisItem.minInterval = 1;
14280
+ yAxisItem.alignTicks = true;
14281
+ } else if (isDepthLane) {
14282
+ yAxisItem.interval = this.computeDepthTimeAxisInterval(
14283
+ dataGroups,
14284
+ axisKey
14285
+ );
14286
+ } else {
14287
+ yAxisItem.interval = unifiedInterval;
14288
+ }
14289
+ if (isDepthLane) {
14290
+ yAxisItem.alignTicks = true;
14291
+ yAxisItem.axisLabel = this.buildDepthTimeAxisLabel(
14292
+ lane,
14293
+ group,
14294
+ false,
14295
+ dataGroups,
14296
+ groupIndex,
14297
+ groupMin,
14298
+ groupMax,
14299
+ axisKey
14300
+ );
14301
+ }
13537
14302
  const currentYAxis = currentOption.yAxis && currentOption.yAxis[gridIndex];
13538
- if (!currentYAxis || currentYAxis.min !== groupMin || currentYAxis.max !== groupMax || currentYAxis.interval !== unifiedInterval) {
14303
+ if (!currentYAxis || currentYAxis.min !== groupMin || currentYAxis.max !== groupMax) {
13539
14304
  needUpdate.yAxis = true;
13540
14305
  }
13541
14306
  newYAxis.push(yAxisItem);
@@ -13591,7 +14356,7 @@ const _sfc_main$2 = {
13591
14356
  lineInfo,
13592
14357
  axisKey
13593
14358
  );
13594
- const finalSeriesData = lineInfo.isUsed === "1" ? this.plotSeriesForDraw(seriesData, isLogScale) : [];
14359
+ const finalSeriesData = lineInfo.isUsed === "1" ? this.toDrawSeriesData(lane, seriesData) : [];
13595
14360
  needUpdate.series = true;
13596
14361
  newSeriesData.push({
13597
14362
  index: seriesIndex,
@@ -13787,7 +14552,7 @@ const _sfc_main$2 = {
13787
14552
  deduplicateByUniqueKey(existingData, newData, uniqueKey, options = {}) {
13788
14553
  const { sortOrder = "asc", isSort = true } = options;
13789
14554
  const newDataArr = Array.isArray(newData) ? newData : [newData];
13790
- let resultData = JSON.parse(JSON.stringify(existingData));
14555
+ const resultData = Array.isArray(existingData) ? existingData.slice() : [];
13791
14556
  const existingKeys = new Set(resultData.map((item) => item[uniqueKey]));
13792
14557
  newDataArr.forEach((newItem) => {
13793
14558
  if (!newItem || !newItem[uniqueKey]) return;
@@ -14066,7 +14831,7 @@ const _sfc_main$2 = {
14066
14831
  this.realTimeData = [];
14067
14832
  this.visibleData = [];
14068
14833
  if (!this.initialRealTimeData || !this.initialRealTimeData.data) {
14069
- this.initialRealTimeData = newVal || {};
14834
+ this.initialRealTimeData = markRaw(newVal || {});
14070
14835
  }
14071
14836
  let processedData = newVal && newVal.data || [];
14072
14837
  if (this.formCache.axisType == "time") {
@@ -14097,13 +14862,13 @@ const _sfc_main$2 = {
14097
14862
  await this.$nextTick();
14098
14863
  this.updateLanesChartOption();
14099
14864
  } else if (newVal.type === "supplementaryData") {
14100
- let data = cloneDeep(newVal && newVal.data) || [];
14865
+ let data = newVal && newVal.data || [];
14101
14866
  if (!Array.isArray(data)) {
14102
14867
  data = [data];
14103
14868
  }
14104
14869
  this.handleDataLoaded(data);
14105
14870
  } else if (newVal.type === "updateData") {
14106
- let data = cloneDeep(newVal && newVal.data) || [];
14871
+ let data = newVal && newVal.data || [];
14107
14872
  if (!Array.isArray(data)) {
14108
14873
  data = [data];
14109
14874
  }
@@ -14159,7 +14924,7 @@ const _sfc_main$2 = {
14159
14924
  this.updateLanesChartOption();
14160
14925
  } else {
14161
14926
  console.log(newVal, "newVal");
14162
- let data = cloneDeep(newVal && newVal.data) || [];
14927
+ let data = newVal && newVal.data || [];
14163
14928
  if (!Array.isArray(data)) {
14164
14929
  data = [data];
14165
14930
  }
@@ -14170,10 +14935,12 @@ const _sfc_main$2 = {
14170
14935
  ...item,
14171
14936
  [axisKey]: this.toMillisecondTimestamp(item[axisKey])
14172
14937
  }));
14173
- this.realTimeData = this.deduplicateByUniqueKey(
14174
- this.realTimeData,
14175
- data,
14176
- this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType]
14938
+ this.realTimeData = markRaw(
14939
+ this.deduplicateByUniqueKey(
14940
+ this.realTimeData,
14941
+ data,
14942
+ this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType]
14943
+ )
14177
14944
  );
14178
14945
  } else {
14179
14946
  data = data.map((item) => ({
@@ -14181,14 +14948,18 @@ const _sfc_main$2 = {
14181
14948
  timestamp: this.toMillisecondTimestamp(item.timestamp)
14182
14949
  }));
14183
14950
  if (direction === "top") {
14184
- this.realTimeData = this.uniqueByKeys(
14185
- [...data, ...this.realTimeData],
14186
- "timestamp"
14951
+ this.realTimeData = markRaw(
14952
+ this.uniqueByKeys(
14953
+ [...data, ...this.realTimeData],
14954
+ "timestamp"
14955
+ )
14187
14956
  );
14188
14957
  } else {
14189
- this.realTimeData = this.uniqueByKeys(
14190
- [...this.realTimeData, ...data],
14191
- "timestamp"
14958
+ this.realTimeData = markRaw(
14959
+ this.uniqueByKeys(
14960
+ [...this.realTimeData, ...data],
14961
+ "timestamp"
14962
+ )
14192
14963
  );
14193
14964
  }
14194
14965
  }
@@ -14206,8 +14977,7 @@ const _sfc_main$2 = {
14206
14977
  }
14207
14978
  }
14208
14979
  },
14209
- immediate: true,
14210
- deep: true
14980
+ immediate: true
14211
14981
  }
14212
14982
  }
14213
14983
  };
@@ -14283,7 +15053,7 @@ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
14283
15053
  placement: "top"
14284
15054
  }, null, 8, ["min", "max"])) : createCommentVNode("", true),
14285
15055
  (openBlock(), createBlock(_component_resizeEcharts, {
14286
- key: lane.laneId,
15056
+ key: $options.chartLaneKey(lane),
14287
15057
  ref: (el) => $options.setChartRef(lane.laneId, el),
14288
15058
  autoresize: "",
14289
15059
  options: $options.getOptionsByLineId(lane.laneId),
@@ -14328,7 +15098,7 @@ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
14328
15098
  placement: "top"
14329
15099
  }, null, 8, ["min", "max"])) : createCommentVNode("", true),
14330
15100
  (openBlock(), createBlock(_component_resizeEcharts, {
14331
- key: lane.laneId,
15101
+ key: $options.chartLaneKey(lane),
14332
15102
  ref: (el) => $options.setChartRef(lane.laneId, el),
14333
15103
  autoresize: "",
14334
15104
  options: $options.getOptionsByLineId(lane.laneId),
@@ -14397,7 +15167,7 @@ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
14397
15167
  ])
14398
15168
  ], 544);
14399
15169
  }
14400
- const chartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2], ["__scopeId", "data-v-5da40120"]]);
15170
+ const chartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2], ["__scopeId", "data-v-22f7e692"]]);
14401
15171
  const _sfc_main$1 = {
14402
15172
  name: "ParameterPanel",
14403
15173
  props: {
@@ -15030,6 +15800,16 @@ const faultParameters = [
15030
15800
  paramId: ["8034"]
15031
15801
  }
15032
15802
  ];
15803
+ function holdCurveDatas(val) {
15804
+ if (!val || typeof val !== "object") {
15805
+ return markRaw({ data: markRaw([]) });
15806
+ }
15807
+ const data = Array.isArray(val.data) ? val.data : [];
15808
+ return markRaw({
15809
+ ...val,
15810
+ data: markRaw(data)
15811
+ });
15812
+ }
15033
15813
  const _sfc_main = {
15034
15814
  name: "frameLayout",
15035
15815
  components: {
@@ -15241,8 +16021,9 @@ const _sfc_main = {
15241
16021
  this.depthTimeChartData = this.WellBitDepthTimePlotConfig && this.WellBitDepthTimePlotConfig.data || [];
15242
16022
  this.initialFormCache = cloneDeep(this.currentToolBarConfig && this.currentToolBarConfig.form || {});
15243
16023
  this.formCache = cloneDeep(this.currentToolBarConfig && this.currentToolBarConfig.form || {});
15244
- this.cachedCurveDatas = cloneDeep(this.curveDatas || {});
15245
- this.initialCurveDatas = cloneDeep(this.curveDatas || {});
16024
+ this.cachedCurveDatas = holdCurveDatas(this.curveDatas);
16025
+ this.initialCurveDatas = holdCurveDatas(this.curveDatas);
16026
+ this._hasInitialCurveDatas = !!(this.curveDatas && this.curveDatas.type);
15246
16027
  let form = cloneDeep(this.currentToolBarConfig && this.currentToolBarConfig.form || {});
15247
16028
  const processedDepthConfig = this.processConfig(this.depthConfig);
15248
16029
  const processedTimeConfig = this.processConfig(this.timeConfig);
@@ -15379,13 +16160,24 @@ const _sfc_main = {
15379
16160
  this.containerWidth = this.$refs.container && this.$refs.container.offsetWidth || 800;
15380
16161
  this.initWidth();
15381
16162
  });
15382
- window.addEventListener("resize", () => {
16163
+ this._onWindowResize = () => {
15383
16164
  this.$nextTick(() => {
16165
+ if (this._isUnmounted) return;
15384
16166
  this.containerWidth = this.$refs.container && this.$refs.container.offsetWidth || 800;
15385
16167
  });
15386
- });
16168
+ };
16169
+ window.addEventListener("resize", this._onWindowResize);
15387
16170
  },
15388
16171
  methods: {
16172
+ // 延后显示图表;销毁时清掉,避免回调打到已卸载实例。8.24
16173
+ deferShowChart(fn) {
16174
+ if (this._showChartTimer) clearTimeout(this._showChartTimer);
16175
+ this._showChartTimer = setTimeout(() => {
16176
+ this._showChartTimer = null;
16177
+ if (this._isUnmounted) return;
16178
+ fn();
16179
+ }, 0);
16180
+ },
15389
16181
  // 处理单个对象,根据paramId匹配faultParameters并补充lineColor、max、min
15390
16182
  processSingleItem(item) {
15391
16183
  if (!item || !item.paramId) return;
@@ -15478,16 +16270,16 @@ const _sfc_main = {
15478
16270
  this.formCache = cloneDeep(this.initialFormCache);
15479
16271
  this.showChartContainer = false;
15480
16272
  this.enableCurveDatasWatch = false;
15481
- setTimeout(() => {
16273
+ this.deferShowChart(() => {
15482
16274
  const processedDepthConfig = this.processConfig(this.depthConfig);
15483
16275
  const processedTimeConfig = this.processConfig(this.timeConfig);
15484
16276
  this.config = this.formCache.axisType === "depth" ? processedDepthConfig : processedTimeConfig;
15485
16277
  if (JSON.stringify(this.config) !== "{}") {
15486
16278
  this.showChartContainer = true;
15487
16279
  }
15488
- this.cachedCurveDatas = cloneDeep(this.initialCurveDatas || {});
16280
+ this.cachedCurveDatas = this.initialCurveDatas;
15489
16281
  this.enableCurveDatasWatch = true;
15490
- }, 0);
16282
+ });
15491
16283
  },
15492
16284
  // 清空图表数据
15493
16285
  clearChartData() {
@@ -15534,14 +16326,14 @@ const _sfc_main = {
15534
16326
  }
15535
16327
  if (key === "axisType") {
15536
16328
  this.showChartContainer = false;
15537
- setTimeout(() => {
16329
+ this.deferShowChart(() => {
15538
16330
  const processedDepthConfig = this.processConfig(this.depthConfig);
15539
16331
  const processedTimeConfig = this.processConfig(this.timeConfig);
15540
16332
  this.config = this.formCache.axisType === "depth" ? processedDepthConfig : processedTimeConfig;
15541
16333
  if (JSON.stringify(this.config) !== "{}") {
15542
16334
  this.showChartContainer = true;
15543
16335
  }
15544
- }, 0);
16336
+ });
15545
16337
  this.$emit("updateSettings", { key, value, settings: cloneDeep(this.formCache) });
15546
16338
  }
15547
16339
  if (key === "dataType") {
@@ -15604,10 +16396,11 @@ const _sfc_main = {
15604
16396
  this.pendingEvent = e;
15605
16397
  if (!this.frameRequested) {
15606
16398
  this.frameRequested = true;
15607
- requestAnimationFrame(this.updateSize);
16399
+ this._panelResizeRaf = requestAnimationFrame(this.updateSize);
15608
16400
  }
15609
16401
  },
15610
16402
  updateSize() {
16403
+ this._panelResizeRaf = 0;
15611
16404
  const e = this.pendingEvent;
15612
16405
  if (!e) return;
15613
16406
  const dx = e.clientX - this.startX;
@@ -15670,10 +16463,19 @@ const _sfc_main = {
15670
16463
  this.isLoading = isLoading;
15671
16464
  }
15672
16465
  },
15673
- // 组件销毁时移除事件监听,防止内存泄漏
15674
16466
  beforeUnmount() {
16467
+ this._isUnmounted = true;
16468
+ window.removeEventListener("resize", this._onWindowResize);
15675
16469
  document.removeEventListener("mousemove", this.handleMove);
15676
16470
  document.removeEventListener("mouseup", this.stopResize);
16471
+ if (this._showChartTimer) {
16472
+ clearTimeout(this._showChartTimer);
16473
+ this._showChartTimer = null;
16474
+ }
16475
+ if (this._panelResizeRaf) {
16476
+ cancelAnimationFrame(this._panelResizeRaf);
16477
+ this._panelResizeRaf = 0;
16478
+ }
15677
16479
  },
15678
16480
  watch: {
15679
16481
  timeConfig: {
@@ -15682,9 +16484,9 @@ const _sfc_main = {
15682
16484
  this.showChartContainer = false;
15683
16485
  const processedConfig = this.processConfig(newVal);
15684
16486
  this.config = processedConfig;
15685
- setTimeout(() => {
16487
+ this.deferShowChart(() => {
15686
16488
  this.showChartContainer = true;
15687
- }, 0);
16489
+ });
15688
16490
  }
15689
16491
  },
15690
16492
  deep: true,
@@ -15699,9 +16501,9 @@ const _sfc_main = {
15699
16501
  this.showChartContainer = false;
15700
16502
  const processedConfig = this.processConfig(newVal);
15701
16503
  this.config = processedConfig;
15702
- setTimeout(() => {
16504
+ this.deferShowChart(() => {
15703
16505
  this.showChartContainer = true;
15704
- }, 0);
16506
+ });
15705
16507
  console.log(this.config, "depthConfig");
15706
16508
  }
15707
16509
  },
@@ -15732,23 +16534,22 @@ const _sfc_main = {
15732
16534
  deep: true,
15733
16535
  immediate: true
15734
16536
  },
15735
- // 监听curveDatas的变化
16537
+ // 只跟对象引用,不 deep 走进 markRaw 行数据。8.24
15736
16538
  curveDatas: {
15737
16539
  handler(newVal) {
15738
- if (this.enableCurveDatasWatch) {
15739
- if (JSON.stringify(this.initialCurveDatas) === "{}") {
15740
- this.initialCurveDatas = cloneDeep(newVal || {});
15741
- }
15742
- if (Object.prototype.hasOwnProperty.call(newVal, "dataType") && newVal.dataType !== this.formCache.dataType && newVal.dataType !== "" && newVal.dataType !== void 0 && newVal.dataType !== null) {
15743
- this.formCache.dataType = newVal.dataType;
15744
- if (this.$refs.functionControlPanel) {
15745
- this.$refs.functionControlPanel.form.dataType = newVal.dataType;
15746
- }
16540
+ if (!this.enableCurveDatasWatch || !newVal) return;
16541
+ if (!this._hasInitialCurveDatas && newVal.type) {
16542
+ this.initialCurveDatas = holdCurveDatas(newVal);
16543
+ this._hasInitialCurveDatas = true;
16544
+ }
16545
+ if (Object.prototype.hasOwnProperty.call(newVal, "dataType") && newVal.dataType !== this.formCache.dataType && newVal.dataType !== "" && newVal.dataType !== void 0 && newVal.dataType !== null) {
16546
+ this.formCache.dataType = newVal.dataType;
16547
+ if (this.$refs.functionControlPanel) {
16548
+ this.$refs.functionControlPanel.form.dataType = newVal.dataType;
15747
16549
  }
15748
- this.cachedCurveDatas = cloneDeep(newVal || {});
15749
16550
  }
15750
- },
15751
- deep: true
16551
+ this.cachedCurveDatas = holdCurveDatas(newVal);
16552
+ }
15752
16553
  },
15753
16554
  themeName: {
15754
16555
  handler(newVal) {
@@ -15881,7 +16682,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
15881
16682
  ])])) : createCommentVNode("", true)
15882
16683
  ]);
15883
16684
  }
15884
- const FrameLayoutComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-bc2030c8"]]);
16685
+ const FrameLayoutComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-76b2334b"]]);
15885
16686
  KdLaneContainerComponent.install = function(app) {
15886
16687
  app.component(KdLaneContainerComponent.name, KdLaneContainerComponent);
15887
16688
  };