@touchvue/plugin 1.0.0-beta.5 → 1.0.0-beta.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/index.mjs CHANGED
@@ -15236,75 +15236,88 @@ const _sfc_main$F = /* @__PURE__ */ defineComponent({
15236
15236
  }
15237
15237
  }
15238
15238
  function syncThWidth() {
15239
- if (props.columns.length > 0) {
15239
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
15240
+ if (props.columns.length > 0 && bodyHead.value && bodyHead.value.row) {
15240
15241
  const trs = bodyHead.value.row.children;
15241
- if (Number(props.fixTop) > 0 && topHead.value) {
15242
+ if (Number(props.fixTop) > 0 && topHead.value && topHead.value.row) {
15242
15243
  const topTrs = topHead.value.row.children;
15243
15244
  for (let i = 0; i < topTrs.length; i++) {
15244
- const ths = trs[i].children;
15245
- const topThs = topTrs[i].children;
15246
- for (let j = 0; j < ths.length; j++) {
15247
- const th = ths[j];
15248
- const topTh = topThs[j];
15249
- topTh.style.width = th.getBoundingClientRect().width + "px";
15245
+ const ths = (_a2 = trs[i]) == null ? void 0 : _a2.children;
15246
+ const topThs = (_b = topTrs[i]) == null ? void 0 : _b.children;
15247
+ if (ths && topThs) {
15248
+ for (let j = 0; j < ths.length; j++) {
15249
+ const th = ths[j];
15250
+ const topTh = topThs[j];
15251
+ if (th && topTh) {
15252
+ topTh.style.width = th.getBoundingClientRect().width + "px";
15253
+ }
15254
+ }
15250
15255
  }
15251
15256
  }
15252
15257
  }
15253
- if (Number(props.fixLeft) > 0 && leftHead.value) {
15258
+ if (Number(props.fixLeft) > 0 && leftHead.value && leftHead.value.row) {
15254
15259
  const leftTrs = leftHead.value.row.children;
15255
15260
  for (let i = 0; i < leftTrs.length; i++) {
15256
- const ths = trs[i].children;
15257
- const leftThs = leftTrs[i].children;
15258
- if (leftThs.length > 0) {
15261
+ const ths = (_c = trs[i]) == null ? void 0 : _c.children;
15262
+ const leftThs = (_d = leftTrs[i]) == null ? void 0 : _d.children;
15263
+ if (ths && leftThs && leftThs.length > 0) {
15259
15264
  for (let j = 0; j < leftThs.length; j++) {
15260
15265
  const th = ths[j];
15261
15266
  const leftTh = leftThs[j];
15262
- leftTh.style.width = th.getBoundingClientRect().width + "px";
15263
- leftTh.style.height = th.getBoundingClientRect().height + "px";
15267
+ if (th && leftTh) {
15268
+ leftTh.style.width = th.getBoundingClientRect().width + "px";
15269
+ leftTh.style.height = th.getBoundingClientRect().height + "px";
15270
+ }
15264
15271
  }
15265
15272
  }
15266
15273
  }
15267
- if (Number(props.fixTop) > 0 && leftTopHead.value) {
15268
- const leftTopTrs = leftTopHead.value.$refs.row.children;
15274
+ if (Number(props.fixTop) > 0 && leftTopHead.value && leftTopHead.value.row) {
15275
+ const leftTopTrs = leftTopHead.value.row.children;
15269
15276
  for (let i = 0; i < leftTopTrs.length; i++) {
15270
- const ths = trs[i].children;
15271
- const leftTopThs = leftTopTrs[i].children;
15272
- if (leftTopThs.length > 0) {
15273
- for (let i2 = 0; i2 < leftTopThs.length; i2++) {
15274
- const th = ths[i2];
15275
- const leftTopTh = leftTopThs[i2];
15276
- leftTopTh.style.width = th.getBoundingClientRect().width + "px";
15277
- leftTopTh.style.height = th.getBoundingClientRect().height + "px";
15277
+ const ths = (_e = trs[i]) == null ? void 0 : _e.children;
15278
+ const leftTopThs = (_f = leftTopTrs[i]) == null ? void 0 : _f.children;
15279
+ if (ths && leftTopThs && leftTopThs.length > 0) {
15280
+ for (let j = 0; j < leftTopThs.length; j++) {
15281
+ const th = ths[j];
15282
+ const leftTopTh = leftTopThs[j];
15283
+ if (th && leftTopTh) {
15284
+ leftTopTh.style.width = th.getBoundingClientRect().width + "px";
15285
+ leftTopTh.style.height = th.getBoundingClientRect().height + "px";
15286
+ }
15278
15287
  }
15279
15288
  }
15280
15289
  }
15281
15290
  }
15282
15291
  }
15283
- if (Number(props.fixRight) > 0 && rightHead.value) {
15292
+ if (Number(props.fixRight) > 0 && rightHead.value && rightHead.value.row) {
15284
15293
  const rightTrs = rightHead.value.row.children;
15285
15294
  for (let i = 0; i < rightTrs.length; i++) {
15286
- const ths = trs[i].children;
15287
- const rightThs = rightTrs[i].children;
15288
- if (rightThs.length > 0) {
15295
+ const ths = (_g = trs[i]) == null ? void 0 : _g.children;
15296
+ const rightThs = (_h = rightTrs[i]) == null ? void 0 : _h.children;
15297
+ if (ths && rightThs && rightThs.length > 0) {
15289
15298
  for (let j = ths.length - rightThs.length; j < ths.length; j++) {
15290
15299
  const th = ths[j];
15291
15300
  const rightTh = rightThs[j - ths.length + rightThs.length];
15292
- rightTh.style.width = th.getBoundingClientRect().width + "px";
15293
- rightTh.style.height = th.getBoundingClientRect().height + "px";
15301
+ if (th && rightTh) {
15302
+ rightTh.style.width = th.getBoundingClientRect().width + "px";
15303
+ rightTh.style.height = th.getBoundingClientRect().height + "px";
15304
+ }
15294
15305
  }
15295
15306
  }
15296
15307
  }
15297
- if (Number(props.fixTop) > 0 && rightTopHead.value) {
15308
+ if (Number(props.fixTop) > 0 && rightTopHead.value && rightTopHead.value.row) {
15298
15309
  const rightTopTrs = rightTopHead.value.row.children;
15299
15310
  for (let i = 0; i < rightTopTrs.length; i++) {
15300
- const ths = trs[i].children;
15301
- const rightTopThs = rightTopTrs[i].children;
15302
- if (rightTopThs.length > 0) {
15303
- for (let i2 = ths.length - rightTopThs.length; i2 < ths.length; i2++) {
15304
- const th = ths[i2];
15305
- const rightTopTh = rightTopThs[i2 - ths.length + rightTopThs.length];
15306
- rightTopTh.style.width = th.getBoundingClientRect().width + "px";
15307
- rightTopTh.style.height = th.getBoundingClientRect().height + "px";
15311
+ const ths = (_i = trs[i]) == null ? void 0 : _i.children;
15312
+ const rightTopThs = (_j = rightTopTrs[i]) == null ? void 0 : _j.children;
15313
+ if (ths && rightTopThs && rightTopThs.length > 0) {
15314
+ for (let j = ths.length - rightTopThs.length; j < ths.length; j++) {
15315
+ const th = ths[j];
15316
+ const rightTopTh = rightTopThs[j - ths.length + rightTopThs.length];
15317
+ if (th && rightTopTh) {
15318
+ rightTopTh.style.width = th.getBoundingClientRect().width + "px";
15319
+ rightTopTh.style.height = th.getBoundingClientRect().height + "px";
15320
+ }
15308
15321
  }
15309
15322
  }
15310
15323
  }
@@ -19496,7 +19509,7 @@ const _sfc_main$q = defineComponent({
19496
19509
  // 类型:normal 或 loading
19497
19510
  type: {
19498
19511
  type: String,
19499
- default: "",
19512
+ default: "normal",
19500
19513
  validator: (val) => ["normal", "loading", "circle"].includes(val)
19501
19514
  },
19502
19515
  // 进度条百分比,0~100的数字
@@ -19678,12 +19691,8 @@ const _sfc_main$q = defineComponent({
19678
19691
  const el = document.querySelector(".to-progress");
19679
19692
  if (el) {
19680
19693
  if (props.type === "circle") {
19681
- const circleBgTick = parseFloat(
19682
- getComputedStyle(elRef.value).getPropertyValue("--thick")
19683
- );
19684
- const circleBarTick = parseFloat(
19685
- getComputedStyle(elRef.value).getPropertyValue("--bar-thick")
19686
- );
19694
+ const circleBgTick = parseFloat(getComputedStyle(elRef.value).getPropertyValue("--thick"));
19695
+ const circleBarTick = parseFloat(getComputedStyle(elRef.value).getPropertyValue("--bar-thick"));
19687
19696
  const width = parseFloat(getComputedStyle(elRef.value).getPropertyValue("--width"));
19688
19697
  thick.value = circleBgTick / width * 100;
19689
19698
  barThick.value = circleBarTick / width * 100;
@@ -25341,7 +25350,12 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
25341
25350
  endAngle: { type: [String, Number], default: -270 },
25342
25351
  value: { type: [String, Number], default: "" },
25343
25352
  label: { type: [String, Number], default: "" },
25344
- gap: { type: [String, Number], default: 0 }
25353
+ gap: { type: [String, Number], default: 0 },
25354
+ emphasisScale: { type: Boolean, default: false },
25355
+ emphasisScaleSize: { type: [String, Number], default: 5 },
25356
+ backgroundSizePercentage: { type: [Number, String], default: 100 },
25357
+ // 默认为 100%
25358
+ backgroundPosition: { type: String, default: "center" }
25345
25359
  },
25346
25360
  emits: {
25347
25361
  "item-click": (_) => true
@@ -25417,15 +25431,37 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
25417
25431
  });
25418
25432
  const isRing = computed(() => Number(props.barSize) < Number(props.size) / 2);
25419
25433
  const chartRadius = computed(() => {
25420
- const outerRatio = 1 - Number(props.borderWidth) / Number(props.size);
25434
+ let outerRatio = 1 - Number(props.borderWidth) / Number(props.size);
25435
+ if (props.emphasisScale) {
25436
+ const scaleAdjustment = props.emphasisScaleSize / (Number(props.size) * 4);
25437
+ outerRatio = Math.max(0, outerRatio - scaleAdjustment);
25438
+ }
25421
25439
  const outer = String(Number(outerRatio.toFixed(2)) * 100 + "%");
25422
25440
  if (isRing.value) {
25423
- const innerRatio = 1 - (2 * Number(props.borderWidth) + 2 * Number(props.barSize)) / Number(props.size);
25441
+ let innerRatio = 1 - (2 * Number(props.borderWidth) + 2 * Number(props.barSize)) / Number(props.size);
25442
+ if (props.emphasisScale) {
25443
+ const scaleAdjustment = props.emphasisScaleSize / (Number(props.size) * 4);
25444
+ innerRatio = Math.max(0, innerRatio + scaleAdjustment);
25445
+ }
25424
25446
  const inner = String(Number(innerRatio.toFixed(2)) * 100 + "%");
25425
25447
  return [inner, outer];
25426
25448
  }
25427
25449
  return ["0%", outer];
25428
25450
  });
25451
+ const backgroundStyle = computed(() => {
25452
+ const percentage = Number(props.backgroundSizePercentage);
25453
+ return {
25454
+ backgroundSize: `${percentage}% ${percentage}%`,
25455
+ backgroundPosition: props.backgroundPosition,
25456
+ backgroundRepeat: "no-repeat",
25457
+ // 使用 transform 来居中背景,当背景不是 100% 时保持居中
25458
+ transform: percentage !== 100 ? "translate(-50%, -50%)" : "none",
25459
+ left: percentage !== 100 ? "50%" : "0",
25460
+ top: percentage !== 100 ? "50%" : "0",
25461
+ width: percentage !== 100 ? `${percentage}%` : "100%",
25462
+ height: percentage !== 100 ? `${percentage}%` : "100%"
25463
+ };
25464
+ });
25429
25465
  const processedColors = computed(() => {
25430
25466
  const color = props.color;
25431
25467
  if (isArray(color)) {
@@ -25536,7 +25572,7 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
25536
25572
  length: 15,
25537
25573
  length2: 15
25538
25574
  },
25539
- emphasis: { scale: false }
25575
+ emphasis: { scale: props.emphasisScale, scaleSize: props.emphasisScaleSize }
25540
25576
  }
25541
25577
  ]
25542
25578
  };
@@ -25623,13 +25659,20 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
25623
25659
  class: "to-echarts-pie-pic-content",
25624
25660
  style: normalizeStyle(setContentStyle.value)
25625
25661
  }, null, 4),
25626
- unref(slots).title ? (openBlock(), createElementBlock("div", {
25662
+ unref(slots).background ? (openBlock(), createElementBlock("div", {
25627
25663
  key: 0,
25664
+ class: "to-echarts-pie-background",
25665
+ style: normalizeStyle(backgroundStyle.value)
25666
+ }, [
25667
+ renderSlot(_ctx.$slots, "background")
25668
+ ], 4)) : createCommentVNode("", true),
25669
+ unref(slots).title ? (openBlock(), createElementBlock("div", {
25670
+ key: 1,
25628
25671
  class: "to-echarts-pie-pic-text"
25629
25672
  }, [
25630
25673
  renderSlot(_ctx.$slots, "title")
25631
25674
  ])) : __props.label || __props.value ? withDirectives((openBlock(), createElementBlock("div", {
25632
- key: 1,
25675
+ key: 2,
25633
25676
  class: "to-echarts-pie-pic-text"
25634
25677
  }, [
25635
25678
  __props.value ? (openBlock(), createElementBlock("div", {
@@ -25773,6 +25816,30 @@ const echartsBarProps = {
25773
25816
  interval: {
25774
25817
  type: Number,
25775
25818
  default: 0
25819
+ },
25820
+ tooltipType: {
25821
+ type: String,
25822
+ default: "shadow"
25823
+ },
25824
+ tooltipTextColor: {
25825
+ type: String,
25826
+ default: "#666"
25827
+ },
25828
+ tooltipBgColor: {
25829
+ type: String,
25830
+ default: "#fff"
25831
+ },
25832
+ tooltipBorderColor: {
25833
+ type: String,
25834
+ default: "#333"
25835
+ },
25836
+ showDefaultTooltip: {
25837
+ type: Boolean,
25838
+ default: false
25839
+ },
25840
+ mode: {
25841
+ type: String,
25842
+ default: "default"
25776
25843
  }
25777
25844
  };
25778
25845
  const echartsBarEmits = {
@@ -25989,6 +26056,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
25989
26056
  smooth: item.smooth || props.smooth
25990
26057
  });
25991
26058
  }
26059
+ let { lineStyle, areaStyle } = getCssConfig(item, i);
25992
26060
  series.push({
25993
26061
  name: item.name,
25994
26062
  type: item.type ? item.type : props.chartsType,
@@ -25996,9 +26064,13 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
25996
26064
  barWidth: Number(props.barSize) * currentEm.value,
25997
26065
  itemStyle: {
25998
26066
  borderRadius: Number(props.borderRadius) * currentEm.value,
25999
- color: getItemColor(item, i)
26067
+ color: lineStyle[2]
26068
+ },
26069
+ lineStyle: {
26070
+ type: lineStyle[1],
26071
+ width: lineStyle[0]
26000
26072
  },
26001
- areaStyle: item.areaStyle ? item.areaStyle : null,
26073
+ areaStyle: areaStyle ? areaStyle : null,
26002
26074
  label: getSeriesLabelConfig(),
26003
26075
  z: 2,
26004
26076
  smooth: item.smooth || props.smooth
@@ -26059,37 +26131,152 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
26059
26131
  return get3dSeriesConfig();
26060
26132
  }
26061
26133
  });
26062
- const getItemColor = (item, i) => {
26063
- let color = null;
26064
- if (isArray(props.color)) {
26065
- color = props.color[i];
26134
+ const getCssConfig = (item, i) => {
26135
+ let box = document.createElement("div");
26136
+ box.className = `to-echarts-bar-item mode-${item.mode}`;
26137
+ box.style.display = "none";
26138
+ chartContainer.value.appendChild(box);
26139
+ let lineStr = getComputedStyle(box).getPropertyValue("--line").trim();
26140
+ let lineStyle = null;
26141
+ if (lineStr) {
26142
+ let lineArr = lineStr.split(" ", 2);
26143
+ let length = lineStr.split(" ").length;
26144
+ if (length > 3) {
26145
+ const thirdPart = lineStr.substring(lineArr.join(" ").length + 1);
26146
+ const result = [...lineArr, thirdPart];
26147
+ lineStyle = [unitToNumber(result[0]), result[1], parseColorStops(result[2])];
26148
+ } else {
26149
+ const result = lineStr.split(" ");
26150
+ lineStyle = [unitToNumber(result[0]), result[1], result[2]];
26151
+ }
26066
26152
  } else {
26067
- color = props.color;
26153
+ lineStyle = [2, "solid", props.color[i]];
26154
+ }
26155
+ let areaStr = getComputedStyle(box).getPropertyValue("--area").trim();
26156
+ let areaStyle = null;
26157
+ if (areaStr) {
26158
+ if (areaStr.includes("linear-gradient")) {
26159
+ areaStyle = {
26160
+ color: parseColorStops(areaStr)
26161
+ };
26162
+ } else {
26163
+ areaStyle = {
26164
+ color: areaStr
26165
+ };
26166
+ }
26068
26167
  }
26069
- if (item.linearGradient) {
26070
- color = item.linearGradient;
26168
+ return {
26169
+ lineStyle,
26170
+ areaStyle
26171
+ };
26172
+ };
26173
+ const parseColorStops = (str) => {
26174
+ const reg = /\((.*?)\)/;
26175
+ const match = str.match(reg);
26176
+ let obj = {};
26177
+ if (match) {
26178
+ let arr = match[1].split(",");
26179
+ let fx = arr[0];
26180
+ let color = arr.splice(1);
26181
+ let colorStops = color.map((item) => {
26182
+ let k = item.trim().split(" ");
26183
+ return {
26184
+ offset: percentToDecimal(k[1]),
26185
+ color: k[0]
26186
+ };
26187
+ });
26188
+ if (fx.includes("right")) {
26189
+ obj = {
26190
+ type: "linear",
26191
+ x: 0,
26192
+ y: 0,
26193
+ x2: 1,
26194
+ y2: 0,
26195
+ colorStops
26196
+ };
26197
+ } else {
26198
+ obj = {
26199
+ type: "linear",
26200
+ x: 0,
26201
+ y: 0,
26202
+ x2: 0,
26203
+ y2: 1,
26204
+ colorStops
26205
+ };
26206
+ }
26071
26207
  }
26072
- return color;
26208
+ return obj;
26073
26209
  };
26210
+ function percentToDecimal(percent, clamp = true) {
26211
+ if (percent === null || percent === void 0 || percent === "") {
26212
+ return 0;
26213
+ }
26214
+ let str = String(percent).trim().replace(/%/g, "");
26215
+ let num = parseFloat(str);
26216
+ if (isNaN(num) || !isFinite(num)) {
26217
+ return 0;
26218
+ }
26219
+ let decimal = num / 100;
26220
+ if (clamp) {
26221
+ decimal = Math.max(0, Math.min(1, decimal));
26222
+ }
26223
+ return decimal;
26224
+ }
26225
+ function unitToNumber(size, clampPositive = true) {
26226
+ if (size === null || size === void 0 || size === "") {
26227
+ return 0;
26228
+ }
26229
+ if (typeof size === "number" && isFinite(size)) {
26230
+ const num2 = clampPositive ? Math.max(0, size) : size;
26231
+ return num2;
26232
+ }
26233
+ const str = String(size).trim();
26234
+ const numMatch = str.match(/^-?\d+(\.\d+)?/);
26235
+ let num = numMatch ? parseFloat(numMatch[0]) : 0;
26236
+ if (isNaN(num) || !isFinite(num)) {
26237
+ return 0;
26238
+ }
26239
+ if (clampPositive) {
26240
+ num = Math.max(0, num);
26241
+ }
26242
+ return num;
26243
+ }
26074
26244
  const tooltipConfig = computed(() => {
26075
26245
  if (!props.showTooltip) {
26076
26246
  return { show: false };
26077
26247
  }
26248
+ if (props.showDefaultTooltip) {
26249
+ return {
26250
+ show: true,
26251
+ trigger: "axis",
26252
+ axisPointer: {
26253
+ type: props.tooltipType
26254
+ },
26255
+ appendTo: typeof document !== "undefined" ? document.body : void 0,
26256
+ className: "to-echarts-tooltip",
26257
+ borderColor: props.tooltipBorderColor,
26258
+ backgroundColor: props.tooltipBgColor,
26259
+ textStyle: {
26260
+ fontSize: Number(props.fontSize) * currentEm.value,
26261
+ color: props.tooltipTextColor
26262
+ }
26263
+ };
26264
+ }
26078
26265
  return {
26079
26266
  show: true,
26080
26267
  trigger: "axis",
26081
26268
  axisPointer: {
26082
- type: "shadow"
26269
+ type: props.tooltipType
26083
26270
  },
26271
+ borderColor: props.tooltipBorderColor,
26084
26272
  appendTo: typeof document !== "undefined" ? document.body : void 0,
26085
26273
  className: "to-echarts-tooltip",
26086
26274
  confine: false,
26087
- extraCssText: slots.tip ? "padding: 0; background: transparent; border: none; box-shadow: none; font-size:" + Number(props.tipFontSize) * getEmPx() + "px" : "background: #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); padding: 10px; border-radius: 4px; font-size:" + Number(props.tipFontSize) * getEmPx() + "px",
26275
+ extraCssText: slots.tip ? "padding: 0; background: transparent; border: none; box-shadow: none; font-size:" + Number(props.tipFontSize) * getEmPx() + "px" : `background: ${props.tooltipBgColor}; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); padding: 10px; border-radius: 4px; font-size:` + Number(props.tipFontSize) * getEmPx() + "px",
26088
26276
  textStyle: {
26089
26277
  fontSize: Number(props.fontSize) * currentEm.value,
26090
- color: "#666"
26278
+ color: props.tooltipTextColor
26091
26279
  },
26092
- backgroundColor: "#fff",
26093
26280
  formatter: (params) => {
26094
26281
  const param = isArray(params) ? params.find((p) => p.value !== void 0) : params;
26095
26282
  if (!param)
@@ -26648,18 +26835,25 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
26648
26835
  resizeObserver = null;
26649
26836
  }
26650
26837
  });
26838
+ const setClass = computed(() => {
26839
+ let arr = [];
26840
+ if (props.mode) {
26841
+ arr.push(`mode-${props.mode}`);
26842
+ }
26843
+ return arr;
26844
+ });
26651
26845
  return (_ctx, _cache) => {
26652
26846
  return openBlock(), createElementBlock("div", {
26653
26847
  ref_key: "chartContainer",
26654
26848
  ref: chartContainer,
26655
- class: "to-echarts-bar",
26849
+ class: normalizeClass(["to-echarts-bar", setClass.value]),
26656
26850
  style: normalizeStyle(setBarStyle.value)
26657
- }, null, 4);
26851
+ }, null, 6);
26658
26852
  };
26659
26853
  }
26660
26854
  });
26661
- const echartsBar_vue_vue_type_style_index_0_scoped_4f4fca0e_lang = "";
26662
- const EchartsBar = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-4f4fca0e"]]);
26855
+ const echartsBar_vue_vue_type_style_index_0_scoped_9ca896ae_lang = "";
26856
+ const EchartsBar = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-9ca896ae"]]);
26663
26857
  const ToEchartsBar = withInstall(EchartsBar);
26664
26858
  const DEFAULT_VIEW_CONTROL = {
26665
26859
  zoomSensitivity: 0,
@@ -26672,6 +26866,22 @@ const echartsMapProps = {
26672
26866
  type: Object,
26673
26867
  default: () => ({})
26674
26868
  },
26869
+ rotate: {
26870
+ type: [String, Number],
26871
+ default: 0
26872
+ },
26873
+ scaleX: {
26874
+ type: [String, Number],
26875
+ default: 1
26876
+ },
26877
+ scaleY: {
26878
+ type: [String, Number],
26879
+ default: 1
26880
+ },
26881
+ aspectRatio: {
26882
+ type: [String, Number],
26883
+ default: ""
26884
+ },
26675
26885
  shadow: {
26676
26886
  type: String,
26677
26887
  default: ""
@@ -26811,6 +27021,26 @@ const echartsMapProps = {
26811
27021
  outlineWidth: {
26812
27022
  type: [String, Number],
26813
27023
  default: 2
27024
+ },
27025
+ showLabelIcon: {
27026
+ type: Boolean,
27027
+ default: false
27028
+ },
27029
+ labelIcon: {
27030
+ type: String,
27031
+ default: "◉"
27032
+ },
27033
+ labelIconType: {
27034
+ type: String,
27035
+ default: "text"
27036
+ },
27037
+ labelIconSize: {
27038
+ type: [Number, Array],
27039
+ default: void 0
27040
+ },
27041
+ position: {
27042
+ type: String,
27043
+ default: ""
26814
27044
  }
26815
27045
  };
26816
27046
  const echartsMapEmits = {
@@ -29018,6 +29248,7 @@ const cityData = [
29018
29248
  city: "90"
29019
29249
  }
29020
29250
  ];
29251
+ const OUTLINE_BASE_URL = "https://geo.datav.aliyun.com/areas_v3/bound/";
29021
29252
  const _sfc_main = /* @__PURE__ */ defineComponent({
29022
29253
  ...{
29023
29254
  name: "ToEchartsMap"
@@ -29120,6 +29351,22 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29120
29351
  if (props.width) {
29121
29352
  style.width = formatSize(props.width);
29122
29353
  }
29354
+ let finalScaleX = Number(props.scaleX) || 1;
29355
+ let finalScaleY = Number(props.scaleY) || 1;
29356
+ if (props.aspectRatio) {
29357
+ const targetRatio = Number(props.aspectRatio);
29358
+ if (targetRatio > 0) {
29359
+ const currentRatio = finalScaleX / finalScaleY;
29360
+ if (currentRatio < targetRatio) {
29361
+ finalScaleX = finalScaleY * targetRatio;
29362
+ } else {
29363
+ finalScaleY = finalScaleX / targetRatio;
29364
+ }
29365
+ }
29366
+ }
29367
+ const rotate = Number(props.rotate) || 0;
29368
+ style.transform = `rotate(${rotate}deg) scaleX(${finalScaleX}) scaleY(${finalScaleY})`;
29369
+ style.transformOrigin = "center center";
29123
29370
  return style;
29124
29371
  });
29125
29372
  const loadEcharts = async () => {
@@ -29273,7 +29520,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29273
29520
  value: item.properties,
29274
29521
  name: item.properties.name
29275
29522
  }))) != null ? _b : [];
29276
- await setMapOptions(geoName, mapData);
29523
+ await setMapOptions(geoName, code, mapData);
29277
29524
  } catch (error) {
29278
29525
  console.error("[ToEchartsMap] 获取地图数据失败", error);
29279
29526
  }
@@ -29302,12 +29549,54 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29302
29549
  const max2 = values.length ? Math.max(...values) : 0;
29303
29550
  return { min, max: max2 };
29304
29551
  };
29305
- const setMapOptions = async (geoName, mapData) => {
29552
+ const outlineCache = /* @__PURE__ */ new Map();
29553
+ const loadOutlineGeoJson = async (code) => {
29554
+ if (!props.showOutline)
29555
+ return null;
29556
+ if (typeof fetch === "undefined")
29557
+ return null;
29558
+ if (!code)
29559
+ return null;
29560
+ if (outlineCache.has(code))
29561
+ return outlineCache.get(code);
29562
+ try {
29563
+ const res = await fetch(`${OUTLINE_BASE_URL}${code}.json`);
29564
+ if (!res.ok)
29565
+ throw new Error(`Request failed: ${res.status}`);
29566
+ const json = await res.json();
29567
+ outlineCache.set(code, json);
29568
+ return json;
29569
+ } catch (e) {
29570
+ console.warn("[ToEchartsMap] 获取外轮廓数据失败", code, e);
29571
+ outlineCache.set(code, null);
29572
+ return null;
29573
+ }
29574
+ };
29575
+ const setMapOptions = async (geoName, code, mapData) => {
29306
29576
  if (!chart.value)
29307
29577
  return;
29308
29578
  await ensureEchartsGl();
29579
+ let outlineMapName = null;
29580
+ if (props.showOutline && echartsLib) {
29581
+ const outlineJson = await loadOutlineGeoJson(code);
29582
+ if (outlineJson) {
29583
+ outlineMapName = `${geoName}__outline`;
29584
+ try {
29585
+ echartsLib.registerMap(outlineMapName, outlineJson);
29586
+ } catch (e) {
29587
+ console.warn("[ToEchartsMap] 外轮廓 registerMap 失败", e);
29588
+ }
29589
+ }
29590
+ }
29309
29591
  isMapData.value = mapData.length > 0;
29310
- const option = getOption(geoName, mapData);
29592
+ const option = getOption(geoName, code, mapData);
29593
+ if (props.showOutline && !outlineMapName && Array.isArray(option.geo)) {
29594
+ for (const g of option.geo) {
29595
+ if (g && typeof g.map === "string" && g.map === `${geoName}__outline`) {
29596
+ g.map = geoName;
29597
+ }
29598
+ }
29599
+ }
29311
29600
  chart.value.setOption(option, true);
29312
29601
  if (props.autoplay && props.data.length) {
29313
29602
  mapActive(props.data);
@@ -29329,6 +29618,52 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29329
29618
  };
29330
29619
  const getBaseSeries = (geoName, mapData) => {
29331
29620
  var _a2;
29621
+ const getLabelConfig = (isHover = false) => {
29622
+ var _a3;
29623
+ const name = (e) => {
29624
+ var _a4, _b;
29625
+ return (_b = (_a4 = props.nameMap) == null ? void 0 : _a4[e.name]) != null ? _b : e.name;
29626
+ };
29627
+ const fontColor = isHover ? props.fontColorHover || props.fontColor : props.fontColor;
29628
+ const fontSizeValue = isHover ? props.fontSizeHover || props.fontSize : props.fontSize;
29629
+ const fontSize = Number(fontSizeValue) * currentEm.value;
29630
+ const baseLabel = {
29631
+ show: true,
29632
+ color: fontColor,
29633
+ fontSize,
29634
+ lineHeight: fontSize * 1.4,
29635
+ align: "center"
29636
+ };
29637
+ if (!props.showLabelIcon) {
29638
+ return {
29639
+ ...baseLabel,
29640
+ formatter: (e) => `${name(e)}`
29641
+ };
29642
+ }
29643
+ if (props.labelIconType === "image") {
29644
+ const size = (_a3 = props.labelIconSize) != null ? _a3 : 12;
29645
+ const [width, height] = Array.isArray(size) ? size : [size, size];
29646
+ return {
29647
+ ...baseLabel,
29648
+ formatter: (e) => `{a|${name(e)}}
29649
+ {b|}`,
29650
+ rich: {
29651
+ a: { ...baseLabel },
29652
+ b: {
29653
+ backgroundColor: { image: props.labelIcon },
29654
+ width,
29655
+ height,
29656
+ align: "center"
29657
+ }
29658
+ }
29659
+ };
29660
+ }
29661
+ return {
29662
+ ...baseLabel,
29663
+ formatter: (e) => `${name(e)}
29664
+ ${props.labelIcon}`
29665
+ };
29666
+ };
29332
29667
  if (props.is3d) {
29333
29668
  return {
29334
29669
  viewControl: props.viewControl,
@@ -29337,15 +29672,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29337
29672
  data: mapData,
29338
29673
  roam: { zoom: false, rotate: true },
29339
29674
  regionHeight: (Number(props.regionHeight) || 0) * currentEm.value * 0.25,
29340
- label: {
29341
- show: true,
29342
- color: props.fontColor,
29343
- fontSize: Number(props.fontSize) * currentEm.value,
29344
- formatter: (e) => {
29345
- var _a3, _b;
29346
- return ` ${(_b = (_a3 = props.nameMap) == null ? void 0 : _a3[e.name]) != null ? _b : e.name} `;
29347
- }
29348
- },
29675
+ label: getLabelConfig(false),
29676
+ labelLayout: { hideOverlap: true },
29349
29677
  itemStyle: {
29350
29678
  color: props.color || "#65bbff",
29351
29679
  areaColor: props.color,
@@ -29363,11 +29691,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29363
29691
  areaColor: props.colorHover || props.color,
29364
29692
  borderColor: props.borderColorHover || props.borderColor
29365
29693
  },
29366
- label: {
29367
- show: true,
29368
- color: props.fontColorHover || props.fontColor,
29369
- fontSize: (props.fontSizeHover ? Number(props.fontSizeHover) : Number(props.fontSize)) * currentEm.value
29370
- }
29694
+ label: getLabelConfig(true)
29371
29695
  }
29372
29696
  };
29373
29697
  }
@@ -29379,15 +29703,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29379
29703
  data: mapData,
29380
29704
  top: 0,
29381
29705
  bottom: props.shadow ? shadowParts[0] ? Number(shadowParts[0]) * currentEm.value : currentEm.value : 0,
29382
- label: {
29383
- show: true,
29384
- color: props.fontColor,
29385
- fontSize: Number(props.fontSize) * currentEm.value,
29386
- formatter: (e) => {
29387
- var _a3, _b;
29388
- return ` ${(_b = (_a3 = props.nameMap) == null ? void 0 : _a3[e.name]) != null ? _b : e.name} `;
29389
- }
29390
- },
29706
+ label: getLabelConfig(false),
29391
29707
  itemStyle: {
29392
29708
  shadowBlur: itemShadowParts[0] ? Number(itemShadowParts[0]) * currentEm.value : 0,
29393
29709
  shadowColor: (_a2 = itemShadowParts[1]) != null ? _a2 : "rgba(0,0,0,0.3)",
@@ -29403,58 +29719,92 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
29403
29719
  areaColor: props.colorHover || props.color,
29404
29720
  borderColor: props.borderColorHover || props.borderColor
29405
29721
  },
29406
- label: {
29407
- show: true,
29408
- color: props.fontColorHover || props.fontColor,
29409
- fontSize: (props.fontSizeHover ? Number(props.fontSizeHover) : Number(props.fontSize)) * currentEm.value
29410
- }
29722
+ label: getLabelConfig(true)
29411
29723
  },
29412
29724
  select: {
29413
29725
  itemStyle: {
29414
29726
  areaColor: props.colorHover || props.color,
29415
29727
  borderColor: props.borderColorHover || props.borderColor
29416
29728
  },
29417
- label: {
29418
- color: props.fontColorHover || props.fontColor,
29419
- fontSize: (props.fontSizeHover ? Number(props.fontSizeHover) : Number(props.fontSize)) * currentEm.value
29420
- }
29729
+ label: getLabelConfig(true)
29421
29730
  }
29422
29731
  };
29423
29732
  };
29424
- const getOption = (geoName, mapData) => {
29733
+ const getOption = (geoName, code, mapData) => {
29425
29734
  var _a2;
29426
29735
  const baseSeries = getBaseSeries(geoName, mapData);
29427
29736
  const shadowParts = parseShadow(props.shadow);
29428
29737
  const { min, max: max2 } = getMinMax(mapData);
29429
- return {
29430
- tooltip: {
29431
- trigger: "item",
29432
- formatter: (params) => {
29433
- if (!params.value)
29434
- return "";
29435
- return renderTooltip(params);
29436
- }
29437
- },
29438
- geo: {
29439
- // 轮廓线与底部阴影共用 geo:
29440
- // - shadow:用 geo 的 areaColor 作为底部投影层
29441
- // - showOutline:用 geo 的 borderColor/borderWidth 画最外围轮廓线
29442
- show: Boolean(props.shadow) || props.showOutline,
29738
+ const geoLayers = [];
29739
+ if (props.shadow) {
29740
+ const shadowOffset = shadowParts[0] ? Number(shadowParts[0]) * currentEm.value : currentEm.value;
29741
+ const shadowColor = (_a2 = shadowParts[1]) != null ? _a2 : "rgba(0,0,0,0.3)";
29742
+ const shadow2Color = shadowParts[2];
29743
+ if (shadow2Color) {
29744
+ geoLayers.push({
29745
+ z: 1,
29746
+ show: true,
29747
+ map: geoName,
29748
+ roam: false,
29749
+ top: shadowOffset * 2,
29750
+ bottom: -shadowOffset,
29751
+ silent: true,
29752
+ itemStyle: {
29753
+ areaColor: shadow2Color,
29754
+ borderColor: "transparent"
29755
+ }
29756
+ });
29757
+ }
29758
+ geoLayers.push({
29759
+ z: 2,
29760
+ show: true,
29443
29761
  map: geoName,
29444
29762
  roam: false,
29445
- top: props.shadow ? shadowParts[0] ? Number(shadowParts[0]) * currentEm.value : currentEm.value : 0,
29763
+ top: shadowOffset,
29446
29764
  bottom: 0,
29447
29765
  silent: true,
29448
- label: { show: false },
29449
29766
  itemStyle: {
29450
- areaColor: props.shadow ? (_a2 = shadowParts[1]) != null ? _a2 : "rgba(0,0,0,0.3)" : "transparent",
29451
- borderColor: props.showOutline ? props.outlineColor : "transparent",
29452
- borderWidth: props.showOutline ? Number(props.outlineWidth) : 0,
29453
- // 避免粗描边在尖锐拐角处产生 miter 尖刺
29767
+ areaColor: shadowColor,
29768
+ borderColor: "transparent"
29769
+ }
29770
+ });
29771
+ }
29772
+ if (props.showOutline) {
29773
+ const shadowOffset = shadowParts[0] ? Number(shadowParts[0]) * currentEm.value : currentEm.value;
29774
+ const outlineMapName = `${geoName}__outline`;
29775
+ geoLayers.push({
29776
+ z: 2,
29777
+ // 低于 map series (z:3),避免盖住 label
29778
+ map: outlineMapName,
29779
+ roam: false,
29780
+ top: 0,
29781
+ bottom: props.shadow ? shadowOffset : 0,
29782
+ silent: true,
29783
+ itemStyle: {
29784
+ areaColor: "transparent",
29785
+ borderColor: props.outlineColor,
29786
+ borderWidth: Number(props.outlineWidth),
29454
29787
  borderJoin: "round",
29455
29788
  borderMiterLimit: 2
29456
29789
  }
29457
- },
29790
+ });
29791
+ }
29792
+ baseSeries.z = 3;
29793
+ const tooltipConfig = {
29794
+ trigger: "item",
29795
+ formatter: (params) => {
29796
+ if (!params.value)
29797
+ return "";
29798
+ return renderTooltip(params);
29799
+ }
29800
+ };
29801
+ if (props.position) {
29802
+ tooltipConfig.position = props.position;
29803
+ }
29804
+ tooltipConfig.confine = true;
29805
+ return {
29806
+ tooltip: tooltipConfig,
29807
+ geo: geoLayers,
29458
29808
  visualMap: showVisualMap() ? {
29459
29809
  seriesIndex: [0],
29460
29810
  min,