kd-lane-chart-v3 0.1.18 → 0.1.20

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
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { ref, onMounted, onBeforeUnmount, resolveDirective, openBlock, createElementBlock, withDirectives, Fragment, renderList, normalizeClass, withModifiers, createElementVNode, toRaw, reactive, computed, inject, watch, resolveComponent, createVNode, withCtx, unref, createBlock, createTextVNode, toDisplayString, createCommentVNode, vShow, provide, mergeProps, normalizeStyle, isRef, isReadonly, getCurrentInstance, nextTick, renderSlot, markRaw, useAttrs, onActivated, onUnmounted, shallowRef, createSlots } from "vue";
4
+ import { ref, onMounted, onBeforeUnmount, openBlock, createElementBlock, withDirectives, Fragment, renderList, normalizeClass, withModifiers, createElementVNode, toRaw, reactive, computed, inject, watch, resolveComponent, createVNode, withCtx, unref, createBlock, createTextVNode, toDisplayString, createCommentVNode, vShow, provide, resolveDirective, mergeProps, normalizeStyle, isRef, isReadonly, getCurrentInstance, nextTick, renderSlot, markRaw, useAttrs, shallowRef, onActivated, onUnmounted, createSlots } from "vue";
5
5
  import { cloneDeep, debounce } from "lodash-es";
6
6
  import { VueDraggable } from "vue-draggable-plus";
7
7
  import { Star, Search } from "@element-plus/icons-vue";
@@ -297,6 +297,19 @@ const _sfc_main$e = /* @__PURE__ */ Object.assign({
297
297
  },
298
298
  emits: ["menu-closed", "option-clicked"],
299
299
  setup(__props, { expose: __expose, emit: __emit }) {
300
+ const vClickOutside = {
301
+ mounted(el, binding) {
302
+ el.__kdClickOutside = (event) => {
303
+ if (el === event.target || el.contains(event.target)) return;
304
+ if (typeof binding.value === "function") binding.value(event);
305
+ };
306
+ document.addEventListener("pointerdown", el.__kdClickOutside, true);
307
+ },
308
+ unmounted(el) {
309
+ document.removeEventListener("pointerdown", el.__kdClickOutside, true);
310
+ delete el.__kdClickOutside;
311
+ }
312
+ };
300
313
  const props = __props;
301
314
  const emit = __emit;
302
315
  const refUl = ref(null);
@@ -376,7 +389,6 @@ const _sfc_main$e = /* @__PURE__ */ Object.assign({
376
389
  hideContextMenu
377
390
  });
378
391
  return (_ctx, _cache) => {
379
- const _directive_click_outside = resolveDirective("click-outside");
380
392
  return openBlock(), createElementBlock("div", null, [
381
393
  withDirectives((openBlock(), createElementBlock("ul", {
382
394
  ref_key: "refUl",
@@ -395,13 +407,13 @@ const _sfc_main$e = /* @__PURE__ */ Object.assign({
395
407
  ], 10, _hoisted_1$d);
396
408
  }), 128))
397
409
  ])), [
398
- [_directive_click_outside, onClickOutside]
410
+ [vClickOutside, onClickOutside]
399
411
  ])
400
412
  ]);
401
413
  };
402
414
  }
403
415
  });
404
- const VueSimpleContextMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-1d3cb41b"]]);
416
+ const VueSimpleContextMenu = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-b8d2d221"]]);
405
417
  class CustomStrategy {
406
418
  constructor(strategy) {
407
419
  this.strategy = strategy;
@@ -2367,10 +2379,12 @@ const _sfc_main$c = {
2367
2379
  theme.lineColor = formData.value.lineColor;
2368
2380
  }
2369
2381
  saving.value = true;
2370
- const origin = props.template || {};
2371
- const isUnset = (v) => v === void 0 || v === null || v === "";
2372
- const rangeChanged = isUnset(origin.min) || isUnset(origin.max) || Number(formData.value.min) !== Number(origin.min) || Number(formData.value.max) !== Number(origin.max);
2373
- formData.value.templateRangeSaved = !!(origin.templateRangeSaved || rangeChanged);
2382
+ if (Object.prototype.hasOwnProperty.call(formData.value, "__runtimeRangeBase")) {
2383
+ delete formData.value.__runtimeRangeBase;
2384
+ }
2385
+ if (Object.prototype.hasOwnProperty.call(formData.value, "templateRangeSaved")) {
2386
+ delete formData.value.templateRangeSaved;
2387
+ }
2374
2388
  const result = upsertLine(formData.value);
2375
2389
  if (result instanceof Promise) {
2376
2390
  result.then((res) => {
@@ -2586,7 +2600,7 @@ const _sfc_main$c = {
2586
2600
  };
2587
2601
  }
2588
2602
  };
2589
- const LineEdit = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-b4e2fdcd"]]);
2603
+ const LineEdit = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-e92b1565"]]);
2590
2604
  const _hoisted_1$a = { class: "kd-lane-template-content" };
2591
2605
  const _hoisted_2$9 = { class: "template-buttons" };
2592
2606
  const _sfc_main$b = {
@@ -6546,43 +6560,52 @@ function bindSetupState(bag, map) {
6546
6560
  if (!bag || !map) return;
6547
6561
  Object.assign(bag, map);
6548
6562
  }
6549
- function isRangeValueUnset(v) {
6550
- return v === void 0 || v === null || v === "";
6551
- }
6552
- function seedHasExplicitRange(seed) {
6553
- if (!seed) return false;
6554
- const hasMin = Object.prototype.hasOwnProperty.call(seed, "min") && !isRangeValueUnset(seed.min);
6555
- const hasMax = Object.prototype.hasOwnProperty.call(seed, "max") && !isRangeValueUnset(seed.max);
6556
- return hasMin || hasMax;
6557
- }
6558
- function ensureUserSavedLineRanges(dbDatas, dataSource) {
6559
- if (!dbDatas || !Array.isArray(dbDatas.templates)) return dbDatas;
6560
- const seedMap = /* @__PURE__ */ Object.create(null);
6561
- (dataSource && dataSource.templates || []).forEach((tpl) => {
6563
+ const RUNTIME_RANGE_BASE_KEY = "__runtimeRangeBase";
6564
+ function visitLines(templates, fn) {
6565
+ (Array.isArray(templates) ? templates : []).forEach((tpl) => {
6562
6566
  (tpl && tpl.lanes || []).forEach((lane) => {
6563
- (lane && lane.lines || []).forEach((line) => {
6564
- if (line && line.lineId != null) seedMap[String(line.lineId)] = line;
6565
- });
6567
+ (lane && lane.lines || []).forEach((line) => fn(line));
6566
6568
  });
6567
6569
  });
6568
- dbDatas.templates.forEach((tpl) => {
6569
- (tpl && tpl.lanes || []).forEach((lane) => {
6570
- (lane && lane.lines || []).forEach((line) => {
6571
- if (!line || line.templateRangeSaved) return;
6572
- const dbHas = !isRangeValueUnset(line.min) || !isRangeValueUnset(line.max);
6573
- if (!dbHas) return;
6574
- const seed = seedMap[String(line.lineId)];
6575
- if (!seedHasExplicitRange(seed)) {
6576
- line.templateRangeSaved = true;
6577
- return;
6578
- }
6579
- if (Number(line.min) !== Number(seed.min) || Number(line.max) !== Number(seed.max)) {
6580
- line.templateRangeSaved = true;
6581
- }
6582
- });
6583
- });
6584
- });
6585
- return dbDatas;
6570
+ }
6571
+ function stripRuntimeRangeForPersist(dataSourceOrConfig) {
6572
+ if (!dataSourceOrConfig || typeof dataSourceOrConfig !== "object") {
6573
+ return dataSourceOrConfig;
6574
+ }
6575
+ const ds = dataSourceOrConfig.dataSource && typeof dataSourceOrConfig.dataSource === "object" ? dataSourceOrConfig.dataSource : dataSourceOrConfig;
6576
+ const restoreLine = (line) => {
6577
+ if (!line || typeof line !== "object") return;
6578
+ const base = line[RUNTIME_RANGE_BASE_KEY];
6579
+ if (base) {
6580
+ if (Object.prototype.hasOwnProperty.call(base, "min")) {
6581
+ line.min = base.min;
6582
+ }
6583
+ if (Object.prototype.hasOwnProperty.call(base, "max")) {
6584
+ line.max = base.max;
6585
+ }
6586
+ }
6587
+ if (Object.prototype.hasOwnProperty.call(line, RUNTIME_RANGE_BASE_KEY)) {
6588
+ delete line[RUNTIME_RANGE_BASE_KEY];
6589
+ }
6590
+ if (Object.prototype.hasOwnProperty.call(line, "templateRangeSaved")) {
6591
+ delete line.templateRangeSaved;
6592
+ }
6593
+ };
6594
+ visitLines(ds.templates, restoreLine);
6595
+ if (Array.isArray(ds.lines)) {
6596
+ ds.lines.forEach(restoreLine);
6597
+ }
6598
+ return dataSourceOrConfig;
6599
+ }
6600
+ function stripRuntimeRangeFields(line) {
6601
+ if (!line || typeof line !== "object") return line;
6602
+ if (Object.prototype.hasOwnProperty.call(line, RUNTIME_RANGE_BASE_KEY)) {
6603
+ delete line[RUNTIME_RANGE_BASE_KEY];
6604
+ }
6605
+ if (Object.prototype.hasOwnProperty.call(line, "templateRangeSaved")) {
6606
+ delete line.templateRangeSaved;
6607
+ }
6608
+ return line;
6586
6609
  }
6587
6610
  const _hoisted_1$6 = ["id", "lane-id"];
6588
6611
  const _hoisted_2$5 = {
@@ -6864,12 +6887,23 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
6864
6887
  clearTimeout(proxy.resizeTimer);
6865
6888
  }
6866
6889
  proxy.resizeTimer = setTimeout(() => {
6867
- if (proxy._isUnmounted || !proxy.$el || proxy._suppressLaneWidthSync) {
6890
+ if (proxy._isUnmounted || !proxy.$el || proxy._suppressLaneWidthSync || proxy.isLineDragging || proxy.isLaneDragging || proxy.isResizing) {
6868
6891
  return;
6869
6892
  }
6893
+ beginLaneWidthSyncGuard();
6894
+ const container = proxy.$refs.targetDom;
6895
+ const containerWidth = container ? container.clientWidth : 0;
6870
6896
  proxy.updateDomHeight();
6871
- proxy.updateLaneWidthOverrides();
6872
- }, 120);
6897
+ const { lanes = [] } = proxy.currentTemplate || {};
6898
+ const overrides = proxy.laneWidthOverrides || {};
6899
+ const allHaveWidth = lanes.length > 0 && lanes.every((lane) => overrides[String(lane.laneId)] != null);
6900
+ const prevW = proxy._lastObservedContainerWidth;
6901
+ const containerWidthChanged = prevW == null || Math.abs(prevW - containerWidth) >= 2;
6902
+ if (!allHaveWidth || containerWidthChanged) {
6903
+ proxy._lastObservedContainerWidth = containerWidth;
6904
+ proxy.updateLaneWidthOverrides();
6905
+ }
6906
+ }, 150);
6873
6907
  }
6874
6908
  function updateDomHeight() {
6875
6909
  const container = proxy.$refs.targetDom;
@@ -6894,18 +6928,27 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
6894
6928
  }
6895
6929
  function beginLaneWidthSyncGuard() {
6896
6930
  proxy._suppressLaneWidthSync = true;
6931
+ if (proxy.resizeObserver) {
6932
+ proxy.resizeObserver.disconnect();
6933
+ }
6897
6934
  if (proxy._laneWidthSyncGuardTimer) {
6898
6935
  clearTimeout(proxy._laneWidthSyncGuardTimer);
6899
6936
  }
6900
6937
  proxy._laneWidthSyncGuardTimer = setTimeout(() => {
6901
6938
  proxy._laneWidthSyncGuardTimer = 0;
6902
6939
  proxy._suppressLaneWidthSync = false;
6903
- }, 200);
6940
+ if (!proxy._isUnmounted && proxy.$refs.targetDom) {
6941
+ proxy.setupResizeObserver();
6942
+ }
6943
+ }, 320);
6904
6944
  }
6905
6945
  function updateLaneWidthOverrides() {
6906
- if (proxy._suppressLaneWidthSync || proxy.isLineDragging || proxy.isLaneDragging || proxy.isResizing) {
6946
+ if (proxy.isLineDragging || proxy.isLaneDragging || proxy.isResizing) {
6907
6947
  return;
6908
6948
  }
6949
+ if (!proxy._suppressLaneWidthSync) {
6950
+ beginLaneWidthSyncGuard();
6951
+ }
6909
6952
  const { lanes = [] } = proxy.currentTemplate || {};
6910
6953
  if (!lanes.length) return;
6911
6954
  const nextOverrides = { ...proxy.laneWidthOverrides || {} };
@@ -6928,7 +6971,6 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
6928
6971
  const nextKeys = Object.keys(nextOverrides);
6929
6972
  const sameAsEmitted = nextKeys.length === Object.keys(prev).length && nextKeys.every((k) => prev[k] === nextOverrides[k]);
6930
6973
  if (sameAsEmitted) return;
6931
- beginLaneWidthSyncGuard();
6932
6974
  proxy.laneWidthOverrides = nextOverrides;
6933
6975
  proxy._lastEmittedLaneWidthMap = { ...nextOverrides };
6934
6976
  emit("lane-width-change", { ...nextOverrides });
@@ -6957,7 +6999,6 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
6957
6999
  let newWidth = Math.max(minWidth, currentWidth + deltaX);
6958
7000
  proxy.setLaneWidthOverride(currentLane2.laneId, newWidth);
6959
7001
  proxy.startX = event.clientX;
6960
- proxy.$forceUpdate();
6961
7002
  }
6962
7003
  function stopResize() {
6963
7004
  proxy.isResizing = false;
@@ -7071,12 +7112,27 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7071
7112
  proxy._laneOrderBeforeDrag = null;
7072
7113
  }
7073
7114
  function dragUpdateLine(data) {
7074
- return proxy.strategy.upsertLine(data).then((savedData) => {
7115
+ const payload = { ...data };
7116
+ const base = payload[RUNTIME_RANGE_BASE_KEY];
7117
+ if (base) {
7118
+ if (Object.prototype.hasOwnProperty.call(base, "min")) payload.min = base.min;
7119
+ if (Object.prototype.hasOwnProperty.call(base, "max")) payload.max = base.max;
7120
+ }
7121
+ stripRuntimeRangeFields(payload);
7122
+ return proxy.strategy.upsertLine(payload).then((savedData) => {
7123
+ const forMemory = {
7124
+ ...savedData,
7125
+ min: data.min,
7126
+ max: data.max
7127
+ };
7128
+ if (data[RUNTIME_RANGE_BASE_KEY]) {
7129
+ forMemory[RUNTIME_RANGE_BASE_KEY] = data[RUNTIME_RANGE_BASE_KEY];
7130
+ }
7075
7131
  const currentLanes = proxy.currentTemplate.lanes;
7076
7132
  currentLanes.forEach((lane) => {
7077
- if (lane.laneId != savedData.laneId) {
7133
+ if (lane.laneId != forMemory.laneId) {
7078
7134
  const staleIndex = (lane.lines || []).findIndex(
7079
- (line) => line.lineId == savedData.lineId
7135
+ (line) => line.lineId == forMemory.lineId
7080
7136
  );
7081
7137
  if (staleIndex >= 0) {
7082
7138
  lane.lines.splice(staleIndex, 1);
@@ -7084,21 +7140,21 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7084
7140
  }
7085
7141
  });
7086
7142
  const laneIndex = currentLanes.findIndex((lane) => {
7087
- return lane.laneId == savedData.laneId;
7143
+ return lane.laneId == forMemory.laneId;
7088
7144
  });
7089
7145
  if (laneIndex < 0) {
7090
7146
  for (const template of proxy.treeTemplates) {
7091
7147
  const { lanes } = template;
7092
7148
  for (const lane of lanes) {
7093
- if (lane.laneId == savedData.laneId) {
7149
+ if (lane.laneId == forMemory.laneId) {
7094
7150
  const { lines } = lane;
7095
7151
  const lineIndex = lines.findIndex((line) => {
7096
- return line.lineId == savedData.lineId;
7152
+ return line.lineId == forMemory.lineId;
7097
7153
  });
7098
7154
  if (lineIndex < 0) {
7099
- lines.push(savedData);
7155
+ lines.push(forMemory);
7100
7156
  } else {
7101
- lines[lineIndex] = savedData;
7157
+ lines[lineIndex] = forMemory;
7102
7158
  }
7103
7159
  sortLaneLines(lane);
7104
7160
  break;
@@ -7109,16 +7165,16 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7109
7165
  const lane = currentLanes[laneIndex];
7110
7166
  const currentLines = lane.lines;
7111
7167
  const lineIndex = currentLines.findIndex((line) => {
7112
- return line.lineId == savedData.lineId;
7168
+ return line.lineId == forMemory.lineId;
7113
7169
  });
7114
7170
  if (lineIndex < 0) {
7115
- currentLines.push(savedData);
7171
+ currentLines.push(forMemory);
7116
7172
  } else {
7117
- currentLines[lineIndex] = savedData;
7173
+ currentLines[lineIndex] = forMemory;
7118
7174
  }
7119
7175
  currentLanes[laneIndex] = lane;
7120
7176
  sortLaneLines(lane);
7121
- return savedData;
7177
+ return forMemory;
7122
7178
  }
7123
7179
  });
7124
7180
  }
@@ -7193,7 +7249,7 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7193
7249
  const minPx = 40;
7194
7250
  const w = Math.max(minPx, Math.round(Number(px) || 0));
7195
7251
  if (proxy.laneWidthOverrides[id] === w) return;
7196
- proxy.laneWidthOverrides[id] = w;
7252
+ proxy.laneWidthOverrides = { ...proxy.laneWidthOverrides, [id]: w };
7197
7253
  }
7198
7254
  function laneContainerStyle(lane, type) {
7199
7255
  const widthPx = proxy.getLaneWidthPxForLayout(lane);
@@ -7245,7 +7301,7 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7245
7301
  }
7246
7302
  function buildCurrentConfigSnapshot() {
7247
7303
  const base = cloneDeep(proxy.config || {});
7248
- return {
7304
+ const snapshot = {
7249
7305
  ...base,
7250
7306
  dataSource: {
7251
7307
  ...base.dataSource || {},
@@ -7253,6 +7309,8 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7253
7309
  params: cloneDeep(proxy.params || [])
7254
7310
  }
7255
7311
  };
7312
+ stripRuntimeRangeForPersist(snapshot);
7313
+ return snapshot;
7256
7314
  }
7257
7315
  function emitConfigChange(reason) {
7258
7316
  const payload = {
@@ -7374,7 +7432,8 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7374
7432
  });
7375
7433
  }
7376
7434
  function upsertLine(data) {
7377
- return proxy.strategy.upsertLine(data).then((savedData) => {
7435
+ const payload = stripRuntimeRangeFields({ ...data });
7436
+ return proxy.strategy.upsertLine(payload).then((savedData) => {
7378
7437
  const currentLanes = proxy.currentTemplate.lanes;
7379
7438
  const laneIndex = currentLanes.findIndex((lane) => {
7380
7439
  return lane.laneId == savedData.laneId;
@@ -7676,10 +7735,7 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7676
7735
  proxy.isLoading = true;
7677
7736
  return proxy.strategy.getUserTemplates().then((dbDatas) => {
7678
7737
  const dataSource = proxy.config && proxy.config.dataSource;
7679
- const merged = ensureUserSavedLineRanges(
7680
- mergeCurveI18nFromDataSource(dbDatas, dataSource),
7681
- dataSource
7682
- );
7738
+ const merged = mergeCurveI18nFromDataSource(dbDatas, dataSource);
7683
7739
  const { templates = [], params: params2 = [] } = merged;
7684
7740
  proxy.params = params2;
7685
7741
  sortTemplates(templates);
@@ -7731,6 +7787,7 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
7731
7787
  if (prevTemplateId != null && proxy.currentTemplate && proxy.currentTemplate.templateId !== prevTemplateId || type === "changeNumber") {
7732
7788
  proxy.laneWidthOverrides = {};
7733
7789
  proxy._lastEmittedLaneWidthMap = {};
7790
+ proxy._lastObservedContainerWidth = null;
7734
7791
  }
7735
7792
  sortLanes(proxy.currentTemplate.lanes);
7736
7793
  emit("template-change", proxy.currentTemplate);
@@ -8633,7 +8690,7 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
8633
8690
  };
8634
8691
  }
8635
8692
  });
8636
- const KdLaneContainerComponent = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-1d7c6388"]]);
8693
+ const KdLaneContainerComponent = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-a170491c"]]);
8637
8694
  /*! Element Plus v2.14.3 */
8638
8695
  var en_default = {
8639
8696
  name: "en",
@@ -11760,7 +11817,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
11760
11817
  const lastArea = ref(0);
11761
11818
  const graphic = echarts.graphic;
11762
11819
  const _skipWatcher = ref(false);
11763
- const chart = ref(null);
11820
+ const chart = shallowRef(null);
11764
11821
  const manualOptions = ref(void 0);
11765
11822
  let unwatchOptionsFn = null;
11766
11823
  let resizeHandlerFn = null;
@@ -11978,7 +12035,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
11978
12035
  );
11979
12036
  addListener(el, resizeHandlerFn);
11980
12037
  }
11981
- chart.value = nextChart;
12038
+ chart.value = markRaw(nextChart);
11982
12039
  emit("chart-inited", nextChart);
11983
12040
  }
11984
12041
  function initOptionsWatcher() {
@@ -12125,7 +12182,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
12125
12182
  enumerable: true,
12126
12183
  get: () => chart.value,
12127
12184
  set: (val) => {
12128
- chart.value = val;
12185
+ chart.value = val && typeof val === "object" ? markRaw(val) : val;
12129
12186
  }
12130
12187
  },
12131
12188
  width: {
@@ -12151,7 +12208,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
12151
12208
  };
12152
12209
  }
12153
12210
  });
12154
- const resizeEcharts = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-c291a28b"]]);
12211
+ const resizeEcharts = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-985d070b"]]);
12155
12212
  const DRAW_POINT_MIN = 400;
12156
12213
  const DRAW_POINT_MAX = 1200;
12157
12214
  function getSeriesDrawThreshold(laneHeightPx) {
@@ -12255,6 +12312,34 @@ function averageBuckets(data, threshold) {
12255
12312
  }
12256
12313
  return out.length ? out : data;
12257
12314
  }
12315
+ function clampSeriesXToAxis(data, min, max, positiveOnly = false) {
12316
+ if (!data || !data.length) return data || [];
12317
+ const lo = Number(min);
12318
+ const hi = Number(max);
12319
+ if (!Number.isFinite(lo) || !Number.isFinite(hi) || !(hi > lo)) return data;
12320
+ let changed = false;
12321
+ const out = new Array(data.length);
12322
+ for (let i = 0; i < data.length; i++) {
12323
+ const pt = data[i];
12324
+ const x = pointX(pt);
12325
+ if (isMissingCurveValue(x)) {
12326
+ out[i] = pt;
12327
+ continue;
12328
+ }
12329
+ const n = Number(x);
12330
+ if (!Number.isFinite(n) || positiveOnly && !(n > 0)) {
12331
+ out[i] = pt;
12332
+ continue;
12333
+ }
12334
+ if (n < lo || n > hi) {
12335
+ changed = true;
12336
+ out[i] = clonePointWithXY(pt, n < lo ? lo : hi, pointYRaw(pt));
12337
+ } else {
12338
+ out[i] = pt;
12339
+ }
12340
+ }
12341
+ return changed ? out : data;
12342
+ }
12258
12343
  function downsampleSeriesForDraw(data, threshold, mode = "average") {
12259
12344
  if (!data || !data.length) return data || [];
12260
12345
  if (data.length <= threshold) return data;
@@ -12273,7 +12358,7 @@ function downsampleSeriesForDraw(data, threshold, mode = "average") {
12273
12358
  }
12274
12359
  if (cur.length) segments.push(cur);
12275
12360
  if (segments.length === 1 && segments[0].length === data.length) {
12276
- return sample(data, threshold);
12361
+ return pinSegmentEnds(sample(data, threshold), data);
12277
12362
  }
12278
12363
  if (!segments.length) return data;
12279
12364
  const totalValid = segments.reduce((n, s) => n + s.length, 0);
@@ -12282,13 +12367,70 @@ function downsampleSeriesForDraw(data, threshold, mode = "average") {
12282
12367
  const seg = segments[s];
12283
12368
  const share = Math.max(2, Math.round(seg.length / totalValid * threshold));
12284
12369
  const sampled = seg.length <= share ? seg : sample(seg, Math.min(share, seg.length));
12370
+ const pinned = pinSegmentEnds(sampled, seg);
12285
12371
  if (out.length) {
12286
- out.push([null, pointYRaw(sampled[0])]);
12372
+ out.push([null, pointYRaw(pinned[0])]);
12287
12373
  }
12288
- for (let i = 0; i < sampled.length; i++) out.push(sampled[i]);
12374
+ for (let i = 0; i < pinned.length; i++) out.push(pinned[i]);
12289
12375
  }
12290
12376
  return out;
12291
12377
  }
12378
+ function pinSegmentEnds(sampled, seg) {
12379
+ if (!seg || seg.length < 2) return sampled && sampled.length ? sampled : seg || [];
12380
+ const first = seg[0];
12381
+ const last = seg[seg.length - 1];
12382
+ if (!sampled || !sampled.length) return [first, last];
12383
+ const out = sampled.slice();
12384
+ out[0] = first;
12385
+ if (out.length === 1) out.push(last);
12386
+ else out[out.length - 1] = last;
12387
+ return out;
12388
+ }
12389
+ function finiteDrawPoint(pt) {
12390
+ if (!Array.isArray(pt) || isMissingCurveValue(pt[0])) return null;
12391
+ const x = Number(pt[0]);
12392
+ const y = Number(pt[1]);
12393
+ if (!Number.isFinite(x) || !Number.isFinite(y)) return null;
12394
+ return { x, y, pt };
12395
+ }
12396
+ function bridgeCurveEnds(actual, recommend, maxGap = 80) {
12397
+ if (!actual || !recommend || !actual.length || !recommend.length) {
12398
+ return { actual, recommend };
12399
+ }
12400
+ let lastA = null;
12401
+ let lastAIndex = -1;
12402
+ for (let i = actual.length - 1; i >= 0; i--) {
12403
+ const p = finiteDrawPoint(actual[i]);
12404
+ if (p) {
12405
+ lastA = p;
12406
+ lastAIndex = i;
12407
+ break;
12408
+ }
12409
+ }
12410
+ let firstR = null;
12411
+ let firstRIndex = -1;
12412
+ for (let i = 0; i < recommend.length; i++) {
12413
+ const p = finiteDrawPoint(recommend[i]);
12414
+ if (p) {
12415
+ firstR = p;
12416
+ firstRIndex = i;
12417
+ break;
12418
+ }
12419
+ }
12420
+ if (!lastA || !firstR) return { actual, recommend };
12421
+ const gap = firstR.y - lastA.y;
12422
+ const abs = Math.abs(gap);
12423
+ if (!(abs > 0.05) || abs > maxGap) return { actual, recommend };
12424
+ const nextActual = actual.slice();
12425
+ const nextRecommend = recommend.slice();
12426
+ const extA = lastA.pt.slice();
12427
+ extA[1] = firstR.y;
12428
+ nextActual.splice(lastAIndex + 1, 0, extA);
12429
+ const extR = firstR.pt.slice();
12430
+ extR[1] = lastA.y;
12431
+ nextRecommend.splice(firstRIndex, 0, extR);
12432
+ return { actual: nextActual, recommend: nextRecommend };
12433
+ }
12292
12434
  function findNearestRow(rows, key, axisValue) {
12293
12435
  if (!rows || !rows.length) return null;
12294
12436
  const target = Number(axisValue);
@@ -12730,7 +12872,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
12730
12872
  proxy._laneWidthResizeTimer = 0;
12731
12873
  if (proxy._isUnmounted) return;
12732
12874
  proxy.resizeAllLaneCharts();
12733
- }, 0);
12875
+ }, 50);
12734
12876
  }
12735
12877
  function isSameLaneWidthMap(a, b) {
12736
12878
  const left = a || {};
@@ -13067,7 +13209,6 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
13067
13209
  if (!hasMin && !hasMax) return false;
13068
13210
  if (hasMin && !Number.isFinite(Number(nextMin))) return false;
13069
13211
  if (hasMax && !Number.isFinite(Number(nextMax))) return false;
13070
- if (proxy.isParamRangeLocked(id)) return false;
13071
13212
  const prev = proxy.paramRangeOverrides[id] || {};
13072
13213
  proxy.paramRangeOverrides[id] = {
13073
13214
  min: hasMin ? Number(nextMin) : prev.min,
@@ -13077,28 +13218,21 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
13077
13218
  if (updated) proxy.updateLanesChartOption();
13078
13219
  return true;
13079
13220
  }
13080
- function isParamRangeLocked(paramsId) {
13081
- const id = String(paramsId);
13082
- let found = false;
13083
- let unlocked = false;
13084
- proxy.forEachConfigLine((line) => {
13085
- if (String(line.paramId) !== id) return;
13086
- found = true;
13087
- if (!line.templateRangeSaved) unlocked = true;
13088
- });
13089
- return found && !unlocked;
13090
- }
13091
- function markTemplateRangeSaved(payload) {
13221
+ function clearParamRangeOverride(payload) {
13092
13222
  if (!payload) return;
13223
+ const paramId = payload.paramId != null ? String(payload.paramId) : "";
13093
13224
  const lineId = payload.lineId;
13094
- const paramId = payload.paramId;
13225
+ if (paramId && proxy.paramRangeOverrides[paramId]) {
13226
+ delete proxy.paramRangeOverrides[paramId];
13227
+ }
13095
13228
  proxy.forEachConfigLine((line) => {
13096
- if (lineId != null && line.lineId === lineId) {
13097
- line.templateRangeSaved = true;
13098
- return;
13229
+ const hit = lineId != null && line.lineId === lineId || lineId == null && paramId && String(line.paramId) === paramId;
13230
+ if (!hit) return;
13231
+ if (Object.prototype.hasOwnProperty.call(line, RUNTIME_RANGE_BASE_KEY)) {
13232
+ delete line[RUNTIME_RANGE_BASE_KEY];
13099
13233
  }
13100
- if (lineId == null && paramId != null && String(line.paramId) === String(paramId)) {
13101
- line.templateRangeSaved = true;
13234
+ if (Object.prototype.hasOwnProperty.call(line, "templateRangeSaved")) {
13235
+ delete line.templateRangeSaved;
13102
13236
  }
13103
13237
  });
13104
13238
  }
@@ -13128,7 +13262,12 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
13128
13262
  let updated = false;
13129
13263
  proxy.forEachConfigLine((line) => {
13130
13264
  if (String(line.paramId) !== id) return;
13131
- if (line.templateRangeSaved) return;
13265
+ if (!line[RUNTIME_RANGE_BASE_KEY]) {
13266
+ line[RUNTIME_RANGE_BASE_KEY] = {
13267
+ min: line.min,
13268
+ max: line.max
13269
+ };
13270
+ }
13132
13271
  if (override.min != null && Number(line.min) !== override.min) {
13133
13272
  line.min = override.min;
13134
13273
  updated = true;
@@ -14244,13 +14383,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
14244
14383
  }
14245
14384
  async function lineChange(payload) {
14246
14385
  if (payload && payload.actionType === "upsertLine") {
14247
- const id = payload.paramId != null ? String(payload.paramId) : "";
14248
- const isFunctionCurve = !!(id && proxy.paramRangeOverrides[id]);
14249
- if (isFunctionCurve && payload.templateRangeSaved) {
14250
- proxy.markTemplateRangeSaved(payload);
14251
- } else {
14252
- proxy.applyAllParamRangeOverrides();
14253
- }
14386
+ proxy.clearParamRangeOverride(payload);
14387
+ proxy.applyAllParamRangeOverrides();
14254
14388
  }
14255
14389
  await nextTick();
14256
14390
  if (proxy._isUnmounted) return;
@@ -15367,8 +15501,30 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15367
15501
  const plotted = proxy.plotSeries(data, isLogScale);
15368
15502
  return downsampleSeriesForDraw(plotted, proxy.getSeriesDrawThreshold());
15369
15503
  }
15370
- function toDrawSeriesData(lane, rawPoints) {
15371
- return proxy.plotSeriesForDraw(rawPoints, isLaneLogScale(lane));
15504
+ function toDrawSeriesData(lane, rawPoints, lineInfo) {
15505
+ const isLog = isLaneLogScale(lane);
15506
+ const range = proxy.curveDrawClampRange(lane, lineInfo, isLog);
15507
+ const bounded = clampSeriesXToAxis(rawPoints, range.min, range.max, isLog);
15508
+ return proxy.plotSeriesForDraw(bounded, isLog);
15509
+ }
15510
+ function curveDrawClampRange(lane, lineInfo, isLog) {
15511
+ if (isLog) {
15512
+ const plot = resolveLaneLogPlotRange(lane, proxy.getLineRangeStore());
15513
+ return { min: plot.min, max: plot.max };
15514
+ }
15515
+ return {
15516
+ min: lineInfo ? Number(lineInfo.min) : NaN,
15517
+ max: lineInfo ? Number(lineInfo.max) : NaN
15518
+ };
15519
+ }
15520
+ function findLineInfoByParam(lane, paramId) {
15521
+ const lines = lane && lane.lines || [];
15522
+ for (let i = 0; i < lines.length; i++) {
15523
+ const line = lines[i];
15524
+ if (!line) continue;
15525
+ if (line.paramId == paramId || line.recommendParamId == paramId) return line;
15526
+ }
15527
+ return null;
15372
15528
  }
15373
15529
  function getAxisDataKey() {
15374
15530
  return proxy.currentToolBarConfig.axisTypeList && proxy.currentToolBarConfig.axisTypeList[proxy.formCache.axisType] || (proxy.formCache.axisType === "time" ? "time" : "depth");
@@ -15421,6 +15577,157 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15421
15577
  }
15422
15578
  return groups;
15423
15579
  }
15580
+ function bridgePatchedCurveEnds(series) {
15581
+ const slots = /* @__PURE__ */ new Map();
15582
+ for (let i = 0; i < series.length; i++) {
15583
+ const item = series[i];
15584
+ const meta = item && item.__bridge;
15585
+ if (!meta) continue;
15586
+ const key = `${meta.gi}:${meta.lineId}`;
15587
+ const slot = slots.get(key) || {};
15588
+ if (meta.isRecommend) slot.recommend = item;
15589
+ else slot.actual = item;
15590
+ slots.set(key, slot);
15591
+ }
15592
+ for (const slot of slots.values()) {
15593
+ if (!slot.actual || !slot.recommend) continue;
15594
+ if (!Array.isArray(slot.actual.data) || !Array.isArray(slot.recommend.data)) continue;
15595
+ const joined = bridgeCurveEnds(slot.actual.data, slot.recommend.data);
15596
+ slot.actual.data = joined.actual;
15597
+ slot.recommend.data = joined.recommend;
15598
+ }
15599
+ for (let i = 0; i < series.length; i++) {
15600
+ if (series[i] && series[i].__bridge) delete series[i].__bridge;
15601
+ }
15602
+ }
15603
+ function latestPointColor(ctx, lineInfo) {
15604
+ const gradient = ctx.linearGradientLineColor && ctx.linearGradientLineColor[ctx.nowTheme] && ctx.linearGradientLineColor[ctx.nowTheme][lineInfo.paramId];
15605
+ if (lineInfo.isGradient && gradient) return gradient;
15606
+ const theme = lineInfo.themeConfig && lineInfo.themeConfig[ctx.nowTheme];
15607
+ if (theme && theme.lineColor) return theme.lineColor;
15608
+ return lineInfo.lineColor;
15609
+ }
15610
+ function resolveLatestPoint(ctx, lineInfo, axisMin, axisMax, axisKey) {
15611
+ if (!lineInfo || !lineInfo.latestDataTips || !lineInfo.paramId) return null;
15612
+ const book = ctx.latestLineDataByParamCode || {};
15613
+ const point = book[lineInfo.paramId];
15614
+ if (!point) return null;
15615
+ const y = Number(point[axisKey]);
15616
+ const lo = Number(axisMin);
15617
+ const hi = Number(axisMax);
15618
+ if (!Number.isFinite(y) || !Number.isFinite(lo) || !Number.isFinite(hi)) return null;
15619
+ if (y < lo || y > hi) return null;
15620
+ return point;
15621
+ }
15622
+ function clampLatestTipX(ctx, raw, lane, lineInfo, isLog) {
15623
+ const x = ctx.plotX(raw, isLog);
15624
+ if (x == null || !Number.isFinite(Number(x))) return null;
15625
+ let n = Number(x);
15626
+ const range = ctx.curveDrawClampRange(lane, lineInfo, isLog);
15627
+ const lo = Number(range && range.min);
15628
+ const hi = Number(range && range.max);
15629
+ if (Number.isFinite(lo) && Number.isFinite(hi) && hi > lo) {
15630
+ if (n < lo) n = lo;
15631
+ if (n > hi) n = hi;
15632
+ }
15633
+ return n;
15634
+ }
15635
+ function buildLatestPointSeries(ctx, lineInfo, lane, point, axisKey, isLog, xAxisIndex, yAxisIndex) {
15636
+ const x = clampLatestTipX(ctx, point[lineInfo.paramId], lane, lineInfo, isLog);
15637
+ if (x == null) return null;
15638
+ return {
15639
+ type: "effectScatter",
15640
+ name: lineInfo.paramId + "-最新点",
15641
+ tipParamId: lineInfo.paramId,
15642
+ xAxisIndex,
15643
+ yAxisIndex,
15644
+ data: [[x, point[axisKey]]],
15645
+ symbol: "circle",
15646
+ symbolSize: getAdaptedFontSize(12),
15647
+ itemStyle: {
15648
+ color: latestPointColor(ctx, lineInfo),
15649
+ opacity: 1
15650
+ },
15651
+ tooltip: { show: false },
15652
+ showEffectOn: "render",
15653
+ rippleEffect: {
15654
+ brushType: "stroke",
15655
+ scale: 3,
15656
+ period: 2
15657
+ },
15658
+ z: (Number(lineInfo.lineSort) || 0) + 1,
15659
+ // 贴在道边缘的点(值为 0,或实测超出道宽)不能被裁掉
15660
+ clip: false,
15661
+ silent: true
15662
+ };
15663
+ }
15664
+ function seriesAxisByParam(ctx, seriesList, paramId) {
15665
+ for (let i = 0; i < seriesList.length; i++) {
15666
+ const opt = seriesList[i] && seriesList[i].option || {};
15667
+ const pid = ctx.unwrapEchartsValue(opt.paramId);
15668
+ if (pid == null || pid === "" || String(pid) !== String(paramId)) continue;
15669
+ let x = opt.xAxisIndex;
15670
+ if (Array.isArray(x)) x = x[0];
15671
+ const xn = Number(x);
15672
+ return {
15673
+ xAxisIndex: Number.isFinite(xn) ? xn : 0,
15674
+ yAxisIndex: ctx.seriesYAxisIndex(opt)
15675
+ };
15676
+ }
15677
+ return null;
15678
+ }
15679
+ function appendMissingWindowGraphics(ctx, lane, groups, seriesList, series, axisKey, paramCodeMap, isLog, seenRange, seenTip) {
15680
+ const lines = lane && lane.lines || [];
15681
+ for (let i = 0; i < lines.length; i++) {
15682
+ const lineInfo = lines[i];
15683
+ if (!lineInfo || lineInfo.paramId == null || lineInfo.paramId === "") continue;
15684
+ const key = String(lineInfo.paramId);
15685
+ const axes = seriesAxisByParam(ctx, seriesList, lineInfo.paramId);
15686
+ if (!axes) continue;
15687
+ const gi = ctx.clampGridIndex(groups.length, axes.yAxisIndex);
15688
+ const group2 = groups[gi];
15689
+ const rows = group2 && group2.rows;
15690
+ if (!rows || !rows.length) continue;
15691
+ if (!seenRange.has(key) && (lineInfo.upperParamId || lineInfo.lowerParamId)) {
15692
+ const built = ctx.addRangeAreaToSeries(
15693
+ {
15694
+ z: Number(lineInfo.lineSort) || 0,
15695
+ xAxisIndex: axes.xAxisIndex,
15696
+ yAxisIndex: axes.yAxisIndex
15697
+ },
15698
+ lineInfo,
15699
+ rows,
15700
+ axisKey,
15701
+ paramCodeMap,
15702
+ lineInfo.min,
15703
+ lineInfo.max,
15704
+ isLog
15705
+ );
15706
+ if (built && built.data && built.data.length) {
15707
+ series.push(built);
15708
+ seenRange.add(key);
15709
+ }
15710
+ }
15711
+ if (!seenTip.has(key)) {
15712
+ const point = resolveLatestPoint(ctx, lineInfo, group2.min, group2.max, axisKey);
15713
+ if (!point) continue;
15714
+ const tip = buildLatestPointSeries(
15715
+ ctx,
15716
+ lineInfo,
15717
+ lane,
15718
+ point,
15719
+ axisKey,
15720
+ isLog,
15721
+ axes.xAxisIndex,
15722
+ axes.yAxisIndex
15723
+ );
15724
+ if (tip) {
15725
+ series.push(tip);
15726
+ seenTip.add(key);
15727
+ }
15728
+ }
15729
+ }
15730
+ }
15424
15731
  function patchVisibleSeries() {
15425
15732
  const rows = proxy.getVisibleData();
15426
15733
  if (!rows.length) return;
@@ -15459,7 +15766,15 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15459
15766
  return;
15460
15767
  }
15461
15768
  const isLog = isLaneLogScale(lane);
15462
- const yAxis = groups.map((g) => ({ min: g.min, max: g.max }));
15769
+ const yAxis = groups.map((g) => {
15770
+ const axis = { min: g.min, max: g.max };
15771
+ if (proxy.formCache.axisType === "depth") {
15772
+ applyDepthYAxisInterval(axis, g.min, g.max);
15773
+ }
15774
+ return axis;
15775
+ });
15776
+ const seenRange = /* @__PURE__ */ new Set();
15777
+ const seenTip = /* @__PURE__ */ new Set();
15463
15778
  const series = seriesList.map((sm) => {
15464
15779
  const opt = sm && sm.option || {};
15465
15780
  const gi = proxy.clampGridIndex(groups.length, proxy.seriesYAxisIndex(opt));
@@ -15475,33 +15790,110 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15475
15790
  };
15476
15791
  }
15477
15792
  const type = sm.subType || proxy.unwrapEchartsValue(opt.type);
15793
+ if (type === "custom" && typeof name === "string" && name.endsWith("-范围区域")) {
15794
+ const paramId2 = name.slice(0, -"-范围区域".length);
15795
+ seenRange.add(String(paramId2));
15796
+ const lineInfo2 = proxy.findLineInfoByParam(lane, paramId2);
15797
+ const rows2 = group2 && group2.rows;
15798
+ if (!lineInfo2 || !rows2 || !rows2.length) return { data: [] };
15799
+ const built = proxy.addRangeAreaToSeries(
15800
+ { z: Number(lineInfo2.lineSort) || 0 },
15801
+ lineInfo2,
15802
+ rows2,
15803
+ axisKey,
15804
+ paramCodeMap,
15805
+ lineInfo2.min,
15806
+ lineInfo2.max,
15807
+ isLog
15808
+ );
15809
+ return {
15810
+ data: built && built.data || [],
15811
+ encode: { x: 1, y: 0 }
15812
+ };
15813
+ }
15814
+ if (type === "effectScatter") {
15815
+ let tipParam = proxy.unwrapEchartsValue(opt.tipParamId);
15816
+ if ((tipParam == null || tipParam === "") && typeof name === "string" && name.endsWith("-最新点")) {
15817
+ tipParam = name.slice(0, -"-最新点".length);
15818
+ }
15819
+ if (tipParam == null || tipParam === "") return { data: [] };
15820
+ seenTip.add(String(tipParam));
15821
+ const lineInfo2 = proxy.findLineInfoByParam(lane, tipParam);
15822
+ const point = lineInfo2 ? resolveLatestPoint(proxy, lineInfo2, group2.min, group2.max, axisKey) : null;
15823
+ if (!point) return { data: [] };
15824
+ const x = clampLatestTipX(proxy, point[lineInfo2.paramId], lane, lineInfo2, isLog);
15825
+ if (x == null) return { data: [] };
15826
+ return { data: [[x, point[axisKey]]] };
15827
+ }
15478
15828
  if (name === "log-grid" || name === "trend" || type !== "line") return {};
15479
- const paramId = proxy.unwrapEchartsValue(opt.paramId);
15480
- if (paramId == null) return {};
15481
- const cacheKey = `${gi}:${paramId}:${isLog ? 1 : 0}`;
15829
+ let paramId = proxy.unwrapEchartsValue(opt.drawParamId);
15830
+ if (paramId == null || paramId === "") {
15831
+ paramId = proxy.unwrapEchartsValue(opt.paramId);
15832
+ }
15833
+ if (paramId == null || paramId === "") {
15834
+ const fromLane = proxy.unwrapEchartsValue(opt.laneId);
15835
+ if (fromLane != null && proxy.findLineInfoByParam(lane, fromLane)) {
15836
+ paramId = fromLane;
15837
+ }
15838
+ }
15839
+ if (paramId == null || paramId === "") return {};
15840
+ const lineInfo = proxy.findLineInfoByParam(lane, paramId);
15841
+ if (!lineInfo) return {};
15842
+ const isRecommend = lineInfo.recommendParamId == paramId && lineInfo.paramId != paramId;
15843
+ if (isRecommend) {
15844
+ if (!(lineInfo.recommendIsUsed === "1" || lineInfo.recommendIsUsed == 1)) {
15845
+ return { data: [] };
15846
+ }
15847
+ } else if (lineInfo.isUsed !== "1") {
15848
+ return { data: [] };
15849
+ }
15850
+ const cacheKey = `${gi}:${paramId}:${isLog ? 1 : 0}:${lane.laneId}`;
15482
15851
  let data = groupSeriesCache.get(cacheKey);
15483
15852
  if (!data) {
15484
- const raw = proxy.generateSeriesDataCached(
15853
+ let raw = proxy.generateSeriesDataCached(
15485
15854
  group2.rows,
15486
15855
  { paramId },
15487
15856
  axisKey,
15488
15857
  paramCodeMap
15489
15858
  );
15859
+ const range = proxy.curveDrawClampRange(lane, lineInfo, isLog);
15860
+ raw = clampSeriesXToAxis(raw, range.min, range.max, isLog);
15490
15861
  data = downsampleSeriesForDraw(
15491
15862
  proxy.plotSeries(raw, isLog),
15492
15863
  threshold
15493
15864
  );
15494
15865
  groupSeriesCache.set(cacheKey, data);
15495
15866
  }
15496
- return { data };
15867
+ return {
15868
+ data,
15869
+ __bridge: {
15870
+ gi,
15871
+ lineId: lineInfo.lineId,
15872
+ isRecommend
15873
+ }
15874
+ };
15497
15875
  });
15498
- const patch = { yAxis, series };
15499
- if (groups.length > 1) {
15500
- patch.grid = groups.map((g) => ({
15876
+ appendMissingWindowGraphics(
15877
+ proxy,
15878
+ lane,
15879
+ groups,
15880
+ seriesList,
15881
+ series,
15882
+ axisKey,
15883
+ paramCodeMap,
15884
+ isLog,
15885
+ seenRange,
15886
+ seenTip
15887
+ );
15888
+ bridgePatchedCurveEnds(series);
15889
+ const patch = {
15890
+ yAxis,
15891
+ series,
15892
+ grid: groups.map((g) => ({
15501
15893
  top: g.top,
15502
15894
  height: g.height
15503
- }));
15504
- }
15895
+ }))
15896
+ };
15505
15897
  try {
15506
15898
  chart.setOption(patch, { lazyUpdate: true, silent: true });
15507
15899
  } catch (e) {
@@ -16436,7 +16828,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16436
16828
  let tipAnchorMin = 0;
16437
16829
  let tipAnchorMax = 1;
16438
16830
  lane.lines.forEach((lineInfo, index2) => {
16439
- var _a, _b, _c, _d;
16831
+ var _a, _b;
16440
16832
  if (!seriesDataCache2[lineInfo.lineId]) {
16441
16833
  seriesDataCache2[lineInfo.lineId] = {
16442
16834
  full: proxy.generateSeriesDataCached(
@@ -16447,7 +16839,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16447
16839
  )
16448
16840
  };
16449
16841
  }
16450
- const groupSeriesData = plotGroups.length === 1 ? seriesDataCache2[lineInfo.lineId].full : proxy.generateSeriesDataCached(
16842
+ const cachedFull = seriesDataCache2[lineInfo.lineId].full;
16843
+ const groupSeriesData = plotGroups.length === 1 && group2.length === realTimeData2.length ? cachedFull : proxy.generateSeriesDataCached(
16451
16844
  group2,
16452
16845
  lineInfo,
16453
16846
  axisKey,
@@ -16494,7 +16887,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16494
16887
  axisTick: { show: false }
16495
16888
  }
16496
16889
  );
16497
- const seriesSource = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, groupSeriesData) : [];
16890
+ const seriesSource = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, groupSeriesData, lineInfo) : [];
16498
16891
  const baseSeries = {
16499
16892
  laneId: lineInfo.paramId,
16500
16893
  paramId: lineInfo.paramId,
@@ -16509,7 +16902,9 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16509
16902
  symbolSize: getAdaptedFontSize(lineInfo.symbolSize || 6),
16510
16903
  lineStyle: {
16511
16904
  width: getAdaptedFontSize(+lineInfo.lineSize || 1.5),
16512
- type: lineInfo.lineType
16905
+ type: lineInfo.lineType,
16906
+ cap: "round",
16907
+ join: "round"
16513
16908
  },
16514
16909
  clip: true,
16515
16910
  connectNulls: false,
@@ -16545,14 +16940,35 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16545
16940
  const rangeAreaSeries = proxy.addRangeAreaToSeries(
16546
16941
  baseSeries,
16547
16942
  lineInfo,
16548
- realTimeData2,
16943
+ group2,
16549
16944
  axisKey,
16550
16945
  paramCodeMap,
16551
16946
  min,
16552
16947
  max,
16553
16948
  isLogScale
16554
16949
  );
16555
- proxy.pushGeoLineSeries(option, baseSeries, seriesSource);
16950
+ let recommendDraw = null;
16951
+ if (lineInfo.recommendParamId) {
16952
+ const recommendLineInfo = {
16953
+ ...lineInfo,
16954
+ paramId: lineInfo.recommendParamId
16955
+ };
16956
+ const recommendGroupSeriesData = proxy.generateSeriesDataCached(
16957
+ group2,
16958
+ recommendLineInfo,
16959
+ axisKey,
16960
+ paramCodeMap
16961
+ );
16962
+ recommendDraw = lineInfo.recommendIsUsed === "1" || lineInfo.recommendIsUsed == 1 ? proxy.toDrawSeriesData(
16963
+ lane,
16964
+ recommendGroupSeriesData,
16965
+ lineInfo
16966
+ ) : [];
16967
+ const joined = bridgeCurveEnds(baseSeries.data, recommendDraw);
16968
+ baseSeries.data = joined.actual;
16969
+ recommendDraw = joined.recommend;
16970
+ }
16971
+ proxy.pushGeoLineSeries(option, baseSeries, baseSeries.data);
16556
16972
  if (rangeAreaSeries) {
16557
16973
  option.series.push(rangeAreaSeries);
16558
16974
  }
@@ -16584,20 +17000,11 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16584
17000
  }
16585
17001
  }
16586
17002
  if (lineInfo.recommendParamId) {
16587
- const recommendLineInfo = {
16588
- ...lineInfo,
16589
- paramId: lineInfo.recommendParamId,
16590
- lineType: "dashed"
16591
- };
16592
- const recommendGroupSeriesData = proxy.generateSeriesDataCached(
16593
- group2,
16594
- recommendLineInfo,
16595
- axisKey,
16596
- paramCodeMap
16597
- );
16598
- const recommendSource = lineInfo.recommendIsUsed === "1" || lineInfo.recommendIsUsed == 1 ? proxy.toDrawSeriesData(lane, recommendGroupSeriesData) : [];
17003
+ const recommendSource = recommendDraw || [];
16599
17004
  const recommendSeries = {
16600
17005
  laneId: lineInfo.recommendParamId,
17006
+ // 不写 paramId,避免点选被当成实测曲线。滚轮缩放靠它重画推荐值。
17007
+ drawParamId: lineInfo.recommendParamId,
16601
17008
  data: recommendSource,
16602
17009
  type: "line",
16603
17010
  xAxisIndex,
@@ -16607,7 +17014,9 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16607
17014
  color: lineInfo.themeConfig ? lineInfo.themeConfig[proxy.nowTheme].lineColor : lineInfo.lineColor,
16608
17015
  lineStyle: {
16609
17016
  width: getAdaptedFontSize(+lineInfo.lineSize || 1.5),
16610
- type: "dashed"
17017
+ type: "dashed",
17018
+ cap: "round",
17019
+ join: "round"
16611
17020
  },
16612
17021
  clip: true,
16613
17022
  connectNulls: false,
@@ -16615,49 +17024,25 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16615
17024
  };
16616
17025
  proxy.pushGeoLineSeries(option, recommendSeries, recommendSource);
16617
17026
  }
16618
- const effectScatterPoint = proxy.latestLineDataByParamCode[lineInfo.paramId];
16619
- if (effectScatterPoint && lineInfo.latestDataTips) {
16620
- let findIndex = -1;
16621
- if (axisKey === "depth") {
16622
- findIndex = group2.findIndex(
16623
- (item) => item.timestamp === effectScatterPoint.timestamp && item[axisKey] === effectScatterPoint[axisKey]
16624
- );
16625
- } else {
16626
- findIndex = group2.findIndex(
16627
- (item) => item[axisKey] === effectScatterPoint[axisKey]
16628
- );
16629
- }
16630
- const pointAxisValue = effectScatterPoint[axisKey];
16631
- if (pointAxisValue >= groupMin && pointAxisValue <= groupMax && findIndex !== -1) {
16632
- option.series.push({
16633
- type: "effectScatter",
16634
- xAxisIndex,
16635
- yAxisIndex: gridIndex,
16636
- data: [
16637
- [
16638
- proxy.plotX(
16639
- effectScatterPoint[lineInfo.paramId],
16640
- isLogScale
16641
- ),
16642
- effectScatterPoint[axisKey]
16643
- ]
16644
- ],
16645
- symbol: "circle",
16646
- symbolSize: getAdaptedFontSize(12),
16647
- itemStyle: {
16648
- color: lineInfo.themeConfig ? lineInfo.isGradient && ((_d = (_c = proxy.linearGradientLineColor) == null ? void 0 : _c[proxy.nowTheme]) == null ? void 0 : _d[lineInfo.paramId]) ? proxy.linearGradientLineColor[proxy.nowTheme][lineInfo.paramId] : lineInfo.themeConfig[proxy.nowTheme].lineColor : lineInfo.lineColor,
16649
- opacity: 1
16650
- },
16651
- tooltip: { show: false },
16652
- showEffectOn: "render",
16653
- rippleEffect: {
16654
- brushType: "stroke",
16655
- scale: 3,
16656
- period: 2
16657
- },
16658
- z: lineInfo.lineSort + 1
16659
- });
16660
- }
17027
+ const latestPoint = resolveLatestPoint(
17028
+ proxy,
17029
+ lineInfo,
17030
+ groupMin,
17031
+ groupMax,
17032
+ axisKey
17033
+ );
17034
+ if (latestPoint) {
17035
+ const tipSeries = buildLatestPointSeries(
17036
+ proxy,
17037
+ lineInfo,
17038
+ lane,
17039
+ latestPoint,
17040
+ axisKey,
17041
+ isLogScale,
17042
+ xAxisIndex,
17043
+ gridIndex
17044
+ );
17045
+ if (tipSeries) option.series.push(tipSeries);
16661
17046
  }
16662
17047
  });
16663
17048
  if (!isDepthLane && !isTimeLane && lane.lines.length > 0) {
@@ -18284,13 +18669,18 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18284
18669
  continue;
18285
18670
  if (!Number.isFinite(upperPoint1[1]) || !Number.isFinite(upperPoint2[1]) || !Number.isFinite(lowerPoint1[1]) || !Number.isFinite(lowerPoint2[1]))
18286
18671
  continue;
18672
+ const upperA = proxy.clampRangeBandX(upperPoint1[0], min, max, isLogScale);
18673
+ const lowerA = proxy.clampRangeBandX(lowerPoint1[0], min, max, isLogScale);
18674
+ const upperB = proxy.clampRangeBandX(upperPoint2[0], min, max, isLogScale);
18675
+ const lowerB = proxy.clampRangeBandX(lowerPoint2[0], min, max, isLogScale);
18676
+ if (upperA == null || lowerA == null || upperB == null || lowerB == null) continue;
18287
18677
  customData.push([
18288
- proxy.plotX(upperPoint1[0], isLogScale),
18289
- proxy.plotX(lowerPoint1[0], isLogScale),
18290
18678
  upperPoint1[1],
18291
- proxy.plotX(upperPoint2[0], isLogScale),
18292
- proxy.plotX(lowerPoint2[0], isLogScale),
18293
- upperPoint2[1]
18679
+ upperA,
18680
+ lowerA,
18681
+ upperPoint2[1],
18682
+ upperB,
18683
+ lowerB
18294
18684
  ]);
18295
18685
  }
18296
18686
  if (customData.length === 0) return null;
@@ -18305,13 +18695,16 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18305
18695
  yAxisIndex: baseSeries.yAxisIndex,
18306
18696
  clip: true,
18307
18697
  z: baseSeries.z - 1,
18698
+ encode: { x: 1, y: 0 },
18699
+ progressive: 0,
18700
+ animation: false,
18308
18701
  renderItem: (params2, api) => {
18309
- const upperX1 = api.value(0);
18310
- const lowerX1 = api.value(1);
18311
- const depth1 = api.value(2);
18312
- const upperX2 = api.value(3);
18313
- const lowerX2 = api.value(4);
18314
- const depth2 = api.value(5);
18702
+ const depth1 = api.value(0);
18703
+ const upperX1 = api.value(1);
18704
+ const lowerX1 = api.value(2);
18705
+ const depth2 = api.value(3);
18706
+ const upperX2 = api.value(4);
18707
+ const lowerX2 = api.value(5);
18315
18708
  const topLeft = api.coord([upperX1, depth1]);
18316
18709
  const topRight = api.coord([upperX2, depth2]);
18317
18710
  const bottomRight = api.coord([lowerX2, depth2]);
@@ -18521,7 +18914,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18521
18914
  lineInfo,
18522
18915
  axisKey
18523
18916
  );
18524
- const finalSeriesData = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, seriesData) : [];
18917
+ const finalSeriesData = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, seriesData, lineInfo) : [];
18525
18918
  needUpdate.series = true;
18526
18919
  newSeriesData.push({
18527
18920
  index: seriesIndex,
@@ -18928,7 +19321,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18928
19321
  proxy.scheduleConnectAllCharts = debounce(() => {
18929
19322
  proxy.connectAllCharts();
18930
19323
  }, 50);
18931
- trendLineManager.value = new TrendLineManager(proxy);
19324
+ trendLineManager.value = markRaw(new TrendLineManager(proxy));
18932
19325
  proxy.paramRangeOverrides = /* @__PURE__ */ Object.create(null);
18933
19326
  onMounted(() => {
18934
19327
  proxy.showDateTime = Object.prototype.hasOwnProperty.call(
@@ -19061,8 +19454,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
19061
19454
  showTrendKnotContextMenu,
19062
19455
  getTrendLineData,
19063
19456
  setCurveMinMaxByParamId,
19064
- isParamRangeLocked,
19065
- markTemplateRangeSaved,
19457
+ clearParamRangeOverride,
19066
19458
  forEachConfigLine,
19067
19459
  applyParamRangeById,
19068
19460
  applyAllParamRangeOverrides,
@@ -19201,6 +19593,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
19201
19593
  getSeriesDrawThreshold: getSeriesDrawThreshold$1,
19202
19594
  plotSeriesForDraw,
19203
19595
  toDrawSeriesData,
19596
+ curveDrawClampRange,
19597
+ findLineInfoByParam,
19204
19598
  getAxisDataKey,
19205
19599
  findRowByAxisValue,
19206
19600
  formatAxisPointerYLabel,
@@ -19591,8 +19985,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
19591
19985
  showTrendKnotContextMenu,
19592
19986
  getTrendLineData,
19593
19987
  setCurveMinMaxByParamId,
19594
- isParamRangeLocked,
19595
- markTemplateRangeSaved,
19988
+ clearParamRangeOverride,
19596
19989
  forEachConfigLine,
19597
19990
  applyParamRangeById,
19598
19991
  applyAllParamRangeOverrides,
@@ -19731,6 +20124,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
19731
20124
  getSeriesDrawThreshold: getSeriesDrawThreshold$1,
19732
20125
  plotSeriesForDraw,
19733
20126
  toDrawSeriesData,
20127
+ curveDrawClampRange,
20128
+ findLineInfoByParam,
19734
20129
  getAxisDataKey,
19735
20130
  findRowByAxisValue,
19736
20131
  formatAxisPointerYLabel,
@@ -20055,7 +20450,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
20055
20450
  };
20056
20451
  }
20057
20452
  });
20058
- const LineChartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-40b0278e"]]);
20453
+ const LineChartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-010ab113"]]);
20059
20454
  const _hoisted_1$1 = ["title"];
20060
20455
  const _hoisted_2$1 = ["title"];
20061
20456
  const _sfc_main$1 = /* @__PURE__ */ Object.assign({
@@ -21790,7 +22185,7 @@ const _sfc_main = /* @__PURE__ */ Object.assign({ name: "frameLayout", component
21790
22185
  };
21791
22186
  }
21792
22187
  });
21793
- const FrameLayoutComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-bd91b982"]]);
22188
+ const FrameLayoutComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a17d7f29"]]);
21794
22189
  function installComponents(app) {
21795
22190
  installKdI18n(app);
21796
22191
  app.component(KdLaneContainerComponent.name, KdLaneContainerComponent);