@lionad/cx-comps-tanstack-charts 0.1.0-alpha.18 → 0.1.0-alpha.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/chart/src/motion-chart.vue.d.ts +15 -0
- package/dist/index.mjs +131 -25
- package/dist/shared/translate/types.d.ts +23 -0
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CxChartSpec } from '../../shared/translate';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** 运行时 DomChartDefinition(translateChartSpec 产物,已含 chart 级 motion 时序) */
|
|
4
|
+
definition: Record<string, unknown>;
|
|
5
|
+
ariaLabel: string;
|
|
6
|
+
/** spec.motion 的 renderer 级选项(initial/resize);transition/delay 已在 definition.motion */
|
|
7
|
+
motionOptions?: CxChartSpec['motion'];
|
|
8
|
+
height?: number;
|
|
9
|
+
width?: number;
|
|
10
|
+
aspectRatio?: number;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { define } from "@lionad/cx-definition";
|
|
2
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, renderList, unref, useAttrs } from "vue";
|
|
2
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, unref, useAttrs, useId, watch } from "vue";
|
|
3
3
|
import { Chart } from "@tanstack/charts/vue";
|
|
4
4
|
import { useCxBEM } from "@lionad/cx-vue";
|
|
5
5
|
import { areaX, areaY, arrow, bandX, bandY, barX, barY, binX, binXY, binY, boxRows, boxX, boxY, cell, colorGradientLegend, colorLegend, cumulative, d3Curve, defaultChartTheme, defineChart, delta, deviation, differenceX, differenceY, dodgeX, dodgeY, dot, first, fold, frame, group, groupBy, hexagon, last, lineX, lineY, linearRegressionRowsX, linearRegressionRowsY, linearRegressionX, linearRegressionY, link, median, mosaicX, mosaicY, normalize, quantile, rank, ratio, rect, ridgelineX, ridgelineY, rollingWindow, ruleX, ruleY, select, stack, stackRowsX, stackRowsY, text, tickX, tickY, variance, vector, violinX, violinY, waffleX, waffleY, waterfall } from "@tanstack/charts";
|
|
6
6
|
import { d3AreaXCurve } from "@tanstack/charts/d3/area-x";
|
|
7
|
-
import { curveBasis, curveCatmullRom, curveLinear, curveLinearClosed, curveMonotoneX, curveNatural, curveStep, curveStepAfter, curveStepBefore } from "d3-shape";
|
|
7
|
+
import { curveBasis, curveBumpX, curveCatmullRom, curveLinear, curveLinearClosed, curveMonotoneX, curveNatural, curveStep, curveStepAfter, curveStepBefore } from "d3-shape";
|
|
8
8
|
import { scaleLinear } from "@tanstack/charts/scales/linear";
|
|
9
9
|
import { scaleOrdinal } from "@tanstack/charts/scales/ordinal";
|
|
10
10
|
import { scalePoint } from "@tanstack/charts/scales/point";
|
|
@@ -27,9 +27,12 @@ import { geoAlbersUsa, geoEqualEarth, geoEquirectangular, geoIdentity, geoMercat
|
|
|
27
27
|
import { decorative } from "@tanstack/charts/mark/decorative";
|
|
28
28
|
import { tooltip } from "@tanstack/charts/tooltip";
|
|
29
29
|
import { viewGrid } from "@tanstack/charts/view";
|
|
30
|
+
import "@tanstack/charts/adapter";
|
|
31
|
+
import { createChartRendererAdapter } from "@tanstack/charts/adapter/renderer";
|
|
32
|
+
import { motion } from "@tanstack/charts/motion";
|
|
30
33
|
import { compileTrigger, createTriggerRegistry } from "@lionad/cx-stream";
|
|
31
34
|
//#region src/shared/chart-skeleton.vue
|
|
32
|
-
const _sfc_main$
|
|
35
|
+
const _sfc_main$7 = /*@__PURE__*/ defineComponent({
|
|
33
36
|
__name: "chart-skeleton",
|
|
34
37
|
props: { height: { default: 320 } },
|
|
35
38
|
setup(__props) {
|
|
@@ -910,6 +913,18 @@ function hierarchyOptions(spec, idKey) {
|
|
|
910
913
|
function hierarchyFieldChannel(field) {
|
|
911
914
|
return (node) => node?.data?.[field];
|
|
912
915
|
}
|
|
916
|
+
/**
|
|
917
|
+
* sankey 布局行顶层只有 canonical 字段(key/width/坐标),原 datum 收纳在 .data 下;
|
|
918
|
+
* 声明式样式字段名(如 stroke:"色调"、color:"id")须穿透到原 datum 解析,
|
|
919
|
+
* 否则 channel 按顶层查表得 undefined 而静默退回默认样式。
|
|
920
|
+
*/
|
|
921
|
+
function sankeyDatumField(field) {
|
|
922
|
+
return (row) => {
|
|
923
|
+
const record = row;
|
|
924
|
+
if (record.data != null && field in record.data) return record.data[field];
|
|
925
|
+
return record[field];
|
|
926
|
+
};
|
|
927
|
+
}
|
|
913
928
|
/** sankey:固化 marks 回调 = link(布局连线) + rect(布局节点),样式取自声明 */
|
|
914
929
|
function translateSankey(spec, datasets) {
|
|
915
930
|
const nodes = resolveMarkData(spec.nodes, datasets);
|
|
@@ -922,25 +937,30 @@ function translateSankey(spec, datasets) {
|
|
|
922
937
|
source: spec.source,
|
|
923
938
|
target: spec.target,
|
|
924
939
|
value: spec.value,
|
|
925
|
-
marks: (context) =>
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
940
|
+
marks: (context) => {
|
|
941
|
+
const strokeField = typeof spec.stroke === "string" && context.links.some((l) => l?.data?.[spec.stroke] !== void 0) ? spec.stroke : null;
|
|
942
|
+
return [looseLink(context.links, {
|
|
943
|
+
x1: "x1",
|
|
944
|
+
y1: "y1",
|
|
945
|
+
x2: "x2",
|
|
946
|
+
y2: "y2",
|
|
947
|
+
key: "key",
|
|
948
|
+
strokeWidth: (row) => Math.max(1, Number(row.width) || 1),
|
|
949
|
+
lineCap: "butt",
|
|
950
|
+
curve: d3Curve(curveBumpX),
|
|
951
|
+
color: strokeField ? sankeyDatumField(strokeField) : void 0,
|
|
952
|
+
stroke: strokeField ? void 0 : spec.stroke ?? void 0,
|
|
953
|
+
strokeOpacity: spec.strokeOpacity ?? .55
|
|
954
|
+
}), looseRect(context.nodes, {
|
|
955
|
+
x1: "x0",
|
|
956
|
+
x2: "x1",
|
|
957
|
+
y1: "y0",
|
|
958
|
+
y2: "y1",
|
|
959
|
+
key: "key",
|
|
960
|
+
color: typeof spec.color === "string" ? sankeyDatumField(spec.color) : spec.color ?? "key",
|
|
961
|
+
fillOpacity: spec.fillOpacity ?? void 0
|
|
962
|
+
})];
|
|
963
|
+
}
|
|
944
964
|
};
|
|
945
965
|
if (spec.id !== void 0) options.id = spec.id;
|
|
946
966
|
if (spec.align !== void 0) options.align = spec.align;
|
|
@@ -1422,7 +1442,8 @@ function buildDefinition(spec, datasets, rowsOverride, mode = "host") {
|
|
|
1422
1442
|
"pointer",
|
|
1423
1443
|
"keyboard",
|
|
1424
1444
|
"focusRing",
|
|
1425
|
-
"focus"
|
|
1445
|
+
"focus",
|
|
1446
|
+
"motion"
|
|
1426
1447
|
]) if (spec[key] !== void 0) throw new Error(`translateViewGrid 子视图不得声明 "${key}"(host 权属字段,配置在外层 spec)`);
|
|
1427
1448
|
return definition;
|
|
1428
1449
|
}
|
|
@@ -1430,6 +1451,12 @@ function buildDefinition(spec, datasets, rowsOverride, mode = "host") {
|
|
|
1430
1451
|
if (spec.keyboard !== void 0) definition.keyboard = spec.keyboard;
|
|
1431
1452
|
if (spec.focusRing !== void 0) definition.focusRing = spec.focusRing;
|
|
1432
1453
|
if (spec.focus !== void 0) definition.focus = spec.focus;
|
|
1454
|
+
if (spec.motion !== void 0) {
|
|
1455
|
+
const timing = {};
|
|
1456
|
+
if (spec.motion.transition !== void 0) timing.transition = spec.motion.transition;
|
|
1457
|
+
if (spec.motion.delay !== void 0) timing.delay = spec.motion.delay;
|
|
1458
|
+
definition.motion = timing;
|
|
1459
|
+
}
|
|
1433
1460
|
const tooltip$2 = spec.tooltip === void 0 ? tooltip : translateTooltip(spec.tooltip);
|
|
1434
1461
|
if (tooltip$2 !== void 0) definition.tooltip = tooltip$2;
|
|
1435
1462
|
return definition;
|
|
@@ -1460,6 +1487,77 @@ function translateChartSpec(spec, datasets) {
|
|
|
1460
1487
|
return defineChart(buildDefinition(spec, datasets));
|
|
1461
1488
|
}
|
|
1462
1489
|
//#endregion
|
|
1490
|
+
//#region src/chart/src/motion-chart.vue
|
|
1491
|
+
const _hoisted_1 = ["innerHTML"];
|
|
1492
|
+
const _sfc_main$6 = /*@__PURE__*/ defineComponent({
|
|
1493
|
+
__name: "motion-chart",
|
|
1494
|
+
props: {
|
|
1495
|
+
definition: {},
|
|
1496
|
+
ariaLabel: {},
|
|
1497
|
+
motionOptions: {},
|
|
1498
|
+
height: {},
|
|
1499
|
+
width: {},
|
|
1500
|
+
aspectRatio: {},
|
|
1501
|
+
className: {}
|
|
1502
|
+
},
|
|
1503
|
+
setup(__props) {
|
|
1504
|
+
const props = __props;
|
|
1505
|
+
const idPrefix = `ts-chart-${useId().replaceAll(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
1506
|
+
const hostStyle = computed(() => ({
|
|
1507
|
+
position: "relative",
|
|
1508
|
+
width: props.width === void 0 ? "100%" : `${props.width}px`,
|
|
1509
|
+
height: props.height ?? (props.aspectRatio === void 0 ? 320 : void 0),
|
|
1510
|
+
aspectRatio: props.height === void 0 ? props.aspectRatio : void 0
|
|
1511
|
+
}));
|
|
1512
|
+
/** host options 组装:与库 vue adapter toHostOptions 同构,renderer 固定为 motion() */
|
|
1513
|
+
function toHostOptions() {
|
|
1514
|
+
return {
|
|
1515
|
+
definition: props.definition,
|
|
1516
|
+
ariaLabel: props.ariaLabel,
|
|
1517
|
+
height: props.height,
|
|
1518
|
+
width: props.width,
|
|
1519
|
+
aspectRatio: props.aspectRatio,
|
|
1520
|
+
className: props.className,
|
|
1521
|
+
idPrefix,
|
|
1522
|
+
renderer: motion({
|
|
1523
|
+
initial: props.motionOptions?.initial ?? true,
|
|
1524
|
+
resize: props.motionOptions?.resize
|
|
1525
|
+
})
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1528
|
+
const adapter = createChartRendererAdapter(toHostOptions());
|
|
1529
|
+
const initialMarkup = adapter.prerender();
|
|
1530
|
+
const container = ref();
|
|
1531
|
+
onMounted(() => {
|
|
1532
|
+
if (!container.value) return;
|
|
1533
|
+
adapter.update(toHostOptions());
|
|
1534
|
+
adapter.mount(container.value);
|
|
1535
|
+
});
|
|
1536
|
+
watch(() => [
|
|
1537
|
+
props.definition,
|
|
1538
|
+
props.height,
|
|
1539
|
+
props.width,
|
|
1540
|
+
props.aspectRatio
|
|
1541
|
+
], () => adapter.update(toHostOptions()));
|
|
1542
|
+
onBeforeUnmount(() => adapter.destroy());
|
|
1543
|
+
return (_ctx, _cache) => {
|
|
1544
|
+
return openBlock(), createElementBlock("div", {
|
|
1545
|
+
class: "ts-chart-host",
|
|
1546
|
+
style: normalizeStyle(hostStyle.value)
|
|
1547
|
+
}, [createCommentVNode(" 首帧 markup 只注入一次:mount 后 DOM 由 motion renderer 接管(含动画态),\n 若随重渲染重设 innerHTML 会摧毁动画状态,故用非响应式常量 "), createElementVNode("div", {
|
|
1548
|
+
ref_key: "container",
|
|
1549
|
+
ref: container,
|
|
1550
|
+
class: "ts-chart-surface",
|
|
1551
|
+
style: {
|
|
1552
|
+
"width": "100%",
|
|
1553
|
+
"height": "100%"
|
|
1554
|
+
},
|
|
1555
|
+
innerHTML: unref(initialMarkup)
|
|
1556
|
+
}, null, 8, _hoisted_1)], 4);
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
});
|
|
1560
|
+
//#endregion
|
|
1463
1561
|
//#region src/chart/src/index.vue
|
|
1464
1562
|
const _sfc_main$5 = /*@__PURE__*/ defineComponent({
|
|
1465
1563
|
name: "CxTanstackChartsChart",
|
|
@@ -1479,10 +1577,18 @@ const _sfc_main$5 = /*@__PURE__*/ defineComponent({
|
|
|
1479
1577
|
return openBlock(), createElementBlock(Fragment, null, [createCommentVNode(" 库根元素 inheritAttrs:false 且多根(host + tooltip Teleport),testid/BEM 类须由本层 wrapper 承担。\n cx-charts 为主题桥作用域类(cx-comps charts-theme 映射 design token 到 --ts-chart-N/--chart-N):\n 随组件自动声明,宿主无需手动加类——shadcn 系 spec 的 var(--chart-N, ...) 引用在此获得色板 "), createElementVNode("div", {
|
|
1480
1578
|
class: normalizeClass([unref(ns).b(), "cx-charts"]),
|
|
1481
1579
|
"data-testid": "cx-tanstack-charts-chart"
|
|
1482
|
-
}, [createCommentVNode(" definition 未闭合期间骨架占位:空壳帧的空 marks 只渲染不可见空 svg,无反馈等同未渲染 "), isStreaming.value ? (openBlock(), createBlock(_sfc_main$
|
|
1580
|
+
}, [createCommentVNode(" definition 未闭合期间骨架占位:空壳帧的空 marks 只渲染不可见空 svg,无反馈等同未渲染 "), isStreaming.value ? (openBlock(), createBlock(_sfc_main$7, {
|
|
1483
1581
|
key: 0,
|
|
1484
1582
|
height: skeletonHeight.value
|
|
1485
|
-
}, null, 8, ["height"])) : (openBlock(),
|
|
1583
|
+
}, null, 8, ["height"])) : unref(spec).motion !== void 0 ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" motion 声明走自研挂载分支:库 vue adapter 无 motion renderer 注入口子 "), createVNode(_sfc_main$6, mergeProps({
|
|
1584
|
+
definition: definition.value,
|
|
1585
|
+
ariaLabel: unref(ariaLabel),
|
|
1586
|
+
"motion-options": unref(spec).motion
|
|
1587
|
+
}, unref(hostProps)), null, 16, [
|
|
1588
|
+
"definition",
|
|
1589
|
+
"ariaLabel",
|
|
1590
|
+
"motion-options"
|
|
1591
|
+
])], 2112)) : (openBlock(), createBlock(unref(Chart), mergeProps({ key: 2 }, unref(hostProps), {
|
|
1486
1592
|
definition: definition.value,
|
|
1487
1593
|
"aria-label": unref(ariaLabel)
|
|
1488
1594
|
}), null, 16, ["definition", "aria-label"]))], 2)], 2112);
|
|
@@ -550,4 +550,27 @@ export interface CxChartSpec {
|
|
|
550
550
|
keyboard?: boolean;
|
|
551
551
|
focusRing?: boolean;
|
|
552
552
|
focus?: 'nearest' | 'nearest-x' | 'nearest-y' | 'group-x' | 'group-y';
|
|
553
|
+
/**
|
|
554
|
+
* 动效声明(可 JSON 化子集)。声明即走 motion 挂载分支:库 vue adapter 未暴露
|
|
555
|
+
* motion renderer 注入,cx 组件层自组装 renderer adapter。transition/delay 翻译为
|
|
556
|
+
* 库 definition.motion 的 chart 级默认时序;initial/resize 为 renderer 级选项。
|
|
557
|
+
* mark 级 per-datum motion 回调不可 JSON 化,不收。
|
|
558
|
+
*/
|
|
559
|
+
motion?: {
|
|
560
|
+
transition?: {
|
|
561
|
+
type: 'tween';
|
|
562
|
+
duration?: number;
|
|
563
|
+
easing?: 'linear' | 'ease' | 'ease-in' | 'ease-out' | 'ease-in-out';
|
|
564
|
+
} | {
|
|
565
|
+
type: 'spring';
|
|
566
|
+
stiffness?: number;
|
|
567
|
+
damping?: number;
|
|
568
|
+
mass?: number;
|
|
569
|
+
restSpeed?: number;
|
|
570
|
+
restDelta?: number;
|
|
571
|
+
};
|
|
572
|
+
delay?: number;
|
|
573
|
+
initial?: boolean | 'always';
|
|
574
|
+
resize?: boolean;
|
|
575
|
+
};
|
|
553
576
|
}
|