@arronqzy/react-view 1.0.11 → 1.0.13

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.
@@ -4,6 +4,7 @@ import { useI18n } from "@arronqzy/i18n/react";
4
4
  import {
5
5
  BlueprintExecutionLogPanel,
6
6
  BlueprintNodeConfigSidebar,
7
+ type BlueprintGraphEdge,
7
8
  type BlueprintGraphNode,
8
9
  type ExecutionLogSettings,
9
10
  type ExecutionTraceEntry,
@@ -41,6 +42,8 @@ export type WorkspaceConfigSidebarProps = Omit<
41
42
  configFocus: WorkspaceConfigFocus;
42
43
  executionLog?: BlueprintExecutionLogViewProps;
43
44
  selectedBlueprintNode: BlueprintGraphNode | null;
45
+ blueprintGraphNodes?: BlueprintGraphNode[];
46
+ blueprintGraphEdges?: BlueprintGraphEdge[];
44
47
  allowFalseSignalPropagation?: boolean;
45
48
  onUpdateAllowFalseSignalPropagation?: (value: boolean) => void;
46
49
  onUpdateBlueprintNode: (
@@ -74,6 +77,8 @@ export function WorkspaceConfigSidebar({
74
77
  configFocus,
75
78
  executionLog,
76
79
  selectedBlueprintNode,
80
+ blueprintGraphNodes = [],
81
+ blueprintGraphEdges = [],
77
82
  allowFalseSignalPropagation = false,
78
83
  onUpdateAllowFalseSignalPropagation,
79
84
  onUpdateBlueprintNode,
@@ -151,6 +156,9 @@ export function WorkspaceConfigSidebar({
151
156
  return (
152
157
  <BlueprintNodeConfigSidebar
153
158
  node={selectedBlueprintNode}
159
+ graphNodes={blueprintGraphNodes}
160
+ graphEdges={blueprintGraphEdges}
161
+ traceEntries={executionLog?.entries}
154
162
  allowFalseSignalPropagation={allowFalseSignalPropagation}
155
163
  onUpdateAllowFalseSignalPropagation={onUpdateAllowFalseSignalPropagation}
156
164
  viewElementOptions={viewElementOptions}
@@ -84,6 +84,45 @@ function deepMerge<T extends Record<string, any>>(base: T, patch?: Record<string
84
84
  return next as T;
85
85
  }
86
86
 
87
+ function resolveBarWidth(chart?: PanelChartConfig): number | undefined {
88
+ const width = chart?.barWidth;
89
+ return typeof width === "number" && Number.isFinite(width) && width > 0 ? width : undefined;
90
+ }
91
+
92
+ function mixHex(a: string, b: string, t: number): string {
93
+ const pa = parseHex(a);
94
+ const pb = parseHex(b);
95
+ if (!pa || !pb) return a;
96
+ const m = (i: number) => Math.round(pa[i]! * (1 - t) + pb[i]! * t);
97
+ return `#${[m(0), m(1), m(2)].map((n) => n.toString(16).padStart(2, "0")).join("")}`;
98
+ }
99
+
100
+ function parseHex(hex: string): [number, number, number] | null {
101
+ const s = hex.replace("#", "").trim();
102
+ const full =
103
+ s.length === 3
104
+ ? s
105
+ .split("")
106
+ .map((c) => c + c)
107
+ .join("")
108
+ : s.slice(0, 6);
109
+ if (!/^[0-9a-fA-F]{6}$/.test(full)) return null;
110
+ return [
111
+ Number.parseInt(full.slice(0, 2), 16),
112
+ Number.parseInt(full.slice(2, 4), 16),
113
+ Number.parseInt(full.slice(4, 6), 16),
114
+ ];
115
+ }
116
+
117
+ function pieSliceColors(base: string, count: number): string[] {
118
+ const n = Math.max(count, 1);
119
+ if (n === 1) return [base];
120
+ return Array.from({ length: n }, (_, i) => {
121
+ const t = n === 1 ? 0 : i / (n - 1);
122
+ return mixHex(mixHex(base, "#111827", 0.12), "#fefce8", t * 0.45);
123
+ });
124
+ }
125
+
87
126
  export function buildChartOption(element: PanelElement): EChartsOption {
88
127
  const chartType = (element.materialType ?? "") as ChartType;
89
128
  const labels = resolveChartLabels(element);
@@ -144,10 +183,11 @@ export function buildChartOption(element: PanelElement): EChartsOption {
144
183
  if (chartType === "pie") {
145
184
  const inner = element.chart?.pieInnerRadius ?? 30;
146
185
  const outer = element.chart?.pieOuterRadius ?? 65;
186
+ const sliceColors = pieSliceColors(color, labels.length);
147
187
  const baseOption: EChartsOption = {
148
188
  animation: false,
149
189
  title: { text: title, left: "center", top: 6, textStyle: { fontSize: 12 } },
150
- color: [chartColor as any],
190
+ color: sliceColors as any,
151
191
  tooltip: tooltipOption,
152
192
  series: [
153
193
  {
@@ -155,7 +195,11 @@ export function buildChartOption(element: PanelElement): EChartsOption {
155
195
  radius: [`${inner}%`, `${outer}%`],
156
196
  center: ["50%", "58%"],
157
197
  label: { fontSize: 10 },
158
- data: labels.map((name, i) => ({ name, value: values[i] ?? 0 })),
198
+ data: labels.map((name, i) => ({
199
+ name,
200
+ value: values[i] ?? 0,
201
+ itemStyle: { color: sliceColors[i % sliceColors.length] as any },
202
+ })),
159
203
  },
160
204
  ],
161
205
  };
@@ -315,7 +359,8 @@ export function buildChartOption(element: PanelElement): EChartsOption {
315
359
  chartType === "line" || chartType === "area"
316
360
  ? (element.chart?.smooth ?? true)
317
361
  : undefined,
318
- barWidth: chartType === "bar" ? (element.chart?.barWidth ?? 24) : undefined,
362
+ barWidth:
363
+ chartType === "bar" ? resolveBarWidth(element.chart) : undefined,
319
364
  areaStyle: chartType === "area" ? { opacity: 0.25 } : undefined,
320
365
  itemStyle: { color: chartColor as any },
321
366
  lineStyle: { color: chartColor as any },
@@ -0,0 +1,69 @@
1
+ /** 产物预览是否缩放内部内容(字体等)。默认 false:块仍按视口撑满,内容保持原尺寸以免失真。 */
2
+ export const OUTPUT_SCALE_STORAGE_KEY = "panel:outputScale";
3
+
4
+ export function readOutputScale(): boolean {
5
+ try {
6
+ return localStorage.getItem(OUTPUT_SCALE_STORAGE_KEY) === "1";
7
+ } catch {
8
+ return false;
9
+ }
10
+ }
11
+
12
+ export function writeOutputScale(enabled: boolean) {
13
+ try {
14
+ localStorage.setItem(OUTPUT_SCALE_STORAGE_KEY, enabled ? "1" : "0");
15
+ } catch {
16
+ // ignore storage errors
17
+ }
18
+ }
19
+
20
+ export type PreviewFillScale = {
21
+ vw: number;
22
+ vh: number;
23
+ scaleX: number;
24
+ scaleY: number;
25
+ };
26
+
27
+ export function getPreviewFillScale(
28
+ sceneWidth: number,
29
+ sceneHeight: number
30
+ ): PreviewFillScale {
31
+ const vw = window.innerWidth || 1;
32
+ const vh = window.innerHeight || 1;
33
+ const sw = Math.max(1, sceneWidth);
34
+ const sh = Math.max(1, sceneHeight);
35
+ return {
36
+ vw,
37
+ vh,
38
+ scaleX: vw / sw,
39
+ scaleY: vh / sh,
40
+ };
41
+ }
42
+
43
+ /**
44
+ * 预览始终按视口宽高比把场景块撑满。
45
+ * outputScale=true:CSS transform 缩放整棵内容(含字体)。
46
+ * outputScale=false:只把场景盒拉到视口大小,节点几何由调用方按 scale 映射,字体不跟着拉伸。
47
+ */
48
+ export function applyPreviewSceneFill(
49
+ scene: HTMLElement | null,
50
+ sceneWidth: number,
51
+ sceneHeight: number,
52
+ outputScale: boolean
53
+ ): PreviewFillScale {
54
+ const fill = getPreviewFillScale(sceneWidth, sceneHeight);
55
+ if (!Number.isFinite(fill.scaleX) || !Number.isFinite(fill.scaleY)) return fill;
56
+ if (!scene) return fill;
57
+ const root = scene.parentElement;
58
+ if (root) root.style.overflow = "hidden";
59
+ if (outputScale) {
60
+ scene.style.width = `${Math.max(1, sceneWidth)}px`;
61
+ scene.style.height = `${Math.max(1, sceneHeight)}px`;
62
+ scene.style.transform = `translate(0px,0px) scale(${fill.scaleX},${fill.scaleY})`;
63
+ } else {
64
+ scene.style.width = `${fill.vw}px`;
65
+ scene.style.height = `${fill.vh}px`;
66
+ scene.style.transform = "none";
67
+ }
68
+ return fill;
69
+ }
@@ -126,7 +126,6 @@ export function getDefaultChartConfig(
126
126
  return {
127
127
  title: t("panel.defaults.bar"),
128
128
  ...common,
129
- barWidth: 24,
130
129
  };
131
130
  }
132
131
  if (materialType === "line") {