kd-lane-chart-v3 0.1.19 → 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;
@@ -8678,7 +8690,7 @@ const _sfc_main$6 = /* @__PURE__ */ Object.assign({
8678
8690
  };
8679
8691
  }
8680
8692
  });
8681
- const KdLaneContainerComponent = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-8592a21f"]]);
8693
+ const KdLaneContainerComponent = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-a170491c"]]);
8682
8694
  /*! Element Plus v2.14.3 */
8683
8695
  var en_default = {
8684
8696
  name: "en",
@@ -11805,7 +11817,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
11805
11817
  const lastArea = ref(0);
11806
11818
  const graphic = echarts.graphic;
11807
11819
  const _skipWatcher = ref(false);
11808
- const chart = ref(null);
11820
+ const chart = shallowRef(null);
11809
11821
  const manualOptions = ref(void 0);
11810
11822
  let unwatchOptionsFn = null;
11811
11823
  let resizeHandlerFn = null;
@@ -12023,7 +12035,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
12023
12035
  );
12024
12036
  addListener(el, resizeHandlerFn);
12025
12037
  }
12026
- chart.value = nextChart;
12038
+ chart.value = markRaw(nextChart);
12027
12039
  emit("chart-inited", nextChart);
12028
12040
  }
12029
12041
  function initOptionsWatcher() {
@@ -12170,7 +12182,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
12170
12182
  enumerable: true,
12171
12183
  get: () => chart.value,
12172
12184
  set: (val) => {
12173
- chart.value = val;
12185
+ chart.value = val && typeof val === "object" ? markRaw(val) : val;
12174
12186
  }
12175
12187
  },
12176
12188
  width: {
@@ -12196,7 +12208,7 @@ const _sfc_main$3 = /* @__PURE__ */ Object.assign({
12196
12208
  };
12197
12209
  }
12198
12210
  });
12199
- 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"]]);
12200
12212
  const DRAW_POINT_MIN = 400;
12201
12213
  const DRAW_POINT_MAX = 1200;
12202
12214
  function getSeriesDrawThreshold(laneHeightPx) {
@@ -12300,6 +12312,34 @@ function averageBuckets(data, threshold) {
12300
12312
  }
12301
12313
  return out.length ? out : data;
12302
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
+ }
12303
12343
  function downsampleSeriesForDraw(data, threshold, mode = "average") {
12304
12344
  if (!data || !data.length) return data || [];
12305
12345
  if (data.length <= threshold) return data;
@@ -12318,7 +12358,7 @@ function downsampleSeriesForDraw(data, threshold, mode = "average") {
12318
12358
  }
12319
12359
  if (cur.length) segments.push(cur);
12320
12360
  if (segments.length === 1 && segments[0].length === data.length) {
12321
- return sample(data, threshold);
12361
+ return pinSegmentEnds(sample(data, threshold), data);
12322
12362
  }
12323
12363
  if (!segments.length) return data;
12324
12364
  const totalValid = segments.reduce((n, s) => n + s.length, 0);
@@ -12327,13 +12367,70 @@ function downsampleSeriesForDraw(data, threshold, mode = "average") {
12327
12367
  const seg = segments[s];
12328
12368
  const share = Math.max(2, Math.round(seg.length / totalValid * threshold));
12329
12369
  const sampled = seg.length <= share ? seg : sample(seg, Math.min(share, seg.length));
12370
+ const pinned = pinSegmentEnds(sampled, seg);
12330
12371
  if (out.length) {
12331
- out.push([null, pointYRaw(sampled[0])]);
12372
+ out.push([null, pointYRaw(pinned[0])]);
12332
12373
  }
12333
- 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]);
12334
12375
  }
12335
12376
  return out;
12336
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
+ }
12337
12434
  function findNearestRow(rows, key, axisValue) {
12338
12435
  if (!rows || !rows.length) return null;
12339
12436
  const target = Number(axisValue);
@@ -15404,8 +15501,30 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15404
15501
  const plotted = proxy.plotSeries(data, isLogScale);
15405
15502
  return downsampleSeriesForDraw(plotted, proxy.getSeriesDrawThreshold());
15406
15503
  }
15407
- function toDrawSeriesData(lane, rawPoints) {
15408
- 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;
15409
15528
  }
15410
15529
  function getAxisDataKey() {
15411
15530
  return proxy.currentToolBarConfig.axisTypeList && proxy.currentToolBarConfig.axisTypeList[proxy.formCache.axisType] || (proxy.formCache.axisType === "time" ? "time" : "depth");
@@ -15458,6 +15577,157 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15458
15577
  }
15459
15578
  return groups;
15460
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
+ }
15461
15731
  function patchVisibleSeries() {
15462
15732
  const rows = proxy.getVisibleData();
15463
15733
  if (!rows.length) return;
@@ -15496,7 +15766,15 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15496
15766
  return;
15497
15767
  }
15498
15768
  const isLog = isLaneLogScale(lane);
15499
- 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();
15500
15778
  const series = seriesList.map((sm) => {
15501
15779
  const opt = sm && sm.option || {};
15502
15780
  const gi = proxy.clampGridIndex(groups.length, proxy.seriesYAxisIndex(opt));
@@ -15512,33 +15790,110 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
15512
15790
  };
15513
15791
  }
15514
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
+ }
15515
15828
  if (name === "log-grid" || name === "trend" || type !== "line") return {};
15516
- const paramId = proxy.unwrapEchartsValue(opt.paramId);
15517
- if (paramId == null) return {};
15518
- 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}`;
15519
15851
  let data = groupSeriesCache.get(cacheKey);
15520
15852
  if (!data) {
15521
- const raw = proxy.generateSeriesDataCached(
15853
+ let raw = proxy.generateSeriesDataCached(
15522
15854
  group2.rows,
15523
15855
  { paramId },
15524
15856
  axisKey,
15525
15857
  paramCodeMap
15526
15858
  );
15859
+ const range = proxy.curveDrawClampRange(lane, lineInfo, isLog);
15860
+ raw = clampSeriesXToAxis(raw, range.min, range.max, isLog);
15527
15861
  data = downsampleSeriesForDraw(
15528
15862
  proxy.plotSeries(raw, isLog),
15529
15863
  threshold
15530
15864
  );
15531
15865
  groupSeriesCache.set(cacheKey, data);
15532
15866
  }
15533
- return { data };
15867
+ return {
15868
+ data,
15869
+ __bridge: {
15870
+ gi,
15871
+ lineId: lineInfo.lineId,
15872
+ isRecommend
15873
+ }
15874
+ };
15534
15875
  });
15535
- const patch = { yAxis, series };
15536
- if (groups.length > 1) {
15537
- 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) => ({
15538
15893
  top: g.top,
15539
15894
  height: g.height
15540
- }));
15541
- }
15895
+ }))
15896
+ };
15542
15897
  try {
15543
15898
  chart.setOption(patch, { lazyUpdate: true, silent: true });
15544
15899
  } catch (e) {
@@ -16473,7 +16828,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16473
16828
  let tipAnchorMin = 0;
16474
16829
  let tipAnchorMax = 1;
16475
16830
  lane.lines.forEach((lineInfo, index2) => {
16476
- var _a, _b, _c, _d;
16831
+ var _a, _b;
16477
16832
  if (!seriesDataCache2[lineInfo.lineId]) {
16478
16833
  seriesDataCache2[lineInfo.lineId] = {
16479
16834
  full: proxy.generateSeriesDataCached(
@@ -16484,7 +16839,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16484
16839
  )
16485
16840
  };
16486
16841
  }
16487
- 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(
16488
16844
  group2,
16489
16845
  lineInfo,
16490
16846
  axisKey,
@@ -16531,7 +16887,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16531
16887
  axisTick: { show: false }
16532
16888
  }
16533
16889
  );
16534
- const seriesSource = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, groupSeriesData) : [];
16890
+ const seriesSource = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, groupSeriesData, lineInfo) : [];
16535
16891
  const baseSeries = {
16536
16892
  laneId: lineInfo.paramId,
16537
16893
  paramId: lineInfo.paramId,
@@ -16546,7 +16902,9 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16546
16902
  symbolSize: getAdaptedFontSize(lineInfo.symbolSize || 6),
16547
16903
  lineStyle: {
16548
16904
  width: getAdaptedFontSize(+lineInfo.lineSize || 1.5),
16549
- type: lineInfo.lineType
16905
+ type: lineInfo.lineType,
16906
+ cap: "round",
16907
+ join: "round"
16550
16908
  },
16551
16909
  clip: true,
16552
16910
  connectNulls: false,
@@ -16582,14 +16940,35 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16582
16940
  const rangeAreaSeries = proxy.addRangeAreaToSeries(
16583
16941
  baseSeries,
16584
16942
  lineInfo,
16585
- realTimeData2,
16943
+ group2,
16586
16944
  axisKey,
16587
16945
  paramCodeMap,
16588
16946
  min,
16589
16947
  max,
16590
16948
  isLogScale
16591
16949
  );
16592
- 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);
16593
16972
  if (rangeAreaSeries) {
16594
16973
  option.series.push(rangeAreaSeries);
16595
16974
  }
@@ -16621,20 +17000,11 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16621
17000
  }
16622
17001
  }
16623
17002
  if (lineInfo.recommendParamId) {
16624
- const recommendLineInfo = {
16625
- ...lineInfo,
16626
- paramId: lineInfo.recommendParamId,
16627
- lineType: "dashed"
16628
- };
16629
- const recommendGroupSeriesData = proxy.generateSeriesDataCached(
16630
- group2,
16631
- recommendLineInfo,
16632
- axisKey,
16633
- paramCodeMap
16634
- );
16635
- const recommendSource = lineInfo.recommendIsUsed === "1" || lineInfo.recommendIsUsed == 1 ? proxy.toDrawSeriesData(lane, recommendGroupSeriesData) : [];
17003
+ const recommendSource = recommendDraw || [];
16636
17004
  const recommendSeries = {
16637
17005
  laneId: lineInfo.recommendParamId,
17006
+ // 不写 paramId,避免点选被当成实测曲线。滚轮缩放靠它重画推荐值。
17007
+ drawParamId: lineInfo.recommendParamId,
16638
17008
  data: recommendSource,
16639
17009
  type: "line",
16640
17010
  xAxisIndex,
@@ -16644,7 +17014,9 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16644
17014
  color: lineInfo.themeConfig ? lineInfo.themeConfig[proxy.nowTheme].lineColor : lineInfo.lineColor,
16645
17015
  lineStyle: {
16646
17016
  width: getAdaptedFontSize(+lineInfo.lineSize || 1.5),
16647
- type: "dashed"
17017
+ type: "dashed",
17018
+ cap: "round",
17019
+ join: "round"
16648
17020
  },
16649
17021
  clip: true,
16650
17022
  connectNulls: false,
@@ -16652,49 +17024,25 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
16652
17024
  };
16653
17025
  proxy.pushGeoLineSeries(option, recommendSeries, recommendSource);
16654
17026
  }
16655
- const effectScatterPoint = proxy.latestLineDataByParamCode[lineInfo.paramId];
16656
- if (effectScatterPoint && lineInfo.latestDataTips) {
16657
- let findIndex = -1;
16658
- if (axisKey === "depth") {
16659
- findIndex = group2.findIndex(
16660
- (item) => item.timestamp === effectScatterPoint.timestamp && item[axisKey] === effectScatterPoint[axisKey]
16661
- );
16662
- } else {
16663
- findIndex = group2.findIndex(
16664
- (item) => item[axisKey] === effectScatterPoint[axisKey]
16665
- );
16666
- }
16667
- const pointAxisValue = effectScatterPoint[axisKey];
16668
- if (pointAxisValue >= groupMin && pointAxisValue <= groupMax && findIndex !== -1) {
16669
- option.series.push({
16670
- type: "effectScatter",
16671
- xAxisIndex,
16672
- yAxisIndex: gridIndex,
16673
- data: [
16674
- [
16675
- proxy.plotX(
16676
- effectScatterPoint[lineInfo.paramId],
16677
- isLogScale
16678
- ),
16679
- effectScatterPoint[axisKey]
16680
- ]
16681
- ],
16682
- symbol: "circle",
16683
- symbolSize: getAdaptedFontSize(12),
16684
- itemStyle: {
16685
- 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,
16686
- opacity: 1
16687
- },
16688
- tooltip: { show: false },
16689
- showEffectOn: "render",
16690
- rippleEffect: {
16691
- brushType: "stroke",
16692
- scale: 3,
16693
- period: 2
16694
- },
16695
- z: lineInfo.lineSort + 1
16696
- });
16697
- }
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);
16698
17046
  }
16699
17047
  });
16700
17048
  if (!isDepthLane && !isTimeLane && lane.lines.length > 0) {
@@ -18321,13 +18669,18 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18321
18669
  continue;
18322
18670
  if (!Number.isFinite(upperPoint1[1]) || !Number.isFinite(upperPoint2[1]) || !Number.isFinite(lowerPoint1[1]) || !Number.isFinite(lowerPoint2[1]))
18323
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;
18324
18677
  customData.push([
18325
- proxy.plotX(upperPoint1[0], isLogScale),
18326
- proxy.plotX(lowerPoint1[0], isLogScale),
18327
18678
  upperPoint1[1],
18328
- proxy.plotX(upperPoint2[0], isLogScale),
18329
- proxy.plotX(lowerPoint2[0], isLogScale),
18330
- upperPoint2[1]
18679
+ upperA,
18680
+ lowerA,
18681
+ upperPoint2[1],
18682
+ upperB,
18683
+ lowerB
18331
18684
  ]);
18332
18685
  }
18333
18686
  if (customData.length === 0) return null;
@@ -18342,13 +18695,16 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18342
18695
  yAxisIndex: baseSeries.yAxisIndex,
18343
18696
  clip: true,
18344
18697
  z: baseSeries.z - 1,
18698
+ encode: { x: 1, y: 0 },
18699
+ progressive: 0,
18700
+ animation: false,
18345
18701
  renderItem: (params2, api) => {
18346
- const upperX1 = api.value(0);
18347
- const lowerX1 = api.value(1);
18348
- const depth1 = api.value(2);
18349
- const upperX2 = api.value(3);
18350
- const lowerX2 = api.value(4);
18351
- 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);
18352
18708
  const topLeft = api.coord([upperX1, depth1]);
18353
18709
  const topRight = api.coord([upperX2, depth2]);
18354
18710
  const bottomRight = api.coord([lowerX2, depth2]);
@@ -18558,7 +18914,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18558
18914
  lineInfo,
18559
18915
  axisKey
18560
18916
  );
18561
- const finalSeriesData = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, seriesData) : [];
18917
+ const finalSeriesData = lineInfo.isUsed === "1" ? proxy.toDrawSeriesData(lane, seriesData, lineInfo) : [];
18562
18918
  needUpdate.series = true;
18563
18919
  newSeriesData.push({
18564
18920
  index: seriesIndex,
@@ -18965,7 +19321,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
18965
19321
  proxy.scheduleConnectAllCharts = debounce(() => {
18966
19322
  proxy.connectAllCharts();
18967
19323
  }, 50);
18968
- trendLineManager.value = new TrendLineManager(proxy);
19324
+ trendLineManager.value = markRaw(new TrendLineManager(proxy));
18969
19325
  proxy.paramRangeOverrides = /* @__PURE__ */ Object.create(null);
18970
19326
  onMounted(() => {
18971
19327
  proxy.showDateTime = Object.prototype.hasOwnProperty.call(
@@ -19237,6 +19593,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
19237
19593
  getSeriesDrawThreshold: getSeriesDrawThreshold$1,
19238
19594
  plotSeriesForDraw,
19239
19595
  toDrawSeriesData,
19596
+ curveDrawClampRange,
19597
+ findLineInfoByParam,
19240
19598
  getAxisDataKey,
19241
19599
  findRowByAxisValue,
19242
19600
  formatAxisPointerYLabel,
@@ -19766,6 +20124,8 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
19766
20124
  getSeriesDrawThreshold: getSeriesDrawThreshold$1,
19767
20125
  plotSeriesForDraw,
19768
20126
  toDrawSeriesData,
20127
+ curveDrawClampRange,
20128
+ findLineInfoByParam,
19769
20129
  getAxisDataKey,
19770
20130
  findRowByAxisValue,
19771
20131
  formatAxisPointerYLabel,
@@ -20090,7 +20450,7 @@ const _sfc_main$2 = /* @__PURE__ */ Object.assign({
20090
20450
  };
20091
20451
  }
20092
20452
  });
20093
- const LineChartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-996922ca"]]);
20453
+ const LineChartContainer = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-010ab113"]]);
20094
20454
  const _hoisted_1$1 = ["title"];
20095
20455
  const _hoisted_2$1 = ["title"];
20096
20456
  const _sfc_main$1 = /* @__PURE__ */ Object.assign({
@@ -21825,7 +22185,7 @@ const _sfc_main = /* @__PURE__ */ Object.assign({ name: "frameLayout", component
21825
22185
  };
21826
22186
  }
21827
22187
  });
21828
- const FrameLayoutComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-2cf67725"]]);
22188
+ const FrameLayoutComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-a17d7f29"]]);
21829
22189
  function installComponents(app) {
21830
22190
  installKdI18n(app);
21831
22191
  app.component(KdLaneContainerComponent.name, KdLaneContainerComponent);