kd-lane-chart-v3 0.1.6 → 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
@@ -2651,13 +2651,21 @@ function axisIndexOf$1(val) {
2651
2651
  return Number(n ?? 0);
2652
2652
  }
2653
2653
  function findLogTrendSeries(chart, paramId) {
2654
- const option = chart.getOption() || {};
2655
- return (option.series || []).find((s) => {
2656
- if (!s || s.type !== "line") return false;
2657
- const name = Array.isArray(s.name) ? s.name[0] : s.name;
2658
- if (name === "helper" || name === "log-grid") return false;
2659
- return String(s.paramId) === String(paramId);
2660
- }) || null;
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;
2661
2669
  }
2662
2670
  function pixelToLogTrendData(chart, paramId, offsetX, offsetY, lane, lineRange, digits = 3) {
2663
2671
  if (!chart || !isLaneLogScale(lane)) return null;
@@ -2986,7 +2994,11 @@ const _sfc_main$8 = {
2986
2994
  let max = -Infinity;
2987
2995
  let min = Infinity;
2988
2996
  for (let i = 0; i < data.length; i++) {
2989
- 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);
2990
3002
  if (!Number.isFinite(v)) continue;
2991
3003
  if (v > max) max = v;
2992
3004
  if (v < min) min = v;
@@ -3006,7 +3018,9 @@ const _sfc_main$8 = {
3006
3018
  return "--";
3007
3019
  }
3008
3020
  const raw = this.headerData[this.line.paramId];
3009
- if (raw === null || raw === void 0 || raw === "") return "--";
3021
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") {
3022
+ return "--";
3023
+ }
3010
3024
  if (isLogScaleFlag(this.isLogScale)) {
3011
3025
  const lg = formatLanePointValue(raw);
3012
3026
  return lg == null ? "--" : lg;
@@ -3127,7 +3141,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
3127
3141
  ])
3128
3142
  ], 6);
3129
3143
  }
3130
- const HeaderItem = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8], ["__scopeId", "data-v-466dec24"]]);
3144
+ const HeaderItem = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$8], ["__scopeId", "data-v-c4185947"]]);
3131
3145
  const _sfc_main$7 = {
3132
3146
  name: "LegendItem",
3133
3147
  props: {
@@ -3198,7 +3212,7 @@ const _sfc_main$7 = {
3198
3212
  return "--";
3199
3213
  }
3200
3214
  const raw = this.headerData[paramId];
3201
- if (raw === null || raw === void 0 || raw === "") return "--";
3215
+ if (raw === null || raw === void 0 || raw === "" || raw === "null") return "--";
3202
3216
  if (isLogScaleFlag(this.isLogScale)) {
3203
3217
  const lg = formatLanePointValue(raw);
3204
3218
  return lg == null ? "--" : lg;
@@ -3298,7 +3312,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
3298
3312
  ])
3299
3313
  ], 4);
3300
3314
  }
3301
- const LegendItem = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7], ["__scopeId", "data-v-41c24d2f"]]);
3315
+ const LegendItem = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$7], ["__scopeId", "data-v-9fa6fff3"]]);
3302
3316
  const TREND_LINE_STYLE = {
3303
3317
  stroke: "#FF9800",
3304
3318
  lineWidth: 2,
@@ -3649,25 +3663,74 @@ function seriesParamId(series) {
3649
3663
  function seriesDisplayName(series) {
3650
3664
  return optionScalar(series && series.name);
3651
3665
  }
3666
+ function chartModel(chart) {
3667
+ try {
3668
+ return chart && !chart.isDisposed() ? chart.getModel() : null;
3669
+ } catch (e) {
3670
+ return null;
3671
+ }
3672
+ }
3673
+ function modelGridCount(model) {
3674
+ if (!model) return 1;
3675
+ try {
3676
+ const list = model.queryComponents({ mainType: "grid" });
3677
+ if (list && list.length) return list.length;
3678
+ } catch (e) {
3679
+ }
3680
+ return 1;
3681
+ }
3682
+ function modelAxisOption(model, mainType, index2) {
3683
+ if (!model) return {};
3684
+ try {
3685
+ const comp = model.getComponent(mainType, index2);
3686
+ return comp && comp.option || {};
3687
+ } catch (e) {
3688
+ return {};
3689
+ }
3690
+ }
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
+ });
3710
+ }
3711
+ return out;
3712
+ } catch (e) {
3713
+ return [];
3714
+ }
3715
+ }
3652
3716
  function findSeriesForDepth(chart, paramId, depth) {
3653
- const option = chart.getOption() || {};
3654
- const series = option.series || [];
3655
- const yAxes = option.yAxis || [];
3717
+ const model = chartModel(chart);
3718
+ const series = listLineSeries(model);
3656
3719
  let fallback = null;
3657
3720
  for (let i = 0; i < series.length; i++) {
3658
3721
  const s = series[i];
3659
- if (!s || seriesTypeName(s) !== "line" || seriesDisplayName(s) === "helper") continue;
3660
- if (String(seriesParamId(s)) !== String(paramId)) continue;
3722
+ if (String(s.paramId) !== String(paramId)) continue;
3661
3723
  const info = {
3662
- seriesIndex: i,
3663
- xAxisIndex: axisIndexOf(s.xAxisIndex),
3664
- yAxisIndex: axisIndexOf(s.yAxisIndex)
3724
+ seriesIndex: s.seriesIndex,
3725
+ xAxisIndex: s.xAxisIndex,
3726
+ yAxisIndex: s.yAxisIndex
3665
3727
  };
3666
3728
  fallback = info;
3667
- const yAx = yAxes[info.yAxisIndex];
3668
- if (!yAx) continue;
3669
- const min = Math.min(Number(yAx.min), Number(yAx.max));
3670
- const max = Math.max(Number(yAx.min), Number(yAx.max));
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);
3671
3734
  if (Number.isFinite(depth) && depth >= min && depth <= max) return info;
3672
3735
  }
3673
3736
  return fallback || { seriesIndex: 0, xAxisIndex: 0, yAxisIndex: 0 };
@@ -3691,8 +3754,7 @@ function eventOffsetInChart(chart, evt) {
3691
3754
  return { offsetX, offsetY };
3692
3755
  }
3693
3756
  function isPointerInAnyGrid(chart, offsetX, offsetY) {
3694
- const option = chart.getOption() || {};
3695
- const gridCount = option.grid && option.grid.length || 1;
3757
+ const gridCount = modelGridCount(chartModel(chart));
3696
3758
  for (let i = 0; i < gridCount; i++) {
3697
3759
  try {
3698
3760
  if (chart.containPixel({ gridIndex: i }, [offsetX, offsetY])) return true;
@@ -3706,22 +3768,22 @@ function axisIndexOf(val) {
3706
3768
  return Number(n ?? 0);
3707
3769
  }
3708
3770
  function pixelToData(chart, paramId, offsetX, offsetY, loose = false) {
3709
- const option = chart.getOption() || {};
3710
- const gridCount = option.grid && option.grid.length || 1;
3711
- const matchParam = (s) => s && seriesTypeName(s) === "line" && seriesDisplayName(s) !== "helper" && String(seriesParamId(s)) === String(paramId);
3771
+ const model = chartModel(chart);
3772
+ const gridCount = modelGridCount(model);
3773
+ const matched = listLineSeries(model).filter(
3774
+ (s) => String(s.paramId) === String(paramId)
3775
+ );
3712
3776
  for (let g = 0; g < gridCount; g++) {
3713
3777
  try {
3714
3778
  if (!loose && !chart.containPixel({ gridIndex: g }, [offsetX, offsetY])) continue;
3715
- const seriesList = (option.series || []).filter(matchParam);
3716
- const series = seriesList.find((s) => axisIndexOf(s.yAxisIndex) === g) || seriesList[0];
3779
+ const series = matched.find((s) => s.yAxisIndex === g) || matched[0];
3717
3780
  const finders = [];
3718
3781
  if (series) {
3719
3782
  finders.push({
3720
- xAxisIndex: axisIndexOf(series.xAxisIndex),
3721
- yAxisIndex: axisIndexOf(series.yAxisIndex)
3783
+ xAxisIndex: series.xAxisIndex,
3784
+ yAxisIndex: series.yAxisIndex
3722
3785
  });
3723
- const seriesIndex = (option.series || []).indexOf(series);
3724
- if (seriesIndex >= 0) finders.push({ seriesIndex });
3786
+ if (series.seriesIndex >= 0) finders.push({ seriesIndex: series.seriesIndex });
3725
3787
  }
3726
3788
  finders.push({ gridIndex: g });
3727
3789
  for (const finder of finders) {
@@ -3784,14 +3846,14 @@ function snapDepthToEdge(depth, depthMin, depthMax, tol) {
3784
3846
  return Math.max(lo, Math.min(hi, d));
3785
3847
  }
3786
3848
  function getAxisRange(chart, paramId, depth) {
3787
- const option = chart.getOption() || {};
3849
+ const model = chartModel(chart);
3788
3850
  const finder = findSeriesForDepth(chart, paramId, depth);
3789
- const xAx = (option.xAxis || [])[finder.xAxisIndex] || {};
3790
- const yAx = (option.yAxis || [])[finder.yAxisIndex] || {};
3791
- const xMin = Number(xAx.min);
3792
- const xMax = Number(xAx.max);
3793
- const yMin = Number(yAx.min);
3794
- const yMax = Number(yAx.max);
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));
3795
3857
  return {
3796
3858
  valueMin: Number.isFinite(xMin) ? xMin : 0,
3797
3859
  valueMax: Number.isFinite(xMax) ? xMax : 100,
@@ -3813,6 +3875,7 @@ class TrendLineManager {
3813
3875
  this._zoomPending = false;
3814
3876
  this._zoomEndTimer = null;
3815
3877
  this._graphicIds = /* @__PURE__ */ Object.create(null);
3878
+ this._zrElCache = /* @__PURE__ */ new WeakMap();
3816
3879
  this._ignoreClickUntil = 0;
3817
3880
  }
3818
3881
  destroy() {
@@ -3930,10 +3993,13 @@ class TrendLineManager {
3930
3993
  zr.on("mousedown", onZrDown);
3931
3994
  zr.on("mousemove", onZrMove);
3932
3995
  zr.on("dblclick", onDblClick);
3933
- 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
+ };
3934
4002
  if (typeof chart.on === "function") chart.on("datazoom", onZoom);
3935
- chart.getZr().on("mousewheel", onZoom);
3936
- if (dom) dom.addEventListener("wheel", onZoom, { passive: true });
3937
4003
  this.binds.set(laneId, { chart, onMouseDown, onZrDown, onZrMove, onDblClick, onZoom, dom });
3938
4004
  this.updateCursor(laneId);
3939
4005
  }
@@ -3982,9 +4048,18 @@ class TrendLineManager {
3982
4048
  this.renderAll();
3983
4049
  });
3984
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
+ }
3985
4060
  /** 缩放过程用 ZR 就地改像素,结束后再整层重画,避免 replaceMerge 把线冲掉。8.22 */
3986
4061
  scheduleZoomRender() {
3987
- if (this.dragSession) return;
4062
+ if (this.dragSession || !this.hasAnyKnots()) return;
3988
4063
  this._zoomPending = true;
3989
4064
  if (this._zoomEndTimer) clearTimeout(this._zoomEndTimer);
3990
4065
  this._zoomEndTimer = setTimeout(() => {
@@ -4078,18 +4153,35 @@ class TrendLineManager {
4078
4153
  });
4079
4154
  return patches;
4080
4155
  }
4081
- _findGraphicZrEl(chart, id) {
4082
- let found = null;
4156
+ _invalidateZrElCache(chart) {
4157
+ if (chart && this._zrElCache) this._zrElCache.delete(chart);
4158
+ }
4159
+ _indexGraphicZrEls(chart, map) {
4083
4160
  const zr = chart.getZr();
4084
- if (!zr || !zr.storage || typeof zr.storage.traverse !== "function") return null;
4161
+ if (!zr || !zr.storage || typeof zr.storage.traverse !== "function") return;
4085
4162
  zr.storage.traverse((el) => {
4086
- if (found) return;
4087
4163
  const elId = el.id ?? el.anid ?? el.name ?? el.__ecGraphicId;
4088
- if (elId === id || String(elId) === String(id) || String(elId).endsWith(id)) {
4089
- found = el;
4090
- }
4164
+ if (elId == null) return;
4165
+ map.set(String(elId), el);
4091
4166
  });
4092
- 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;
4093
4185
  }
4094
4186
  _graphicPixel(el) {
4095
4187
  const cx = el.shape && el.shape.cx || 0;
@@ -4196,14 +4288,14 @@ class TrendLineManager {
4196
4288
  el.setShape(shape);
4197
4289
  applied += 1;
4198
4290
  });
4199
- if (applied > 0 && chart.getZr() && typeof chart.getZr().refreshImmediately === "function") {
4200
- chart.getZr().refreshImmediately();
4201
- }
4291
+ const zr = chart.getZr && chart.getZr();
4292
+ if (applied > 0 && zr && typeof zr.refresh === "function") zr.refresh();
4202
4293
  return applied > 0;
4203
4294
  }
4204
4295
  // 只 merge 新图形,不动已有线。8.24
4205
4296
  _addGraphicElements(chart, elements) {
4206
4297
  if (!elements.length) return;
4298
+ this._invalidateZrElCache(chart);
4207
4299
  chart.setOption(
4208
4300
  {
4209
4301
  graphic: elements.map((el) => ({ ...el, $action: "merge" }))
@@ -4214,6 +4306,7 @@ class TrendLineManager {
4214
4306
  // 按 id 删除,不 replaceMerge 整层 graphic。8.24
4215
4307
  _removeGraphicIds(chart, ids) {
4216
4308
  if (!ids.length) return;
4309
+ this._invalidateZrElCache(chart);
4217
4310
  chart.setOption(
4218
4311
  {
4219
4312
  graphic: ids.map((id) => ({ id, $action: "remove" }))
@@ -4415,6 +4508,9 @@ class TrendLineManager {
4415
4508
  /** 指针靠近控制点时先停地应力平移,按下时才来得及拖点。8.22 */
4416
4509
  onZrHover(e, laneId) {
4417
4510
  if (this.dragSession) return;
4511
+ if (this.host && typeof this.host.isChartBusy === "function" && this.host.isChartBusy()) {
4512
+ return;
4513
+ }
4418
4514
  const chart = this.getChart(laneId);
4419
4515
  const target = this.getTargetByLane(laneId);
4420
4516
  if (!chart || !target || !target.editable) {
@@ -7456,8 +7552,14 @@ const _sfc_main$5 = {
7456
7552
  ensureVisible() {
7457
7553
  const rows = this.resolvedRows;
7458
7554
  if (!rows.length) return;
7459
- const option = this.chart.getOption();
7460
- 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
+ })();
7461
7563
  if (!dz) return;
7462
7564
  const total = rows.length;
7463
7565
  const start = dz.start ?? 0;
@@ -7913,7 +8015,7 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
7913
8015
  ], 512)
7914
8016
  ], 512);
7915
8017
  }
7916
- const DepthTimeChart = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5], ["__scopeId", "data-v-9991a24b"]]);
8018
+ const DepthTimeChart = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5], ["__scopeId", "data-v-300010d5"]]);
7917
8019
  const curveExportIcon = "data:image/png;base64,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";
7918
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";
7919
8021
  const refreshIcon = "data:image/png;base64,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";
@@ -9173,27 +9275,31 @@ const _sfc_main$3 = {
9173
9275
  _saveDataZoomState() {
9174
9276
  if (!this.chart || this.chart.isDisposed()) return null;
9175
9277
  try {
9176
- const option = this.chart.getOption();
9177
- if (option && option.dataZoom && option.dataZoom.length > 0) {
9178
- return option.dataZoom.map((dz) => ({
9179
- start: dz.start,
9180
- end: dz.end,
9181
- startValue: dz.startValue,
9182
- endValue: dz.endValue
9183
- }));
9184
- }
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
+ });
9185
9290
  } catch (e) {
9291
+ return null;
9186
9292
  }
9187
- return null;
9188
9293
  },
9189
9294
  // notMerge 刷 option 时把当前趋势线 graphic 带回去,避免先消失再画。8.24
9190
9295
  _preserveGraphic(options) {
9191
9296
  if (!options || options.graphic || !this.chart || this.chart.isDisposed()) return;
9192
9297
  try {
9193
- const current = this.chart.getOption();
9194
- if (current && current.graphic && current.graphic.length) {
9195
- options.graphic = current.graphic;
9196
- }
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;
9197
9303
  } catch (e) {
9198
9304
  }
9199
9305
  },
@@ -9507,17 +9613,35 @@ const _hoisted_1$3 = { class: "echarts" };
9507
9613
  function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
9508
9614
  return openBlock(), createElementBlock("div", _hoisted_1$3);
9509
9615
  }
9510
- const resizeEcharts = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3], ["__scopeId", "data-v-8c9f410f"]]);
9616
+ const resizeEcharts = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3], ["__scopeId", "data-v-c1cce4a1"]]);
9511
9617
  const DRAW_POINT_MIN = 600;
9512
9618
  const DRAW_POINT_MAX = 1800;
9513
9619
  function getSeriesDrawThreshold(laneHeightPx) {
9514
9620
  const h = Number(laneHeightPx) || 400;
9515
9621
  return Math.max(DRAW_POINT_MIN, Math.min(DRAW_POINT_MAX, Math.round(h * 2)));
9516
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
+ }
9517
9640
  function getPointXY(pt) {
9518
- if (Array.isArray(pt)) return [Number(pt[0]), Number(pt[1])];
9519
- if (pt && Array.isArray(pt.value)) return [Number(pt.value[0]), Number(pt.value[1])];
9520
- 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)];
9521
9645
  }
9522
9646
  function lttb(data, threshold) {
9523
9647
  const n = data && data.length || 0;
@@ -9550,8 +9674,37 @@ function lttb(data, threshold) {
9550
9674
  return sampled;
9551
9675
  }
9552
9676
  function downsampleSeriesForDraw(data, threshold) {
9553
- if (!data || data.length <= threshold) return data || [];
9554
- 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;
9555
9708
  }
9556
9709
  function lowerBound(rows, key, target) {
9557
9710
  let lo = 0;
@@ -9868,16 +10021,34 @@ const _sfc_main$2 = {
9868
10021
  this._pointerMetaGen = 0;
9869
10022
  this._lastTipKey = /* @__PURE__ */ new WeakMap();
9870
10023
  this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10024
+ this._laneHasValidPoint = /* @__PURE__ */ Object.create(null);
9871
10025
  this._pendingPointer = null;
9872
10026
  this._pointerRaf = 0;
9873
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();
9874
10038
  this._flushPointerSync = () => {
9875
10039
  this._pointerRaf = 0;
9876
10040
  const pending = this._pendingPointer;
9877
10041
  if (!pending || !this.pointerInChartArea) return;
9878
- this._pendingPointer = null;
9879
10042
  const { chart, x, y } = pending;
9880
- 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;
9881
10052
  this.syncAxisPointerAcrossCharts(chart, x, y);
9882
10053
  };
9883
10054
  this.debounceJudgeEdge = debounce(() => {
@@ -9895,12 +10066,18 @@ const _sfc_main$2 = {
9895
10066
  ) && this.currentToolBarConfig.showDateTime == true;
9896
10067
  window.addEventListener("keydown", this.handleKeyDown);
9897
10068
  window.addEventListener("keyup", this.handleKeyUp);
10069
+ window.addEventListener("mouseup", this._onWindowMouseUp);
9898
10070
  this.showTooltip = this.formCache.displayType == "float";
9899
10071
  },
9900
10072
  beforeUnmount() {
9901
10073
  this._isUnmounted = true;
9902
10074
  window.removeEventListener("keydown", this.handleKeyDown);
9903
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
+ }
9904
10081
  if (this.trendLineManager) this.trendLineManager.destroy();
9905
10082
  if (this._pointerRaf) {
9906
10083
  cancelAnimationFrame(this._pointerRaf);
@@ -9919,6 +10096,7 @@ const _sfc_main$2 = {
9919
10096
  this.scheduleConnectAllCharts.cancel();
9920
10097
  }
9921
10098
  this._pendingPointer = null;
10099
+ this.attachChartConnect();
9922
10100
  this.unbindChartPointerSync();
9923
10101
  echarts.disConnect(this.group);
9924
10102
  this.clearEcharts();
@@ -9953,7 +10131,7 @@ const _sfc_main$2 = {
9953
10131
  chartLaneKey(lane) {
9954
10132
  return `${lane && lane.laneId}-${isLaneLogScale(lane) ? "log" : "lin"}`;
9955
10133
  },
9956
- // 整道 10 条竖线,样式跟普通泳道 splitLine 同一套。8.22对数轴
10134
+ // 对数竖格:整道 10 条同一虚线,和线性纸格一致。8.25
9957
10135
  getLogPaperGridSeries(lane, xAxisIndex, yAxisIndex) {
9958
10136
  const range = this.getLaneLogPlotRange(lane);
9959
10137
  const color = getCssVariable("--kd-lane-container-item-line-color");
@@ -9989,19 +10167,18 @@ const _sfc_main$2 = {
9989
10167
  },
9990
10168
  getLaneChartContentStyle(laneId) {
9991
10169
  const width = this.laneWidthMap && this.laneWidthMap[laneId];
9992
- const gap = this.currentHeaderStyle.itemGap || 0;
9993
10170
  const style = {};
9994
10171
  if (width && Number(width) > 0) {
9995
10172
  Object.assign(style, {
9996
10173
  width: `${width}px`,
9997
- padding: `0 ${gap}px`,
10174
+ padding: "0",
9998
10175
  height: "100%"
9999
10176
  });
10000
10177
  } else {
10001
10178
  Object.assign(style, {
10002
10179
  width: "100%",
10003
10180
  height: "100%",
10004
- padding: `0 ${gap}px`,
10181
+ padding: "0",
10005
10182
  flex: "1"
10006
10183
  });
10007
10184
  }
@@ -10052,8 +10229,14 @@ const _sfc_main$2 = {
10052
10229
  if (!this.isGeomechanical) return;
10053
10230
  this.getConnectedCharts().forEach((chart) => {
10054
10231
  if (!chart || chart.isDisposed()) return;
10232
+ const laneId = this.findLaneIdByChart(chart);
10055
10233
  chart.setOption({
10056
- dataZoom: [this.buildInsideDataZoom(!!enabled)]
10234
+ dataZoom: [
10235
+ this.buildInsideDataZoom(
10236
+ !!enabled,
10237
+ this.dataZoomFilterModeForLane(this.findLaneById(laneId))
10238
+ )
10239
+ ]
10057
10240
  });
10058
10241
  });
10059
10242
  },
@@ -10130,6 +10313,35 @@ const _sfc_main$2 = {
10130
10313
  }
10131
10314
  return 1;
10132
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
+ },
10133
10345
  readGridBounds(chart, gridIndex, width) {
10134
10346
  try {
10135
10347
  const gridModel = chart.getModel().getComponent("grid", gridIndex);
@@ -10173,7 +10385,15 @@ const _sfc_main$2 = {
10173
10385
  bottom: chart.getHeight && chart.getHeight() || 0
10174
10386
  };
10175
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
+ },
10176
10395
  collectTooltipSeries(chart, seriesByGrid) {
10396
+ let hasAnyValidPlotPoint = false;
10177
10397
  try {
10178
10398
  const seriesList = chart.getModel().getSeries();
10179
10399
  for (let s = 0; s < seriesList.length; s++) {
@@ -10196,9 +10416,13 @@ const _sfc_main$2 = {
10196
10416
  seriesIndex: sm.seriesIndex,
10197
10417
  data
10198
10418
  });
10419
+ if (!hasAnyValidPlotPoint) {
10420
+ hasAnyValidPlotPoint = this.seriesDataHasValidX(data);
10421
+ }
10199
10422
  }
10200
10423
  } catch (e) {
10201
10424
  }
10425
+ return hasAnyValidPlotPoint;
10202
10426
  },
10203
10427
  ensurePointerMeta(chart) {
10204
10428
  const width = chart.getWidth && chart.getWidth() || 0;
@@ -10214,14 +10438,18 @@ const _sfc_main$2 = {
10214
10438
  bounds[i] = this.readGridBounds(chart, i, width);
10215
10439
  seriesByGrid[i] = [];
10216
10440
  }
10217
- this.collectTooltipSeries(chart, seriesByGrid);
10441
+ const hasAnyValidPlotPoint = this.collectTooltipSeries(
10442
+ chart,
10443
+ seriesByGrid
10444
+ );
10218
10445
  meta = {
10219
10446
  gen: this._pointerMetaGen,
10220
10447
  width,
10221
10448
  height,
10222
10449
  gridCount,
10223
10450
  bounds,
10224
- seriesByGrid
10451
+ seriesByGrid,
10452
+ hasAnyValidPlotPoint
10225
10453
  };
10226
10454
  this._pointerMeta.set(chart, meta);
10227
10455
  return meta;
@@ -10288,18 +10516,32 @@ const _sfc_main$2 = {
10288
10516
  const item = Array.isArray(tip) ? tip[0] : tip;
10289
10517
  return !!(item && item.show === false);
10290
10518
  },
10291
- // 对数轴曲线 X 用 lg(x);轴是线性 lg 量程,允许负数。不改原始行。8.24
10519
+ // 对数轴曲线 X 用 lg(x);缺数保持 null,不能 Number(null) 成 0。8.25
10292
10520
  plotX(raw, isLogScale) {
10521
+ if (isMissingCurveValue(raw)) return null;
10293
10522
  return isLogScale ? toLogPlotX(raw) : raw;
10294
10523
  },
10295
10524
  plotSeries(data, isLogScale) {
10296
- 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
+ });
10297
10541
  },
10298
10542
  // null / '' 不能当有数:Number(null) === 0,会误打到空的第一条线。8.22
10299
10543
  isValidTooltipX(raw) {
10300
- if (raw === null || raw === void 0 || raw === "") return false;
10301
- const n = Number(raw);
10302
- return Number.isFinite(n);
10544
+ return !isMissingCurveValue(raw);
10303
10545
  },
10304
10546
  pointY(pt) {
10305
10547
  if (Array.isArray(pt)) return Number(pt[1]);
@@ -10380,6 +10622,73 @@ const _sfc_main$2 = {
10380
10622
  }
10381
10623
  return best;
10382
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;
10691
+ },
10383
10692
  onChartAreaMouseMove(event) {
10384
10693
  const charts = this.getConnectedCharts();
10385
10694
  for (let i = 0; i < charts.length; i++) {
@@ -10424,51 +10733,56 @@ const _sfc_main$2 = {
10424
10733
  this.showSyncedLaneTooltips(hit.yValue, offsetY, hit.gridIndex);
10425
10734
  },
10426
10735
  showSyncedLaneTooltips(yValue, fallbackY, gridIndex) {
10427
- const charts = this.getConnectedCharts();
10736
+ if (this.isChartBusy() || this._showingTips) return;
10737
+ this._showingTips = true;
10428
10738
  const needTip = this.showTooltip;
10429
10739
  const needHeader = this.formCache.displayType === "header";
10430
- for (let c = 0; c < charts.length; c++) {
10431
- const chart = charts[c];
10432
- if (!chart || chart.isDisposed()) continue;
10433
- const meta = this.ensurePointerMeta(chart);
10434
- const targetGridIndex = this.clampGridIndex(meta.gridCount, gridIndex);
10435
- const pos = this.getPixelFromYValue(chart, yValue, targetGridIndex);
10436
- const x = pos && Number.isFinite(pos[0]) ? pos[0] : (meta.width || 80) / 2;
10437
- const y = pos && Number.isFinite(pos[1]) ? pos[1] : fallbackY;
10438
- const axisKey = `${targetGridIndex}:${y | 0}`;
10439
- const group = chart.group;
10440
- chart.group = null;
10441
- if (this._lastAxisPx.get(chart) !== axisKey) {
10442
- this._lastAxisPx.set(chart, axisKey);
10443
- chart.dispatchAction({
10444
- type: "updateAxisPointer",
10445
- currTrigger: "mousemove",
10446
- x,
10447
- y,
10448
- axesInfo: [
10449
- {
10450
- axisDim: "y",
10451
- axisIndex: targetGridIndex,
10452
- value: yValue
10453
- }
10454
- ]
10455
- });
10456
- }
10457
- if (needTip || needHeader) {
10458
- const nearest = this.findNearestTooltipPoint(
10459
- chart,
10460
- yValue,
10461
- targetGridIndex
10462
- );
10463
- if (needHeader && nearest && nearest.rowData && nearest.dataIndex !== this._lastHeaderDataIndex) {
10464
- this._lastHeaderDataIndex = nearest.dataIndex;
10465
- 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();
10466
10778
  }
10467
- if (needTip) {
10468
- 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)}`;
10469
10782
  if (this._lastTipKey.get(chart) !== tipKey) {
10470
- this._lastTipKey.set(chart, tipKey);
10783
+ const nearest = this.findHelperTooltipAnchor(chart, yValue, targetGridIndex) || this.findNearestTooltipPoint(chart, yValue, targetGridIndex);
10471
10784
  if (nearest) {
10785
+ this._lastTipKey.set(chart, tipKey);
10472
10786
  chart.dispatchAction({
10473
10787
  type: "showTip",
10474
10788
  seriesIndex: nearest.seriesIndex,
@@ -10476,13 +10790,16 @@ const _sfc_main$2 = {
10476
10790
  x,
10477
10791
  y
10478
10792
  });
10479
- } else {
10480
- chart.dispatchAction({ type: "hideTip" });
10481
10793
  }
10482
10794
  }
10795
+ } else if (this._lastTipKey.get(chart) != null) {
10796
+ this._lastTipKey.delete(chart);
10797
+ chart.dispatchAction({ type: "hideTip" });
10483
10798
  }
10799
+ pinAxis();
10484
10800
  }
10485
- chart.group = group;
10801
+ } finally {
10802
+ this._showingTips = false;
10486
10803
  }
10487
10804
  },
10488
10805
  isLeavingToTooltip(event) {
@@ -10491,6 +10808,79 @@ const _sfc_main$2 = {
10491
10808
  if (next.nodeType !== 1) return false;
10492
10809
  return !!(next.classList && next.classList.contains("echarts-tooltip") || next.closest && next.closest(".echarts-tooltip"));
10493
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
+ },
10494
10884
  hideAllLaneTooltips(event) {
10495
10885
  if (this.isLeavingToTooltip(event)) return;
10496
10886
  const next = event && event.relatedTarget;
@@ -10498,8 +10888,10 @@ const _sfc_main$2 = {
10498
10888
  if (wrap && next && wrap.contains(next)) return;
10499
10889
  this.pointerInChartArea = false;
10500
10890
  this._lastTooltipY = null;
10891
+ this._lastTooltipAxisLabel = "";
10501
10892
  this._lastTooltipGridIndex = 0;
10502
10893
  this._lastHeaderDataIndex = -1;
10894
+ this._tooltipLaneId = null;
10503
10895
  this._lastTipKey = /* @__PURE__ */ new WeakMap();
10504
10896
  this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10505
10897
  this.crosshairVisible = false;
@@ -10514,6 +10906,7 @@ const _sfc_main$2 = {
10514
10906
  currTrigger: "leave"
10515
10907
  });
10516
10908
  });
10909
+ this.attachChartConnect();
10517
10910
  },
10518
10911
  hideAxisPointerAcrossCharts(event) {
10519
10912
  if (this.isLeavingToTooltip(event)) return;
@@ -10532,9 +10925,10 @@ const _sfc_main$2 = {
10532
10925
  this._pendingPointer = null;
10533
10926
  if (!this._pointerSyncHandlers || this._pointerSyncHandlers.length === 0)
10534
10927
  return;
10535
- this._pointerSyncHandlers.forEach(({ zr, onMove, onOut }) => {
10928
+ this._pointerSyncHandlers.forEach(({ zr, onMove, onDown, onOut }) => {
10536
10929
  if (zr) {
10537
10930
  zr.off("mousemove", onMove);
10931
+ if (onDown) zr.off("mousedown", onDown);
10538
10932
  if (onOut) zr.off("globalout", onOut);
10539
10933
  }
10540
10934
  });
@@ -10547,31 +10941,26 @@ const _sfc_main$2 = {
10547
10941
  const chart = item == null ? void 0 : item.chart;
10548
10942
  if (!chart || chart.isDisposed()) return;
10549
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
+ };
10550
10949
  const onMove = (e) => {
10551
10950
  var _a, _b;
10951
+ const native = e.event || e;
10952
+ if (this.isGeomechanical && native.buttons === 1 && !this._isPanning) {
10953
+ this.startChartPan();
10954
+ }
10552
10955
  this.schedulePointerSync(
10553
10956
  chart,
10554
10957
  e.offsetX ?? ((_a = e.event) == null ? void 0 : _a.offsetX),
10555
10958
  e.offsetY ?? ((_b = e.event) == null ? void 0 : _b.offsetY)
10556
10959
  );
10557
10960
  };
10558
- const onOut = () => {
10559
- if (!this.pointerInChartArea || !this.showTooltip) return;
10560
- if (this._lastTooltipY == null) return;
10561
- this.$nextTick(() => {
10562
- if (!this.pointerInChartArea || this._lastTooltipY == null) return;
10563
- this._lastTipKey = /* @__PURE__ */ new WeakMap();
10564
- this._lastAxisPx = /* @__PURE__ */ new WeakMap();
10565
- this.showSyncedLaneTooltips(
10566
- this._lastTooltipY,
10567
- this._lastTooltipOffsetY,
10568
- this._lastTooltipGridIndex
10569
- );
10570
- });
10571
- };
10961
+ zr.on("mousedown", onDown);
10572
10962
  zr.on("mousemove", onMove);
10573
- zr.on("globalout", onOut);
10574
- this._pointerSyncHandlers.push({ zr, onMove, onOut });
10963
+ this._pointerSyncHandlers.push({ zr, onMove, onDown });
10575
10964
  });
10576
10965
  },
10577
10966
  // 联动所有泳道图表的十字准线与 tooltip(贯穿整个泳道区域)
@@ -10584,6 +10973,9 @@ const _sfc_main$2 = {
10584
10973
  if (this._isUnmounted) return;
10585
10974
  const charts = this.getConnectedCharts();
10586
10975
  if (charts.length === 0) return;
10976
+ const keepDetached = this._connectDetached || this.pointerInChartArea && !this.isChartBusy();
10977
+ this._connectDetached = false;
10978
+ this._savedConnectGroups = null;
10587
10979
  charts.forEach((chart) => {
10588
10980
  chart.group = this.group;
10589
10981
  });
@@ -10592,6 +10984,7 @@ const _sfc_main$2 = {
10592
10984
  echarts.connect(this.group);
10593
10985
  }
10594
10986
  this.bindChartPointerSync();
10987
+ if (keepDetached) this.detachChartConnect();
10595
10988
  });
10596
10989
  });
10597
10990
  },
@@ -10687,7 +11080,12 @@ const _sfc_main$2 = {
10687
11080
  getXAxisRangeByHeader(lineInfo, validData = []) {
10688
11081
  let headerMin = 0;
10689
11082
  let headerMax = 1;
10690
- 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
+ }, []);
10691
11089
  if (lineInfo && Object.prototype.hasOwnProperty.call(lineInfo, "min")) {
10692
11090
  headerMin = Number(lineInfo.min);
10693
11091
  } else if (numericValues.length > 0) {
@@ -10700,10 +11098,10 @@ const _sfc_main$2 = {
10700
11098
  }
10701
11099
  const min = headerMin;
10702
11100
  const max = headerMax;
10703
- this.lineRange[lineInfo.lineId] = {
10704
- min,
10705
- max
10706
- };
11101
+ const prev = this.lineRange[lineInfo.lineId];
11102
+ if (!prev || prev.min !== min || prev.max !== max) {
11103
+ this.lineRange[lineInfo.lineId] = { min, max };
11104
+ }
10707
11105
  return { min, max };
10708
11106
  },
10709
11107
  // 判断滚动是否到达边界
@@ -10719,7 +11117,7 @@ const _sfc_main$2 = {
10719
11117
  currentData: this.visibleData[0],
10720
11118
  direction: "top"
10721
11119
  };
10722
- 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)) {
10723
11121
  this.latestTopInfo = { data, timestamp: now };
10724
11122
  this.$emit("chart-scroll", data);
10725
11123
  }
@@ -10735,13 +11133,19 @@ const _sfc_main$2 = {
10735
11133
  currentData: this.visibleData[this.visibleData.length - 1],
10736
11134
  direction: "bottom"
10737
11135
  };
10738
- 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)) {
10739
11137
  this.latestBottomInfo = { data, timestamp: now };
10740
11138
  this.$emit("chart-scroll", data);
10741
11139
  }
10742
11140
  }
10743
11141
  },
10744
- // 更新所有泳道的图表选项
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
+ },
10745
11149
  updateOptionsByLineId(lineId, option) {
10746
11150
  let index2 = this.allOptions.findIndex((lane) => lane.lineId == lineId);
10747
11151
  if (Object.prototype.hasOwnProperty.call(option, "xAxis") && option.xAxis.length === 0) {
@@ -10789,7 +11193,6 @@ const _sfc_main$2 = {
10789
11193
  const chart = chartRef.chart;
10790
11194
  chart.setOption({
10791
11195
  tooltip: {
10792
- ...chart.getOption().tooltip,
10793
11196
  showContent: this.shouldShowTooltipContent(lane.laneId)
10794
11197
  }
10795
11198
  });
@@ -10820,6 +11223,19 @@ const _sfc_main$2 = {
10820
11223
  return { min, max };
10821
11224
  },
10822
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
+ },
10823
11239
  shouldShowDepthAxisLabel(rows, axisKey) {
10824
11240
  if (!rows || !rows.length) return false;
10825
11241
  for (let i = 0; i < rows.length; i++) {
@@ -10827,6 +11243,56 @@ const _sfc_main$2 = {
10827
11243
  }
10828
11244
  return false;
10829
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
+ },
10830
11296
  getGroupAxisExtents(groups, axisKey) {
10831
11297
  const extents = [];
10832
11298
  let totalRange = 0;
@@ -10838,6 +11304,64 @@ const _sfc_main$2 = {
10838
11304
  }
10839
11305
  return { extents, totalRange };
10840
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
+ },
10841
11365
  computeUnifiedAxisInterval(groups, axisKey) {
10842
11366
  let total = 0;
10843
11367
  let min = Infinity;
@@ -10850,9 +11374,10 @@ const _sfc_main$2 = {
10850
11374
  if (e.max > max) max = e.max;
10851
11375
  }
10852
11376
  const range = max - min;
11377
+ const splits = this.getYGridSplitCount();
10853
11378
  if (!Number.isFinite(range) || range <= 0) return 5;
10854
11379
  if (this.isGeomechanical || total > 4e3) {
10855
- return range / 10;
11380
+ return range / splits;
10856
11381
  }
10857
11382
  let minStep = Infinity;
10858
11383
  for (let g = 0; g < groups.length; g++) {
@@ -10873,19 +11398,86 @@ const _sfc_main$2 = {
10873
11398
  let unified = Math.ceil(range / Math.min(12, intervalCount));
10874
11399
  return Math.max(minStep, Math.ceil(unified / minStep) * minStep);
10875
11400
  },
10876
- buildInsideDataZoom(moveOnMouseMove) {
11401
+ // 与桌面 kd-curve-v3 井深轴相同:按最小数据步长、最多 12 段。8.25
11402
+ computeDepthTimeAxisInterval(groups, axisKey) {
11403
+ let min = Infinity;
11404
+ let max = -Infinity;
11405
+ let minStep = Infinity;
11406
+ for (let g = 0; g < groups.length; g++) {
11407
+ const group = groups[g];
11408
+ let prev = NaN;
11409
+ for (let i = 0; i < group.length; i++) {
11410
+ const v = Number(group[i][axisKey]);
11411
+ if (!Number.isFinite(v)) continue;
11412
+ if (v < min) min = v;
11413
+ if (v > max) max = v;
11414
+ if (Number.isFinite(prev)) {
11415
+ const step = Math.abs(v - prev);
11416
+ if (step > 0 && step < minStep) minStep = step;
11417
+ }
11418
+ prev = v;
11419
+ }
11420
+ }
11421
+ const range = max - min;
11422
+ if (!Number.isFinite(range) || range <= 0) return 5;
11423
+ if (!Number.isFinite(minStep) || minStep <= 0) return range / 10;
11424
+ const intervalCount = Math.max(1, Math.min(12, Math.ceil(range / minStep)));
11425
+ let unified = Math.ceil(range / Math.min(12, intervalCount));
11426
+ return Math.max(minStep, Math.ceil(unified / minStep) * minStep);
11427
+ },
11428
+ buildInsideDataZoom(moveOnMouseMove, filterMode) {
10877
11429
  const pan = moveOnMouseMove === void 0 ? this.isGeomechanical && !this._chartPanLocked : !!moveOnMouseMove;
11430
+ const mode = filterMode == null ? this.isGeomechanical ? "weakFilter" : "none" : filterMode;
10878
11431
  return {
10879
11432
  type: "inside",
10880
11433
  orient: "vertical",
10881
- filterMode: "none",
11434
+ // 视窗外的点不画;x 轴仍用表头 min/max,不会跟着被滤掉的点跑偏。8.25
11435
+ filterMode: mode,
10882
11436
  disabled: !this.isGeomechanical,
10883
11437
  zoomOnMouseWheel: true,
10884
11438
  moveOnMouseMove: pan,
10885
11439
  moveOnMouseWheel: false,
10886
- throttle: this.isGeomechanical ? 50 : 100
11440
+ throttle: this.isGeomechanical ? 16 : 100
11441
+ // 地应力跟手;过大 throttle 会拖影。8.25
10887
11442
  };
10888
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
+ },
10889
11481
  applyGeoLineDrawOption(series, pointCount) {
10890
11482
  if (!this.isGeomechanical || !series) return series;
10891
11483
  series.clip = true;
@@ -10900,11 +11492,16 @@ const _sfc_main$2 = {
10900
11492
  itemStyle: { opacity: 1 }
10901
11493
  };
10902
11494
  series.select = { disabled: true };
11495
+ series.connectNulls = false;
10903
11496
  const area = series.areaStyle;
10904
11497
  const filled = area && Number(area.opacity) > 0;
10905
- 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) {
10906
11503
  series.large = true;
10907
- series.largeThreshold = 2e3;
11504
+ series.largeThreshold = 400;
10908
11505
  series.symbol = "none";
10909
11506
  }
10910
11507
  return series;
@@ -10922,10 +11519,30 @@ const _sfc_main$2 = {
10922
11519
  toDrawSeriesData(lane, rawPoints) {
10923
11520
  return this.plotSeriesForDraw(rawPoints, isLaneLogScale(lane));
10924
11521
  },
11522
+ getAxisDataKey() {
11523
+ return this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType] || (this.formCache.axisType === "time" ? "time" : "depth");
11524
+ },
10925
11525
  findRowByAxisValue(axisValue) {
10926
- const key = this.currentToolBarConfig.axisTypeList && this.currentToolBarConfig.axisTypeList[this.formCache.axisType] || (this.formCache.axisType === "time" ? "time" : "depth");
11526
+ const key = this.getAxisDataKey();
10927
11527
  return findNearestRow(this.visibleData, key, axisValue) || findNearestRow(this.realTimeData, key, axisValue);
10928
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
+ },
10929
11546
  readChartGridCount(option) {
10930
11547
  const grid = option && option.grid;
10931
11548
  if (Array.isArray(grid)) return grid.length;
@@ -10986,7 +11603,7 @@ const _sfc_main$2 = {
10986
11603
  const ref = this.getChartRefByLaneId(lanes[i].laneId);
10987
11604
  const chart = ref && ref.chart;
10988
11605
  if (!chart || chart.isDisposed()) continue;
10989
- const gridCount = this.readChartGridCount(chart.getOption() || {});
11606
+ const gridCount = this.readGridCount(chart);
10990
11607
  if (!gridCount || gridCount !== groups.length) {
10991
11608
  if (!this.isUpdatingChart) this.updateLanesChartOption();
10992
11609
  return;
@@ -10997,19 +11614,27 @@ const _sfc_main$2 = {
10997
11614
  const ref = this.getChartRefByLaneId(lane.laneId);
10998
11615
  const chart = ref && ref.chart;
10999
11616
  if (!chart || chart.isDisposed()) return;
11000
- const option = chart.getOption() || {};
11617
+ let seriesList = [];
11618
+ try {
11619
+ seriesList = chart.getModel().getSeries() || [];
11620
+ } catch (e) {
11621
+ return;
11622
+ }
11001
11623
  const isLog = isLaneLogScale(lane);
11002
11624
  const yAxis = groups.map((g) => ({ min: g.min, max: g.max }));
11003
- const series = (option.series || []).map((s) => {
11004
- 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));
11005
11628
  const group = groups[gi];
11006
- const name = Array.isArray(s.name) ? s.name[0] : s.name;
11629
+ const name = this.unwrapEchartsValue(sm && sm.name);
11007
11630
  if (name === "helper") {
11008
- 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];
11009
11633
  return { data: [[x, group.min], [x, group.max]] };
11010
11634
  }
11011
- if (name === "log-grid" || s.type !== "line") return {};
11012
- 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);
11013
11638
  if (paramId == null) return {};
11014
11639
  const cacheKey = `${gi}:${paramId}:${isLog ? 1 : 0}`;
11015
11640
  let data = groupSeriesCache.get(cacheKey);
@@ -11108,8 +11733,10 @@ const _sfc_main$2 = {
11108
11733
  },
11109
11734
  // 处理鼠标滚轮事件
11110
11735
  handleWheel(e) {
11111
- if (this.trendLineManager) this.trendLineManager.scheduleZoomRender();
11112
- if (this.isGeomechanical) return;
11736
+ if (this.isGeomechanical) {
11737
+ this.startChartZoom();
11738
+ return;
11739
+ }
11113
11740
  e.preventDefault();
11114
11741
  const dataLength = this.realTimeData && this.realTimeData.length || 0;
11115
11742
  this.wheelDelta = Math.sign(e.deltaY);
@@ -11180,7 +11807,7 @@ const _sfc_main$2 = {
11180
11807
  let markLineYValues = [];
11181
11808
  const firstChart = this.getConnectedCharts()[0];
11182
11809
  if (firstChart) {
11183
- const chartOption = firstChart.getOption();
11810
+ const chartOption = this.readChartOptionRefs(firstChart);
11184
11811
  if (chartOption && chartOption.series) {
11185
11812
  chartOption.series.forEach((series) => {
11186
11813
  if (series.markLine && series.markLine.data) {
@@ -11377,28 +12004,29 @@ const _sfc_main$2 = {
11377
12004
  const newItems = newData.filter(
11378
12005
  (item) => !existingKeys.has(item[axisKey])
11379
12006
  );
11380
- this.realTimeData = [...this.realTimeData, ...newItems];
12007
+ const merged = [...this.realTimeData, ...newItems];
11381
12008
  if (axisType === "depth") {
11382
- if (this.realTimeData[0] && this.realTimeData[0].timestamp) {
11383
- this.realTimeData.sort((a, b) => {
12009
+ if (merged[0] && merged[0].timestamp) {
12010
+ merged.sort((a, b) => {
11384
12011
  const timestampA = this.toMillisecondTimestamp(a.timestamp);
11385
12012
  const timestampB = this.toMillisecondTimestamp(b.timestamp);
11386
12013
  return timestampA - timestampB;
11387
12014
  });
11388
12015
  } else {
11389
- this.realTimeData.sort((a, b) => {
12016
+ merged.sort((a, b) => {
11390
12017
  const valA = Number(a[axisKey]);
11391
12018
  const valB = Number(b[axisKey]);
11392
12019
  return valA - valB;
11393
12020
  });
11394
12021
  }
11395
12022
  } else {
11396
- this.realTimeData.sort((a, b) => {
12023
+ merged.sort((a, b) => {
11397
12024
  const valA = Number(a[axisKey]);
11398
12025
  const valB = Number(b[axisKey]);
11399
12026
  return valA - valB;
11400
12027
  });
11401
12028
  }
12029
+ this.realTimeData = markRaw(merged);
11402
12030
  let targetStartValue = Number(startValue);
11403
12031
  if (axisType !== "depth") {
11404
12032
  const str = String(targetStartValue);
@@ -11525,16 +12153,8 @@ const _sfc_main$2 = {
11525
12153
  type: "value",
11526
12154
  inverse: true,
11527
12155
  boundaryGap: false,
11528
- scale: true,
11529
- splitLine: {
11530
- show: true,
11531
- showMinLine: false,
11532
- showMaxLine: false,
11533
- lineStyle: {
11534
- color: getCssVariable("--kd-lane-container-item-line-color"),
11535
- type: "dashed"
11536
- }
11537
- },
12156
+ scale: false,
12157
+ ...this.getPaperGridAxisStyle(true, this.getYGridSplitCount()),
11538
12158
  axisLine: {
11539
12159
  show: false,
11540
12160
  onZero: false
@@ -11577,24 +12197,7 @@ const _sfc_main$2 = {
11577
12197
  backgroundColor: `${getCssVariable("--kd-lane-container-border-color")}99`,
11578
12198
  color: `${getCssVariable("--default-text-color")}`,
11579
12199
  show: true,
11580
- formatter: (params) => {
11581
- var _a;
11582
- try {
11583
- if (this.formCache.displayType == "header") {
11584
- const firstItem = this.getFirstDataIndexItem(
11585
- params && params.seriesData
11586
- );
11587
- this.headerData = ((_a = firstItem == null ? void 0 : firstItem.data) == null ? void 0 : _a.rowData) || this.findRowByAxisValue(params && params.value) || {};
11588
- }
11589
- if (params == null || params.value == null) return "";
11590
- if (this.formCache.axisType == "time") {
11591
- return this.timestampToYMDHMS(params.value);
11592
- }
11593
- return String(params.value);
11594
- } catch (e) {
11595
- return "";
11596
- }
11597
- }
12200
+ formatter: () => this._lastTooltipAxisLabel || ""
11598
12201
  }
11599
12202
  },
11600
12203
  confine: true,
@@ -11603,65 +12206,7 @@ const _sfc_main$2 = {
11603
12206
  textStyle: {
11604
12207
  color: getCssVariable("--default-text-color")
11605
12208
  },
11606
- formatter: (series) => {
11607
- if (!series || !Array.isArray(series)) return "";
11608
- const uniqueMap = /* @__PURE__ */ new Map();
11609
- for (let i = 0; i < series.length; i++) {
11610
- const current = series[i];
11611
- if (!current || current.seriesName === "helper") continue;
11612
- const existingItem = uniqueMap.get(current.seriesName);
11613
- if (!existingItem) {
11614
- uniqueMap.set(current.seriesName, current);
11615
- continue;
11616
- }
11617
- const existingValue = Array.isArray(existingItem.value) ? existingItem.value[0] : existingItem.value;
11618
- const currentValue = Array.isArray(current.value) ? current.value[0] : current.value;
11619
- const existingHasValue = existingValue !== void 0 && existingValue !== null && existingValue !== "";
11620
- const currentHasValue = currentValue !== void 0 && currentValue !== null && currentValue !== "";
11621
- if (!existingHasValue && currentHasValue) {
11622
- continue;
11623
- }
11624
- if (existingHasValue && !currentHasValue) {
11625
- uniqueMap.set(current.seriesName, current);
11626
- } else if (existingHasValue && currentHasValue) {
11627
- if (Number(currentValue) > Number(existingValue)) {
11628
- uniqueMap.set(current.seriesName, current);
11629
- }
11630
- } else {
11631
- uniqueMap.set(current.seriesName, current);
11632
- }
11633
- }
11634
- const uniqueSeries = [];
11635
- uniqueMap.forEach((item) => uniqueSeries.push(item));
11636
- if (this.tooltipFormatter && typeof this.tooltipFormatter === "function") {
11637
- let mousePositionData = null;
11638
- if (uniqueSeries.length > 0) {
11639
- const firstItem = this.getFirstDataIndexItem(uniqueSeries);
11640
- const tip = firstItem || uniqueSeries[0];
11641
- const axisVal = Array.isArray(tip && tip.value) ? tip.value[1] : tip && tip.axisValue;
11642
- mousePositionData = firstItem && firstItem.data && firstItem.data.rowData || this.findRowByAxisValue(
11643
- Number.isFinite(Number(axisVal)) ? axisVal : this._lastTooltipY
11644
- ) || {};
11645
- } else if (this._lastTooltipY != null) {
11646
- mousePositionData = this.findRowByAxisValue(this._lastTooltipY) || {};
11647
- }
11648
- return this.tooltipFormatter({
11649
- series: uniqueSeries,
11650
- mousePositionData
11651
- });
11652
- }
11653
- let html = "<div>";
11654
- for (let i = 0; i < uniqueSeries.length; i++) {
11655
- const params = uniqueSeries[i];
11656
- const { seriesName, value, color } = params;
11657
- let xValue = value;
11658
- if (Array.isArray(value)) xValue = value[0];
11659
- const text = xValue == void 0 || xValue == null ? `${seriesName}:--` : `${seriesName}:${typeof +xValue === "number" ? Number(Number(xValue).toFixed(3)) : xValue}`;
11660
- 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>`;
11661
- }
11662
- html += "</div>";
11663
- return html;
11664
- }
12209
+ formatter: () => this.renderLaneTooltipHtml(this._tooltipLaneId)
11665
12210
  }
11666
12211
  };
11667
12212
  return option;
@@ -11731,6 +12276,7 @@ const _sfc_main$2 = {
11731
12276
  dataIndexMap.set(String(realTimeData[i][axisKey]), realTimeData[i]);
11732
12277
  }
11733
12278
  try {
12279
+ this._laneHasValidPoint = /* @__PURE__ */ Object.create(null);
11734
12280
  for (let laneIndex = 0; laneIndex < lanes.length; laneIndex++) {
11735
12281
  const lane = lanes[laneIndex];
11736
12282
  const axisTypeList = this.currentToolBarConfig.axisTypeList || {
@@ -11740,11 +12286,15 @@ const _sfc_main$2 = {
11740
12286
  const isDepthLane = Object.prototype.hasOwnProperty.call(axisTypeList, "depth") && axisTypeList.depth == lane.laneKey;
11741
12287
  const isTimeLane = Object.prototype.hasOwnProperty.call(axisTypeList, "time") && axisTypeList.time == lane.laneKey;
11742
12288
  const option = this.getDefaultLaneChartOption();
12289
+ if (isDepthLane || isTimeLane) {
12290
+ if (option.dataZoom && option.dataZoom[0]) {
12291
+ option.dataZoom[0].filterMode = "none";
12292
+ }
12293
+ }
11743
12294
  let hasValidLineData = false;
11744
12295
  const seriesDataCache = {};
11745
12296
  if (lane && lane.lines && lane.lines.length > 0) {
11746
12297
  for (const lineInfo of lane.lines) {
11747
- if (lineInfo.isUsed !== "1") continue;
11748
12298
  const seriesData = this.generateSeriesDataCached(
11749
12299
  realTimeData,
11750
12300
  lineInfo,
@@ -11753,9 +12303,7 @@ const _sfc_main$2 = {
11753
12303
  );
11754
12304
  seriesDataCache[lineInfo.lineId] = { full: seriesData };
11755
12305
  if (!hasValidLineData) {
11756
- hasValidLineData = seriesData.some(
11757
- (point) => point[0] !== null && point[0] !== void 0 && point[0] !== ""
11758
- );
12306
+ hasValidLineData = this.seriesDataHasValidX(seriesData);
11759
12307
  }
11760
12308
  if (lineInfo.recommendParamId) {
11761
12309
  const recommendLineInfo = {
@@ -11772,13 +12320,14 @@ const _sfc_main$2 = {
11772
12320
  full: recommendSeriesData
11773
12321
  };
11774
12322
  if (!hasValidLineData) {
11775
- hasValidLineData = recommendSeriesData.some(
11776
- (point) => point[0] !== null && point[0] !== void 0 && point[0] !== ""
12323
+ hasValidLineData = this.seriesDataHasValidX(
12324
+ recommendSeriesData
11777
12325
  );
11778
12326
  }
11779
12327
  }
11780
12328
  }
11781
12329
  }
12330
+ this._laneHasValidPoint[lane.laneId] = hasValidLineData;
11782
12331
  if (dataGroups.length > 0) {
11783
12332
  option.yAxis = [];
11784
12333
  option.series = [];
@@ -11808,9 +12357,12 @@ const _sfc_main$2 = {
11808
12357
  right: 2,
11809
12358
  height: `${groupHeight}%`,
11810
12359
  show: false,
11811
- containLabel: true
12360
+ containLabel: !!(isDepthLane || isTimeLane)
12361
+ // 井深列给刻度留宽,和桌面版一致。8.25
11812
12362
  });
11813
12363
  currentTop += groupHeight;
12364
+ const groupPlotH = this.getChartPlotHeightPx() * (groupHeight / 100);
12365
+ const ySplitCount = this.isGeomechanical ? this.getDepthLabelSplitCount(groupPlotH) : this.getYGridSplitCount();
11814
12366
  option.yAxis.push({
11815
12367
  gridIndex,
11816
12368
  type: "value",
@@ -11818,17 +12370,11 @@ const _sfc_main$2 = {
11818
12370
  max: groupMax,
11819
12371
  inverse: true,
11820
12372
  boundaryGap: false,
11821
- splitLine: {
11822
- show: true,
11823
- showMinLine: false,
11824
- showMaxLine: false,
11825
- lineStyle: {
11826
- color: getCssVariable(
11827
- "--kd-lane-container-item-line-color"
11828
- ),
11829
- type: "dashed"
11830
- }
11831
- },
12373
+ scale: false,
12374
+ ...this.getPaperGridAxisStyle(
12375
+ !isDepthLane && !isTimeLane,
12376
+ ySplitCount
12377
+ ),
11832
12378
  axisLine: { show: false, onZero: false },
11833
12379
  axisTick: { show: false },
11834
12380
  axisLabel: {
@@ -11838,13 +12384,16 @@ const _sfc_main$2 = {
11838
12384
  },
11839
12385
  axisPointer: { show: hasValidLineData }
11840
12386
  });
11841
- if (dataGroups.length > 1) {
11842
- 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);
11843
12393
  } else {
11844
- option.yAxis[gridIndex].splitNumber = 15;
12394
+ option.yAxis[gridIndex].interval = unifiedInterval;
11845
12395
  }
11846
12396
  if (isDepthLane || isTimeLane) {
11847
- const clientWidth = this.laneWidthMap && this.laneWidthMap[lane.laneId];
11848
12397
  option.xAxis.push({
11849
12398
  gridIndex,
11850
12399
  type: "value",
@@ -11859,53 +12408,33 @@ const _sfc_main$2 = {
11859
12408
  type: "line",
11860
12409
  xAxisIndex: option.xAxis.length - 1,
11861
12410
  yAxisIndex: gridIndex,
12411
+ name: "helper",
11862
12412
  nameIndex: groupIndex,
11863
- data: []
12413
+ data: [
12414
+ [0, groupMin],
12415
+ [0, groupMax]
12416
+ ],
12417
+ symbol: "none",
12418
+ silent: true,
12419
+ tooltip: { show: false },
12420
+ lineStyle: { opacity: 0 }
11864
12421
  });
11865
12422
  Object.assign(option.yAxis[gridIndex], {
11866
12423
  splitLine: { show: false },
12424
+ minorSplitLine: { show: false },
11867
12425
  axisPointer: { show: false },
11868
12426
  alignTicks: true,
11869
12427
  boundaryGap: false,
11870
- axisLabel: {
11871
- show: this.shouldShowDepthAxisLabel(group, axisKey),
11872
- // 无井深值不显示 0/1。8.24
11873
- width: clientWidth,
11874
- hideOverlap: true,
11875
- height: 14,
11876
- verticalAlign: "middle",
11877
- color: getCssVariable("--default-text-color"),
11878
- overflow: "truncate",
11879
- rich: {
11880
- center: {
11881
- align: "center",
11882
- fontSize: 12,
11883
- verticalAlign: "middle",
11884
- width: clientWidth - 6,
11885
- height: 14,
11886
- textBaseline: "middle",
11887
- lineHeight: 14
11888
- },
11889
- center2: {
11890
- align: "center",
11891
- fontSize: 12,
11892
- backgroundColor: "red",
11893
- verticalAlign: "middle",
11894
- width: clientWidth - 6,
11895
- height: 14,
11896
- textBaseline: "middle",
11897
- lineHeight: 14
11898
- }
11899
- },
11900
- formatter: this.getYAxisLabelFormatter(
11901
- isTimeLane,
11902
- dataGroups,
11903
- groupIndex,
11904
- groupMin,
11905
- groupMax,
11906
- axisKey
11907
- )
11908
- }
12428
+ axisLabel: this.buildDepthTimeAxisLabel(
12429
+ lane,
12430
+ group,
12431
+ isTimeLane,
12432
+ dataGroups,
12433
+ groupIndex,
12434
+ groupMin,
12435
+ groupMax,
12436
+ axisKey
12437
+ )
11909
12438
  });
11910
12439
  option.backgroundColor = "transparent";
11911
12440
  delete option.tooltip;
@@ -11962,22 +12491,16 @@ const _sfc_main$2 = {
11962
12491
  }),
11963
12492
  show: !isDepthLane
11964
12493
  } : {
11965
- interval: (max - min) / 5,
11966
- splitNumber: 5,
12494
+ interval: (max - min) / this.getPaperXSplitCount(),
11967
12495
  gridIndex,
11968
12496
  show: !isDepthLane,
11969
12497
  type: "value",
11970
12498
  min,
11971
12499
  max,
11972
- splitLine: {
11973
- show: !isDepthLane,
11974
- showMaxLine: false,
11975
- showMinLine: false,
11976
- lineStyle: {
11977
- color: splitColor,
11978
- type: "dashed"
11979
- }
11980
- },
12500
+ ...this.getPaperGridAxisStyle(
12501
+ !isDepthLane && index2 === 0,
12502
+ this.getPaperXSplitCount()
12503
+ ),
11981
12504
  axisLabel: { show: false },
11982
12505
  axisLine: { show: false },
11983
12506
  axisTick: { show: false }
@@ -12001,6 +12524,7 @@ const _sfc_main$2 = {
12001
12524
  type: lineInfo.lineType
12002
12525
  },
12003
12526
  clip: true,
12527
+ connectNulls: false,
12004
12528
  z: lineInfo.lineSort
12005
12529
  };
12006
12530
  if (lane.lines.length - 1 == index2) {
@@ -12039,8 +12563,7 @@ const _sfc_main$2 = {
12039
12563
  max,
12040
12564
  isLogScale
12041
12565
  );
12042
- this.applyGeoLineDrawOption(baseSeries, seriesSource.length);
12043
- option.series.push(baseSeries);
12566
+ this.pushGeoLineSeries(option, baseSeries, seriesSource);
12044
12567
  if (rangeAreaSeries) {
12045
12568
  option.series.push(rangeAreaSeries);
12046
12569
  }
@@ -12098,13 +12621,10 @@ const _sfc_main$2 = {
12098
12621
  type: "dashed"
12099
12622
  },
12100
12623
  clip: true,
12624
+ connectNulls: false,
12101
12625
  z: lineInfo.lineSort
12102
12626
  };
12103
- this.applyGeoLineDrawOption(
12104
- recommendSeries,
12105
- recommendSource.length
12106
- );
12107
- option.series.push(recommendSeries);
12627
+ this.pushGeoLineSeries(option, recommendSeries, recommendSource);
12108
12628
  }
12109
12629
  const effectScatterPoint = this.latestLineDataByParamCode[lineInfo.paramId];
12110
12630
  if (effectScatterPoint && lineInfo.latestDataTips) {
@@ -12159,25 +12679,27 @@ const _sfc_main$2 = {
12159
12679
  }).filter(
12160
12680
  (v) => v !== void 0 && v !== null && !Number.isNaN(v)
12161
12681
  );
12682
+ let helperX = 0;
12162
12683
  if (rangeMins.length > 0) {
12163
- const min = Math.max(...rangeMins);
12164
- const helperX = isLogScale ? Math.log10(this.getLaneLogPlotRange(lane).min) : min;
12165
- option.series.unshift({
12166
- name: "helper",
12167
- type: "line",
12168
- xAxisIndex: option.xAxis.length - 1,
12169
- yAxisIndex: gridIndex,
12170
- data: [
12171
- [helperX, groupMin],
12172
- [helperX, groupMax]
12173
- ],
12174
- lineStyle: { opacity: 0 },
12175
- symbol: "none",
12176
- silent: true,
12177
- // 禁用鼠标事件
12178
- tooltip: { show: false }
12179
- });
12684
+ helperX = isLogScale ? Math.log10(this.getLaneLogPlotRange(lane).min) : Math.max(...rangeMins);
12685
+ } else if (isLogScale) {
12686
+ helperX = Math.log10(this.getLaneLogPlotRange(lane).min);
12180
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
+ });
12181
12703
  if (isLogScale) {
12182
12704
  option.series.unshift(
12183
12705
  this.getLogPaperGridSeries(
@@ -12191,12 +12713,12 @@ const _sfc_main$2 = {
12191
12713
  }
12192
12714
  }
12193
12715
  if (option.tooltip && lane && lane.lines && lane.lines.length) {
12194
- option.tooltip.showContent = this.shouldShowTooltipContent(
12195
- lane.laneId
12196
- );
12716
+ const laneId = lane.laneId;
12717
+ option.tooltip.showContent = this.shouldShowTooltipContent(laneId);
12197
12718
  option.tooltip.triggerOn = "none";
12198
12719
  option.tooltip.enterable = false;
12199
12720
  option.tooltip.extraCssText = "pointer-events: none !important;";
12721
+ option.tooltip.formatter = () => this.renderLaneTooltipHtml(laneId);
12200
12722
  }
12201
12723
  this.updateOptionsByLineId(lane.laneId, option);
12202
12724
  }
@@ -12270,6 +12792,108 @@ const _sfc_main$2 = {
12270
12792
  output.push(data[dataLength - 1]);
12271
12793
  return output;
12272
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
+ },
12273
12897
  // 生成泳道图表数据
12274
12898
  generateSeriesData(data, lineInfo, axisKey) {
12275
12899
  return data.map((item) => {
@@ -12290,6 +12914,7 @@ const _sfc_main$2 = {
12290
12914
  }
12291
12915
  }
12292
12916
  }
12917
+ if (isMissingCurveValue(value)) value = null;
12293
12918
  return [value, +item[axisKey], item.timestamp];
12294
12919
  });
12295
12920
  },
@@ -12308,6 +12933,7 @@ const _sfc_main$2 = {
12308
12933
  }
12309
12934
  }
12310
12935
  }
12936
+ if (isMissingCurveValue(value)) value = null;
12311
12937
  return [value, +item[axisKey], item.timestamp];
12312
12938
  });
12313
12939
  },
@@ -12326,6 +12952,7 @@ const _sfc_main$2 = {
12326
12952
  }
12327
12953
  }
12328
12954
  }
12955
+ if (isMissingCurveValue(value)) value = null;
12329
12956
  return {
12330
12957
  value: [value, +item[axisKey]],
12331
12958
  rowData: item
@@ -12431,7 +13058,7 @@ const _sfc_main$2 = {
12431
13058
  }
12432
13059
  }
12433
13060
  const chart = chartRef.chart;
12434
- const option = chart.getOption();
13061
+ const option = this.readChartOptionRefs(chart);
12435
13062
  const pointInPixel = [
12436
13063
  e.offsetX || ((_a = e.event) == null ? void 0 : _a.offsetX),
12437
13064
  e.offsetY || ((_b = e.event) == null ? void 0 : _b.offsetY)
@@ -12603,10 +13230,10 @@ const _sfc_main$2 = {
12603
13230
  const filteredPoints = points.filter((point) => {
12604
13231
  if (this.formCache.axisType === "depth" && point.timestamp !== void 0 && point.timestamp !== null) {
12605
13232
  const pointY = point.value[1];
12606
- let findItem = this.visibleData.find(
13233
+ const findItem = this.visibleData.find(
12607
13234
  (d) => d[axisKey] == pointY && d.timestamp == point.timestamp
12608
- ) || {};
12609
- if (JSON.stringify(findItem) == "{}") {
13235
+ );
13236
+ if (!findItem) {
12610
13237
  return false;
12611
13238
  }
12612
13239
  return true;
@@ -12624,7 +13251,7 @@ const _sfc_main$2 = {
12624
13251
  borderWidth: 2
12625
13252
  }
12626
13253
  }));
12627
- const option = chart.getOption();
13254
+ const option = this.readChartOptionRefs(chart);
12628
13255
  const existingIndex = option.series.findIndex(
12629
13256
  (s) => s.id === "selectedPointScatter"
12630
13257
  );
@@ -12721,7 +13348,7 @@ const _sfc_main$2 = {
12721
13348
  e.offsetX || ((_a = e.event) == null ? void 0 : _a.offsetX),
12722
13349
  e.offsetY || ((_b = e.event) == null ? void 0 : _b.offsetY)
12723
13350
  ];
12724
- const option = chart.getOption();
13351
+ const option = this.readChartOptionRefs(chart);
12725
13352
  let clickedPoint = null;
12726
13353
  let minDistance = 15;
12727
13354
  for (let i = 0; i < option.series.length; i++) {
@@ -12869,7 +13496,6 @@ const _sfc_main$2 = {
12869
13496
  findMarkAreaByPoint(point, laneId) {
12870
13497
  const chartRef = this.getChartRefByLaneId(laneId);
12871
13498
  if (!chartRef || !chartRef.chart) return -1;
12872
- chartRef.chart.getOption();
12873
13499
  const yValue = point.value[1];
12874
13500
  for (let i = 0; i < this.markAreaLineData.length; i++) {
12875
13501
  const area = this.markAreaLineData[i];
@@ -13589,7 +14215,7 @@ const _sfc_main$2 = {
13589
14215
  const chartRef = this.getChartRefByLaneId(lane.laneId);
13590
14216
  if (!chartRef || !chartRef.chart) continue;
13591
14217
  const chart = chartRef.chart;
13592
- const currentOption = chart.getOption();
14218
+ const currentOption = this.readChartOptionRefs(chart);
13593
14219
  const axisTypeList = this.currentToolBarConfig.axisTypeList || {
13594
14220
  depth: "depth",
13595
14221
  time: "time"
@@ -13626,13 +14252,15 @@ const _sfc_main$2 = {
13626
14252
  right: 2,
13627
14253
  height: `${groupHeight}%`,
13628
14254
  show: false,
13629
- containLabel: false
14255
+ containLabel: !!isDepthLane
13630
14256
  };
13631
14257
  const currentGrid = currentOption.grid && currentOption.grid[gridIndex];
13632
14258
  if (!currentGrid || currentGrid.top !== gridItem.top || currentGrid.height !== gridItem.height) {
13633
14259
  needUpdate.grid = true;
13634
14260
  }
13635
14261
  newGrid.push(gridItem);
14262
+ const groupPlotH = this.getChartPlotHeightPx() * (groupHeight / 100);
14263
+ const ySplitCount = this.isGeomechanical ? this.getDepthLabelSplitCount(groupPlotH) : this.getYGridSplitCount();
13636
14264
  const yAxisItem = {
13637
14265
  gridIndex,
13638
14266
  type: "value",
@@ -13640,16 +14268,39 @@ const _sfc_main$2 = {
13640
14268
  max: groupMax,
13641
14269
  inverse: true,
13642
14270
  boundaryGap: false,
13643
- interval: unifiedInterval
14271
+ scale: false,
14272
+ ...this.getPaperGridAxisStyle(
14273
+ !isDepthLane,
14274
+ ySplitCount
14275
+ )
13644
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
+ }
13645
14289
  if (isDepthLane) {
13646
- yAxisItem.axisLabel = {
13647
- show: this.shouldShowDepthAxisLabel(group, axisKey)
13648
- // 无井深值不显示 0/1。8.24
13649
- };
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
+ );
13650
14301
  }
13651
14302
  const currentYAxis = currentOption.yAxis && currentOption.yAxis[gridIndex];
13652
- if (!currentYAxis || currentYAxis.min !== groupMin || currentYAxis.max !== groupMax || currentYAxis.interval !== unifiedInterval) {
14303
+ if (!currentYAxis || currentYAxis.min !== groupMin || currentYAxis.max !== groupMax) {
13653
14304
  needUpdate.yAxis = true;
13654
14305
  }
13655
14306
  newYAxis.push(yAxisItem);
@@ -13901,7 +14552,7 @@ const _sfc_main$2 = {
13901
14552
  deduplicateByUniqueKey(existingData, newData, uniqueKey, options = {}) {
13902
14553
  const { sortOrder = "asc", isSort = true } = options;
13903
14554
  const newDataArr = Array.isArray(newData) ? newData : [newData];
13904
- let resultData = JSON.parse(JSON.stringify(existingData));
14555
+ const resultData = Array.isArray(existingData) ? existingData.slice() : [];
13905
14556
  const existingKeys = new Set(resultData.map((item) => item[uniqueKey]));
13906
14557
  newDataArr.forEach((newItem) => {
13907
14558
  if (!newItem || !newItem[uniqueKey]) return;
@@ -14516,7 +15167,7 @@ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
14516
15167
  ])
14517
15168
  ], 544);
14518
15169
  }
14519
- const chartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2], ["__scopeId", "data-v-aace7d52"]]);
15170
+ const chartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2], ["__scopeId", "data-v-22f7e692"]]);
14520
15171
  const _sfc_main$1 = {
14521
15172
  name: "ParameterPanel",
14522
15173
  props: {