@iyulab/u-widgets 0.9.1 → 0.10.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"u-widgets-charts.js","sources":["../src/renderers/echarts-adapter.ts","../src/elements/uw-chart.ts"],"sourcesContent":["import type { UWidgetSpec, NormalizedMapping, ReferenceLineOption, AxisFormatOption } from '../core/types.js';\nimport { formatValue } from '../core/format.js';\nimport { normalizeMapping } from '../core/normalize.js';\n\ninterface ConditionalStyleRule {\n field: string;\n above?: number;\n below?: number;\n color: string;\n symbol?: string;\n symbolSize?: number;\n}\n\nfunction matchConditionalStyle(\n row: Record<string, unknown>,\n rules: ConditionalStyleRule[],\n): ConditionalStyleRule | undefined {\n for (const rule of rules) {\n const raw = row[rule.field];\n if (raw === undefined || raw === null) continue;\n const val = Number(raw);\n if (Number.isNaN(val)) continue;\n const aboveOk = rule.above === undefined || val > rule.above;\n const belowOk = rule.below === undefined || val < rule.below;\n if (aboveOk && belowOk) return rule;\n }\n return undefined;\n}\n\n/**\n * Translate a u-widget spec into an ECharts option object.\n * This is a pure function with no DOM or ECharts dependency.\n *\n * Supports `options.echarts` passthrough: any key-value pairs in\n * `options.echarts` are deep-merged (one level) into the generated\n * ECharts option, allowing full customization.\n */\nexport function toEChartsOption(spec: UWidgetSpec): Record<string, unknown> {\n const widget = spec.widget;\n const data = spec.data;\n const mapping = spec.mapping ? normalizeMapping(spec.mapping) : undefined;\n const options = spec.options ?? {};\n\n if (!data) return {};\n\n let result: Record<string, unknown>;\n\n switch (widget) {\n case 'chart.bar':\n result = buildCartesian(data, mapping, 'bar', options);\n break;\n case 'chart.line':\n result = buildCartesian(data, mapping, 'line', options);\n break;\n case 'chart.area':\n result = buildCartesian(data, mapping, 'line', { ...options, _area: true });\n break;\n case 'chart.pie':\n result = buildPie(data, mapping, options);\n break;\n case 'chart.scatter':\n result = buildScatter(data, mapping, options);\n break;\n case 'chart.radar':\n result = buildRadar(data, mapping, options);\n break;\n case 'chart.heatmap':\n result = buildHeatmap(data, mapping, options);\n break;\n case 'chart.box':\n result = buildBoxplot(data, mapping, options);\n break;\n case 'chart.funnel':\n result = buildFunnel(data, mapping, options);\n break;\n case 'chart.waterfall':\n result = buildWaterfall(data, mapping, options);\n break;\n case 'chart.treemap':\n result = buildTreemap(data, options);\n break;\n case 'chart.histogram':\n result = buildHistogram(data, mapping, options);\n break;\n default:\n return {};\n }\n\n // Apply chart-level options\n if (options.legend === false && result.legend) {\n result.legend = { ...result.legend as Record<string, unknown>, show: false };\n }\n\n if (options.grid === false) {\n // Hide grid lines on axes\n if (result.xAxis && typeof result.xAxis === 'object' && !Array.isArray(result.xAxis)) {\n result.xAxis = { ...result.xAxis as Record<string, unknown>, splitLine: { show: false } };\n }\n if (result.yAxis && typeof result.yAxis === 'object' && !Array.isArray(result.yAxis)) {\n result.yAxis = { ...result.yAxis as Record<string, unknown>, splitLine: { show: false } };\n }\n }\n\n if (options.animate === false) {\n result.animation = false;\n }\n\n if (Array.isArray(options.colors) && options.colors.length > 0) {\n result.color = options.colors;\n }\n\n // Apply axis format options\n const locale = options.locale as string | undefined;\n applyAxisFormat(result, 'xAxis', options.xFormat as AxisFormatOption | undefined, locale);\n applyAxisFormat(result, 'yAxis', options.yFormat as AxisFormatOption | undefined, locale);\n\n // Apply echarts passthrough: deep-merge\n const passthrough = options.echarts as Record<string, unknown> | undefined;\n if (passthrough && typeof passthrough === 'object') {\n result = deepMerge(result, passthrough);\n }\n\n return result;\n}\n\nfunction buildCartesian(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n type: string,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const xField = mapping?.x ?? guessStringField(data);\n const yFields = mapping?.y ?? [guessNumberField(data)].filter(Boolean) as string[];\n\n if (!xField || yFields.length === 0) return {};\n\n const categories = data.map((row) => String(row[xField] ?? ''));\n const horizontal = !!options.horizontal;\n\n const seriesOverrides = Array.isArray(options.series) ? options.series as Record<string, unknown>[] : [];\n const condStyles = options.conditionalStyles as ConditionalStyleRule[] | undefined;\n\n const seriesItems = yFields.map((field, i) => {\n const s: Record<string, unknown> = {\n name: field,\n type,\n data: data.map((row) => {\n const val = row[field] ?? null;\n if (condStyles?.length) {\n const match = matchConditionalStyle(row, condStyles);\n if (match) {\n const item: Record<string, unknown> = { value: val, itemStyle: { color: match.color } };\n if (match.symbol) item.symbol = match.symbol;\n if (match.symbolSize) item.symbolSize = match.symbolSize;\n return item;\n }\n }\n return val;\n }),\n };\n if (options._area) s.areaStyle = {};\n if (options.smooth) s.smooth = true;\n if (options.step) s.step = options.step === true ? 'end' : options.step;\n\n // Apply per-series overrides from options.series[i]\n const override = seriesOverrides[i];\n if (override) {\n if (override.color) {\n s.itemStyle = { color: override.color };\n s.lineStyle = { ...(s.lineStyle as Record<string, unknown> ?? {}), color: override.color };\n }\n if (override.lineStyle) {\n s.lineStyle = { ...(s.lineStyle as Record<string, unknown> ?? {}), ...(override.lineStyle as Record<string, unknown>) };\n }\n if (override.symbol !== undefined) s.symbol = override.symbol;\n if (override.label) s.name = override.label as string;\n if (override.type) s.type = override.type as string;\n if (override.yAxisIndex !== undefined) s.yAxisIndex = override.yAxisIndex;\n }\n return s;\n });\n\n const catAxis: Record<string, unknown> = { type: 'category', data: categories };\n const valAxis: Record<string, unknown> = { type: 'value' };\n\n // Histogram mode: remove gaps between bars\n if (options.histogram) {\n catAxis.axisTick = { alignWithLabel: true };\n seriesItems.forEach((s) => { s.barCategoryGap = '0%'; });\n }\n\n // Detect if any series requires a secondary Y axis\n const needsDualYAxis = !horizontal && seriesItems.some((s) => (s.yAxisIndex as number) >= 1);\n let yAxisConfig: unknown;\n if (needsDualYAxis) {\n const secondAxis = Array.isArray(options.yAxis) && (options.yAxis as unknown[]).length >= 2\n ? (options.yAxis as Record<string, unknown>[])[1]\n : { type: 'value' };\n yAxisConfig = [valAxis, secondAxis];\n } else {\n yAxisConfig = horizontal ? catAxis : valAxis;\n }\n\n const result: Record<string, unknown> = {\n xAxis: horizontal ? valAxis : catAxis,\n yAxis: yAxisConfig,\n series: seriesItems,\n tooltip: { trigger: 'axis' },\n };\n\n if (yFields.length > 1) {\n const legendNames = seriesItems.map((s) => s.name as string);\n result.legend = { data: legendNames };\n }\n\n if (options.stack) {\n (result.series as Record<string, unknown>[]).forEach((s) => {\n s.stack = 'total';\n });\n }\n\n // Reference lines → ECharts markLine on first series\n const refLines = options.referenceLines as ReferenceLineOption[] | undefined;\n if (Array.isArray(refLines) && refLines.length > 0 && seriesItems.length > 0) {\n seriesItems[0].markLine = {\n silent: true,\n symbol: 'none',\n data: refLines.map((rl) => {\n const item: Record<string, unknown> = {};\n if (rl.axis === 'x') {\n item.xAxis = rl.value;\n } else {\n item.yAxis = rl.value;\n }\n if (rl.label) item.name = rl.label;\n const lineStyle: Record<string, unknown> = {};\n if (rl.color) lineStyle.color = rl.color;\n if (rl.style) lineStyle.type = rl.style;\n if (Object.keys(lineStyle).length > 0) item.lineStyle = lineStyle;\n if (rl.label) item.label = { formatter: rl.label, position: 'end' };\n return item;\n }),\n };\n }\n\n return result;\n}\n\nfunction buildScatter(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n // For scatter, prefer two numeric fields for x/y\n const numFields = getNumberFields(data);\n const xField = mapping?.x ?? numFields[0];\n const yField = (mapping?.y ?? [numFields[1]])[0];\n const colorField = mapping?.color;\n const sizeField = mapping?.size;\n const opacityField = mapping?.opacity;\n\n if (!xField || !yField) return {};\n\n const result: Record<string, unknown> = {\n xAxis: { type: 'value' },\n yAxis: { type: 'value' },\n tooltip: { trigger: 'item' },\n };\n\n // Pre-compute opacity normalization range if needed\n let opacityMin = Infinity;\n let opacityMax = -Infinity;\n if (opacityField) {\n for (const row of data) {\n const v = Number(row[opacityField] ?? 0);\n if (v < opacityMin) opacityMin = v;\n if (v > opacityMax) opacityMax = v;\n }\n }\n const opacityRange = opacityMax - opacityMin || 1;\n\n const condStyles = options.conditionalStyles as ConditionalStyleRule[] | undefined;\n\n // Helper: build a data point — plain array or object with itemStyle for opacity/conditionalStyles\n const toPoint = (row: Record<string, unknown>): unknown => {\n const pt = [Number(row[xField] ?? 0), Number(row[yField] ?? 0)];\n if (sizeField) pt.push(Number(row[sizeField] ?? 0));\n\n if (condStyles?.length) {\n const match = matchConditionalStyle(row, condStyles);\n if (match) {\n const style: Record<string, unknown> = { color: match.color };\n if (opacityField) {\n const raw = Number(row[opacityField] ?? 0);\n style.opacity = Math.round((0.1 + 0.9 * ((raw - opacityMin) / opacityRange)) * 100) / 100;\n }\n const item: Record<string, unknown> = { value: pt, itemStyle: style };\n if (match.symbol) item.symbol = match.symbol;\n if (match.symbolSize) item.symbolSize = match.symbolSize;\n return item;\n }\n }\n\n if (opacityField) {\n const raw = Number(row[opacityField] ?? 0);\n const norm = 0.1 + 0.9 * ((raw - opacityMin) / opacityRange);\n return { value: pt, itemStyle: { opacity: Math.round(norm * 100) / 100 } };\n }\n return pt;\n };\n\n // symbolSize function that maps the third value to pixel radius\n const symbolSizeFn = sizeField\n ? (val: number[] | { value: number[] }) => {\n const arr = Array.isArray(val) ? val : val.value;\n const raw = arr[2] ?? 0;\n // Clamp to [4, 60] range — square root scale for area perception\n return Math.max(4, Math.min(60, Math.sqrt(raw) * 4));\n }\n : undefined;\n\n if (colorField) {\n // Group data by color field → separate series per group\n const groups = new Map<string, unknown[]>();\n for (const row of data) {\n const key = String(row[colorField] ?? 'unknown');\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(toPoint(row));\n }\n const seriesItems: Record<string, unknown>[] = [];\n for (const [name, points] of groups) {\n const series: Record<string, unknown> = { name, type: 'scatter', data: points };\n if (symbolSizeFn) series.symbolSize = symbolSizeFn;\n seriesItems.push(series);\n }\n result.series = seriesItems;\n result.legend = { data: Array.from(groups.keys()) };\n } else {\n // Single series — all points same color\n const points = data.map((row) => toPoint(row));\n const series: Record<string, unknown> = { type: 'scatter', data: points };\n if (symbolSizeFn) series.symbolSize = symbolSizeFn;\n result.series = [series];\n }\n\n // Reference lines\n const refLines = options.referenceLines as ReferenceLineOption[] | undefined;\n if (Array.isArray(refLines) && refLines.length > 0) {\n const firstSeries = (result.series as Record<string, unknown>[])[0];\n firstSeries.markLine = {\n silent: true,\n symbol: 'none',\n data: refLines.map((rl) => {\n const item: Record<string, unknown> = {};\n if (rl.axis === 'x') item.xAxis = rl.value;\n else item.yAxis = rl.value;\n if (rl.label) item.name = rl.label;\n const lineStyle: Record<string, unknown> = {};\n if (rl.color) lineStyle.color = rl.color;\n if (rl.style) lineStyle.type = rl.style;\n if (Object.keys(lineStyle).length > 0) item.lineStyle = lineStyle;\n if (rl.label) item.label = { formatter: rl.label, position: 'end' };\n return item;\n }),\n };\n }\n\n return result;\n}\n\nfunction buildPie(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const labelField = mapping?.label ?? guessStringField(data);\n const valueField = mapping?.value ?? guessNumberField(data);\n\n if (!labelField || !valueField) return {};\n\n const pieData = data.map((row) => ({\n name: String(row[labelField] ?? ''),\n value: Number(row[valueField] ?? 0),\n }));\n\n const radius = options.donut ? ['40%', '70%'] : '50%';\n const seriesItem: Record<string, unknown> = {\n type: 'pie',\n radius,\n data: pieData,\n label: { overflow: 'truncate', width: 80 },\n };\n\n if (options.showLabel === false) {\n seriesItem.label = { show: false };\n }\n\n const result: Record<string, unknown> = {\n tooltip: { trigger: 'item' },\n legend: { orient: 'vertical', left: 'left' },\n series: [seriesItem],\n };\n\n // Donut center label\n const center = options.center as { label?: string; value?: string } | undefined;\n if (options.donut && center && (center.label || center.value)) {\n const children: Record<string, unknown>[] = [];\n if (center.label) {\n children.push({\n type: 'text',\n top: center.value ? -16 : 0,\n style: { text: center.label, fontSize: 13, fill: '#999', textAlign: 'center' },\n });\n }\n if (center.value) {\n children.push({\n type: 'text',\n top: center.label ? 8 : 0,\n style: { text: center.value, fontSize: 20, fontWeight: 'bold', fill: '#333', textAlign: 'center' },\n });\n }\n result.graphic = [{ type: 'group', left: 'center', top: 'middle', children }];\n }\n\n return result;\n}\n\nfunction buildRadar(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const axisField = mapping?.axis ?? guessStringField(data);\n const yFields = mapping?.y ?? getNumberFields(data);\n\n if (!axisField || yFields.length === 0) return {};\n\n const indicator = data.map((row) => ({\n name: String(row[axisField] ?? ''),\n }));\n\n const series = yFields.map((field) => ({\n name: field,\n value: data.map((row) => Number(row[field] ?? 0)),\n }));\n\n return {\n tooltip: {},\n legend: { data: yFields },\n radar: { indicator },\n series: [\n {\n type: 'radar',\n data: series,\n },\n ],\n };\n}\n\nfunction buildHeatmap(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n // Determine x, y (category), value (number) fields\n const first = data[0] ?? {};\n const keys = Object.keys(first);\n const stringFields = keys.filter((k) => typeof first[k] === 'string');\n const numberFields = keys.filter((k) => typeof first[k] === 'number');\n\n const xField = mapping?.x ?? stringFields[0];\n // For heatmap, y is a category field (string), not a numeric series\n const yField = mapping?.y?.[0] ?? stringFields.find((k) => k !== xField);\n const valueField = mapping?.value ?? numberFields[0];\n\n if (!xField || !yField || !valueField) return {};\n\n // Extract unique categories preserving order of appearance\n const xCats: string[] = [];\n const yCats: string[] = [];\n const xSet = new Set<string>();\n const ySet = new Set<string>();\n\n for (const row of data) {\n const x = String(row[xField] ?? '');\n const y = String(row[yField] ?? '');\n if (!xSet.has(x)) { xSet.add(x); xCats.push(x); }\n if (!ySet.has(y)) { ySet.add(y); yCats.push(y); }\n }\n\n // Build index maps for O(1) lookup\n const xIndex = new Map<string, number>();\n xCats.forEach((v, i) => xIndex.set(v, i));\n const yIndex = new Map<string, number>();\n yCats.forEach((v, i) => yIndex.set(v, i));\n\n // Build [xIndex, yIndex, value] data\n const heatData: (number | null)[][] = [];\n let minVal = Infinity;\n let maxVal = -Infinity;\n\n for (const row of data) {\n const xi = xIndex.get(String(row[xField] ?? '')) ?? 0;\n const yi = yIndex.get(String(row[yField] ?? '')) ?? 0;\n const v = row[valueField] != null ? Number(row[valueField]) : null;\n heatData.push([xi, yi, v]);\n if (v != null) {\n if (v < minVal) minVal = v;\n if (v > maxVal) maxVal = v;\n }\n }\n\n // Handle edge case of empty/no-value data\n if (!isFinite(minVal)) { minVal = 0; maxVal = 1; }\n\n // Determine color range from options or use defaults\n const colorRange = (options.colorRange as string[]) ?? ['#313695', '#4575b4', '#74add1', '#abd9e9', '#fee090', '#fdae61', '#f46d43', '#d73027'];\n\n return {\n xAxis: { type: 'category', data: xCats, splitArea: { show: true } },\n yAxis: { type: 'category', data: yCats, splitArea: { show: true } },\n visualMap: {\n min: options.min != null ? Number(options.min) : minVal,\n max: options.max != null ? Number(options.max) : maxVal,\n calculable: true,\n orient: 'horizontal',\n left: 'center',\n bottom: 0,\n inRange: { color: colorRange },\n },\n tooltip: {\n trigger: 'item',\n formatter: (params: Record<string, unknown>) => {\n const d = params.data as number[];\n if (!d) return '';\n return `${xCats[d[0]]} × ${yCats[d[1]]}: ${d[2] != null ? d[2] : '-'}`;\n },\n },\n grid: { bottom: 60 },\n series: [{\n type: 'heatmap',\n data: heatData,\n label: { show: options.showLabel !== false },\n }],\n };\n}\n\nfunction buildBoxplot(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data) || data.length === 0) return {};\n\n const first = data[0] ?? {};\n const keys = Object.keys(first);\n const stringFields = keys.filter((k) => typeof first[k] === 'string');\n const numberFields = keys.filter((k) => typeof first[k] === 'number');\n\n // Category field (x)\n const xField = mapping?.x ?? stringFields[0];\n\n // Stat fields: use mapping.y if provided (5 fields: min, q1, median, q3, max)\n // Otherwise, try well-known names, then fall back to first 5 number fields\n let statFields: string[];\n if (mapping?.y && mapping.y.length >= 5) {\n statFields = mapping.y.slice(0, 5);\n } else {\n const wellKnown = ['min', 'q1', 'median', 'q3', 'max'];\n const matched = wellKnown.filter((name) => numberFields.includes(name));\n statFields = matched.length === 5 ? matched : numberFields.slice(0, 5);\n }\n\n if (statFields.length < 5) return {};\n\n const categories = xField ? data.map((row) => String(row[xField] ?? '')) : undefined;\n\n const boxData = data.map((row) =>\n statFields.map((f) => Number(row[f] ?? 0)),\n );\n\n const result: Record<string, unknown> = {\n tooltip: { trigger: 'item' },\n series: [{\n type: 'boxplot',\n data: boxData,\n }],\n };\n\n if (categories) {\n result.xAxis = { type: 'category', data: categories };\n result.yAxis = { type: 'value' };\n } else {\n result.xAxis = { type: 'category' };\n result.yAxis = { type: 'value' };\n }\n\n return result;\n}\n\n// ── Helpers ──\n\nfunction guessStringField(data: Record<string, unknown>[]): string | undefined {\n if (data.length === 0) return undefined;\n const first = data[0];\n return Object.keys(first).find((k) => typeof first[k] === 'string');\n}\n\nfunction guessNumberField(data: Record<string, unknown>[]): string | undefined {\n if (data.length === 0) return undefined;\n const first = data[0];\n return Object.keys(first).find((k) => typeof first[k] === 'number');\n}\n\nfunction buildFunnel(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const labelField = mapping?.label ?? guessStringField(data as Record<string, unknown>[]);\n const valueField = (mapping?.value ?? guessNumberField(data as Record<string, unknown>[]));\n\n if (!labelField || !valueField) return {};\n\n const seriesData = (data as Record<string, unknown>[]).map((row) => ({\n name: String(row[labelField] ?? ''),\n value: Number(row[valueField] ?? 0),\n }));\n\n return {\n tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },\n legend: { orient: 'vertical', left: 'left' },\n series: [{\n type: 'funnel',\n data: seriesData,\n sort: 'descending',\n gap: 2,\n label: { show: true, position: 'inside' },\n }],\n };\n}\n\nfunction buildWaterfall(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const records = data as Record<string, unknown>[];\n const xField = mapping?.x ?? guessStringField(records);\n const yField = (mapping?.y ?? [guessNumberField(records)])[0];\n\n if (!xField || !yField) return {};\n\n const categories: string[] = [];\n const baseValues: number[] = [];\n const positiveValues: (number | null)[] = [];\n const negativeValues: (number | null)[] = [];\n\n let running = 0;\n for (const row of records) {\n const label = String(row[xField] ?? '');\n const value = Number(row[yField] ?? 0);\n categories.push(label);\n\n if (value >= 0) {\n baseValues.push(running);\n positiveValues.push(value);\n negativeValues.push(null);\n } else {\n baseValues.push(running + value);\n positiveValues.push(null);\n negativeValues.push(Math.abs(value));\n }\n running += value;\n }\n\n return {\n tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },\n xAxis: { type: 'category', data: categories },\n yAxis: { type: 'value' },\n series: [\n {\n name: 'Base',\n type: 'bar',\n stack: 'waterfall',\n itemStyle: { borderColor: 'transparent', color: 'transparent' },\n emphasis: { itemStyle: { borderColor: 'transparent', color: 'transparent' } },\n data: baseValues,\n },\n {\n name: 'Positive',\n type: 'bar',\n stack: 'waterfall',\n data: positiveValues,\n },\n {\n name: 'Negative',\n type: 'bar',\n stack: 'waterfall',\n data: negativeValues,\n },\n ],\n };\n}\n\nfunction buildTreemap(\n data: unknown,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n // Treemap data uses name/value/children directly — pass through to ECharts\n const seriesData = (data as Record<string, unknown>[]).map((item) => toTreeNode(item));\n\n return {\n tooltip: { trigger: 'item' },\n series: [{\n type: 'treemap',\n data: seriesData,\n leafDepth: 1,\n roam: false,\n label: { show: true, formatter: '{b}' },\n }],\n };\n}\n\nfunction toTreeNode(item: Record<string, unknown>): Record<string, unknown> {\n const node: Record<string, unknown> = {\n name: String(item.name ?? ''),\n value: Number(item.value ?? 0),\n };\n if (Array.isArray(item.children)) {\n node.children = (item.children as Record<string, unknown>[]).map((child) => toTreeNode(child));\n }\n return node;\n}\n\nfunction buildHistogram(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n // Extract numeric values from flat array or object array\n let values: number[];\n if (!Array.isArray(data) || data.length === 0) return {};\n\n if (typeof data[0] === 'number') {\n values = data as number[];\n } else {\n const field = mapping?.value ?? guessNumberField(data as Record<string, unknown>[]);\n if (!field) return {};\n values = (data as Record<string, unknown>[]).map((row) => Number(row[field] ?? 0));\n }\n\n if (values.length === 0) return {};\n\n // Determine bin count: explicit or Sturges' rule\n const binCount = typeof options.bins === 'number'\n ? options.bins\n : Math.ceil(Math.log2(values.length) + 1);\n\n const min = Math.min(...values);\n const max = Math.max(...values);\n const range = max - min;\n const binWidth = range / binCount || 1;\n\n // Build bins\n const bins: number[] = new Array(binCount).fill(0);\n const labels: string[] = [];\n\n for (let i = 0; i < binCount; i++) {\n const lo = min + i * binWidth;\n const hi = min + (i + 1) * binWidth;\n const fmt = (n: number) => Number.isInteger(n) ? String(n) : n.toFixed(1);\n labels.push(`${fmt(lo)}\\u2013${fmt(hi)}`);\n }\n\n for (const v of values) {\n let idx = Math.floor((v - min) / binWidth);\n if (idx >= binCount) idx = binCount - 1; // clamp max to last bin\n bins[idx]++;\n }\n\n const series: Record<string, unknown> = {\n type: 'bar',\n data: bins,\n barCategoryGap: '0%',\n };\n\n const result: Record<string, unknown> = {\n xAxis: { type: 'category', data: labels, axisTick: { alignWithLabel: true } },\n yAxis: { type: 'value' },\n series: [series],\n tooltip: { trigger: 'axis' },\n };\n\n // Reference lines\n const refLines = options.referenceLines as ReferenceLineOption[] | undefined;\n if (Array.isArray(refLines) && refLines.length > 0) {\n series.markLine = {\n silent: true,\n symbol: 'none',\n data: refLines.map((rl) => {\n const item: Record<string, unknown> = {};\n if (rl.axis === 'x') item.xAxis = rl.value;\n else item.yAxis = rl.value;\n if (rl.label) item.name = rl.label;\n const lineStyle: Record<string, unknown> = {};\n if (rl.color) lineStyle.color = rl.color;\n if (rl.style) lineStyle.type = rl.style;\n if (Object.keys(lineStyle).length > 0) item.lineStyle = lineStyle;\n if (rl.label) item.label = { formatter: rl.label, position: 'end' };\n return item;\n }),\n };\n }\n\n return result;\n}\n\nfunction getNumberFields(data: Record<string, unknown>[]): string[] {\n if (data.length === 0) return [];\n const first = data[0];\n return Object.keys(first).filter((k) => typeof first[k] === 'number');\n}\n\n/**\n * Deep-merge `overrides` into `base` recursively.\n * If both base[key] and overrides[key] are plain objects, merge recursively.\n * Arrays and other values: overrides[key] wins.\n */\nfunction deepMerge(\n base: Record<string, unknown>,\n overrides: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...base };\n for (const key of Object.keys(overrides)) {\n const bv = base[key];\n const ov = overrides[key];\n if (isPlainObject(bv) && isPlainObject(ov)) {\n result[key] = deepMerge(bv as Record<string, unknown>, ov as Record<string, unknown>);\n } else {\n result[key] = ov;\n }\n }\n return result;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return v != null && typeof v === 'object' && !Array.isArray(v);\n}\n\n/**\n * Build a formatter string or function for ECharts axis labels\n * based on an AxisFormatOption.\n */\nfunction buildAxisFormatter(fmt: AxisFormatOption, locale?: string): (value: number | string) => string {\n return (value: number | string) => {\n let result: string;\n if (fmt.type) {\n const formatStr = fmt.type === 'currency' && fmt.currency\n ? `currency:${fmt.currency}`\n : fmt.type;\n result = formatValue(value, formatStr, locale);\n // For percent type, formatValue divides by 100 — but axis values are already in\n // display units (e.g. 73 means 73%), so use raw suffix instead\n if (fmt.type === 'percent') {\n result = typeof value === 'number'\n ? new Intl.NumberFormat(locale, { maximumFractionDigits: fmt.decimals ?? 2 }).format(value) + '%'\n : String(value) + '%';\n }\n } else {\n result = String(value);\n }\n if (fmt.decimals !== undefined && fmt.type === 'number') {\n const num = Number(value);\n if (!isNaN(num)) {\n result = new Intl.NumberFormat(locale, {\n minimumFractionDigits: fmt.decimals,\n maximumFractionDigits: fmt.decimals,\n }).format(num);\n }\n }\n if (fmt.prefix) result = fmt.prefix + result;\n if (fmt.suffix) result = result + fmt.suffix;\n return result;\n };\n}\n\n/**\n * Apply xFormat/yFormat to the corresponding axis in the ECharts option.\n * Handles both single axis and axis arrays (dual Y axis).\n */\nfunction applyAxisFormat(\n result: Record<string, unknown>,\n axisKey: 'xAxis' | 'yAxis',\n fmt: AxisFormatOption | undefined,\n locale?: string,\n): void {\n if (!fmt || !result[axisKey]) return;\n\n const formatter = buildAxisFormatter(fmt, locale);\n const axis = result[axisKey];\n\n if (Array.isArray(axis)) {\n // Dual axis — apply to all value-type axes\n result[axisKey] = (axis as Record<string, unknown>[]).map((a) => {\n if (a.type === 'value') {\n return { ...a, axisLabel: { ...(a.axisLabel as Record<string, unknown> ?? {}), formatter } };\n }\n return a;\n });\n } else if (isPlainObject(axis)) {\n const a = axis as Record<string, unknown>;\n result[axisKey] = { ...a, axisLabel: { ...(a.axisLabel as Record<string, unknown> ?? {}), formatter } };\n }\n}\n","import { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { UWidgetSpec, UWidgetEvent } from '../core/types.js';\nimport { toEChartsOption } from '../renderers/echarts-adapter.js';\nimport { themeStyles } from '../styles/tokens.js';\n\n// Tree-shakeable ECharts imports\nimport * as echarts from 'echarts/core';\nimport { BarChart, LineChart, PieChart, ScatterChart, RadarChart, HeatmapChart, BoxplotChart, FunnelChart, TreemapChart } from 'echarts/charts';\nimport {\n GridComponent,\n TooltipComponent,\n LegendComponent,\n RadarComponent,\n MarkLineComponent,\n VisualMapComponent,\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\n\necharts.use([\n BarChart,\n LineChart,\n PieChart,\n ScatterChart,\n RadarChart,\n HeatmapChart,\n BoxplotChart,\n FunnelChart,\n TreemapChart,\n GridComponent,\n TooltipComponent,\n LegendComponent,\n RadarComponent,\n MarkLineComponent,\n VisualMapComponent,\n CanvasRenderer,\n]);\n\n@customElement('uw-chart')\nexport class UwChart extends LitElement {\n static styles = [\n themeStyles,\n css`\n :host {\n display: block;\n container: uw-chart / inline-size;\n }\n\n .chart-container {\n width: 100%;\n height: var(--u-widget-chart-height, 300px);\n }\n\n @container uw-chart (max-width: 20rem) {\n .chart-container {\n height: var(--u-widget-chart-height-narrow, 200px);\n }\n }\n `,\n ];\n\n @property({ type: Object })\n spec: UWidgetSpec | null = null;\n\n private _chart: echarts.ECharts | null = null;\n private _container: HTMLDivElement | null = null;\n private _resizeObserver: ResizeObserver | null = null;\n\n render() {\n if (!this.spec) return nothing;\n const label = this.spec.title ?? `${this.spec.widget} chart`;\n return html`<div class=\"chart-container\" part=\"chart\" role=\"img\" aria-label=${label}></div>`;\n }\n\n protected firstUpdated() {\n this._container = this.shadowRoot?.querySelector('.chart-container') as HTMLDivElement | null;\n this._initChart();\n if (this._container) {\n this._resizeObserver = new ResizeObserver(() => this._chart?.resize());\n this._resizeObserver.observe(this._container);\n }\n }\n\n protected updated(changed: Map<string, unknown>) {\n if (changed.has('spec') && this._container) {\n this._updateChart();\n }\n }\n\n private _initChart() {\n if (!this._container || !this.spec) return;\n\n try {\n this._chart = echarts.init(this._container);\n this._chart.on('click', (params: Record<string, unknown>) => {\n this._onChartClick(params);\n });\n this._updateChart();\n } catch (e) {\n console.warn('[uw-chart] Failed to initialize ECharts:', (e as Error).message);\n }\n }\n\n private _onChartClick(params: Record<string, unknown>) {\n if (!this.spec) return;\n const detail: UWidgetEvent = {\n type: 'select',\n widget: this.spec.widget,\n id: this.spec.id,\n data: {\n name: params.name as string,\n seriesName: params.seriesName as string,\n value: params.value,\n dataIndex: params.dataIndex as number,\n },\n };\n this.dispatchEvent(\n new CustomEvent('u-widget-internal', {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _updateChart() {\n if (!this._chart || !this.spec) return;\n\n const option = toEChartsOption(this.spec);\n\n // Inject theme colors from CSS custom properties,\n // but only if the spec didn't provide explicit colors\n const hasSpecColors = Array.isArray(\n (this.spec.options as Record<string, unknown> | undefined)?.colors,\n ) && ((this.spec.options as Record<string, unknown>).colors as unknown[]).length > 0;\n if (!hasSpecColors) {\n const themeColors = this._readThemeColors();\n if (themeColors.length > 0) {\n option.color = themeColors;\n }\n }\n if (this._readCSSVar('--u-widget-bg')) {\n option.backgroundColor = 'transparent';\n }\n\n // Inject text/axis/grid theme from CSS variables\n this._applyThemeStyle(option);\n\n this._chart.setOption(option, true);\n }\n\n private _applyThemeStyle(option: Record<string, unknown>) {\n const textColor = this._readCSSVar('--u-widget-text');\n const secondaryColor = this._readCSSVar('--u-widget-text-secondary');\n const borderColor = this._readCSSVar('--u-widget-border');\n\n if (!textColor) return; // no theme vars available\n\n // Global text style\n option.textStyle = { ...(option.textStyle as Record<string, unknown>), color: textColor };\n\n // Axis styling — merge into existing axis config preserving formatter etc.\n const mergeAxisTheme = (axis: unknown): unknown => {\n if (!axis || typeof axis !== 'object') return axis;\n if (Array.isArray(axis)) return axis.map(mergeAxisTheme);\n const a = axis as Record<string, unknown>;\n return {\n ...a,\n axisLabel: { ...(a.axisLabel as Record<string, unknown> ?? {}), color: secondaryColor || textColor },\n axisLine: { lineStyle: { color: borderColor || secondaryColor } },\n splitLine: { lineStyle: { color: borderColor } },\n };\n };\n if (option.xAxis) option.xAxis = mergeAxisTheme(option.xAxis);\n if (option.yAxis) option.yAxis = mergeAxisTheme(option.yAxis);\n\n // Legend\n if (option.legend && typeof option.legend === 'object') {\n option.legend = { ...option.legend as Record<string, unknown>, textStyle: { color: textColor } };\n }\n }\n\n private _readThemeColors(): string[] {\n const colors: string[] = [];\n // Read --u-widget-chart-color-N (1-based) custom properties\n for (let i = 1; i <= 10; i++) {\n const c = this._readCSSVar(`--u-widget-chart-color-${i}`);\n if (c) colors.push(c);\n else break;\n }\n // Fallback: use --u-widget-primary as first color if no palette defined\n if (colors.length === 0) {\n const primary = this._readCSSVar('--u-widget-primary');\n if (primary) colors.push(primary);\n }\n return colors;\n }\n\n private _readCSSVar(name: string): string {\n return getComputedStyle(this).getPropertyValue(name).trim();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._chart?.dispose();\n this._chart = null;\n }\n\n /** Resize the chart (call when container size changes). */\n resize() {\n this._chart?.resize();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'uw-chart': UwChart;\n }\n}\n"],"names":["matchConditionalStyle","row","rules","rule","raw","val","aboveOk","belowOk","toEChartsOption","spec","widget","data","mapping","normalizeMapping","options","result","buildCartesian","buildPie","buildScatter","buildRadar","buildHeatmap","buildBoxplot","buildFunnel","buildWaterfall","buildTreemap","buildHistogram","locale","applyAxisFormat","passthrough","deepMerge","type","xField","guessStringField","yFields","guessNumberField","categories","horizontal","seriesOverrides","condStyles","seriesItems","field","i","s","match","item","override","catAxis","valAxis","needsDualYAxis","yAxisConfig","secondAxis","legendNames","refLines","rl","lineStyle","numFields","getNumberFields","yField","colorField","sizeField","opacityField","opacityMin","opacityMax","v","opacityRange","toPoint","pt","style","norm","symbolSizeFn","groups","key","name","points","series","firstSeries","labelField","valueField","pieData","seriesItem","center","children","_options","axisField","indicator","first","keys","stringFields","k","numberFields","xCats","yCats","xSet","ySet","x","y","xIndex","yIndex","heatData","minVal","maxVal","xi","yi","colorRange","params","d","statFields","matched","boxData","f","seriesData","records","baseValues","positiveValues","negativeValues","running","label","value","toTreeNode","node","child","values","binCount","min","binWidth","bins","labels","lo","hi","fmt","n","idx","base","overrides","bv","ov","isPlainObject","buildAxisFormatter","formatStr","formatValue","num","axisKey","formatter","axis","a","echarts","BarChart","LineChart","PieChart","ScatterChart","RadarChart","HeatmapChart","BoxplotChart","FunnelChart","TreemapChart","GridComponent","TooltipComponent","LegendComponent","RadarComponent","MarkLineComponent","VisualMapComponent","CanvasRenderer","UwChart","LitElement","nothing","html","changed","detail","option","themeColors","textColor","secondaryColor","borderColor","mergeAxisTheme","colors","c","primary","themeStyles","css","__decorateClass","property","customElement"],"mappings":"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"}
1
+ {"version":3,"file":"u-widgets-charts.js","sources":["../src/renderers/echarts-adapter.ts","../src/elements/uw-chart.ts"],"sourcesContent":["import type { UWidgetSpec, NormalizedMapping, ReferenceLineOption, AxisFormatOption } from '../core/types.js';\nimport { formatValue } from '../core/format.js';\nimport { normalizeMapping } from '../core/normalize.js';\n\ninterface ConditionalStyleRule {\n field: string;\n above?: number;\n below?: number;\n color: string;\n symbol?: string;\n symbolSize?: number;\n}\n\nfunction matchConditionalStyle(\n row: Record<string, unknown>,\n rules: ConditionalStyleRule[],\n): ConditionalStyleRule | undefined {\n for (const rule of rules) {\n const raw = row[rule.field];\n if (raw === undefined || raw === null) continue;\n const val = Number(raw);\n if (Number.isNaN(val)) continue;\n const aboveOk = rule.above === undefined || val > rule.above;\n const belowOk = rule.below === undefined || val < rule.below;\n if (aboveOk && belowOk) return rule;\n }\n return undefined;\n}\n\n/**\n * Translate a u-widget spec into an ECharts option object.\n * This is a pure function with no DOM or ECharts dependency.\n *\n * Supports `options.echarts` passthrough: any key-value pairs in\n * `options.echarts` are deep-merged (one level) into the generated\n * ECharts option, allowing full customization.\n */\nexport function toEChartsOption(spec: UWidgetSpec): Record<string, unknown> {\n const widget = spec.widget;\n const data = spec.data;\n const mapping = spec.mapping ? normalizeMapping(spec.mapping) : undefined;\n const options = spec.options ?? {};\n\n if (!data) return {};\n\n let result: Record<string, unknown>;\n\n switch (widget) {\n case 'chart.bar':\n result = buildCartesian(data, mapping, 'bar', options);\n break;\n case 'chart.line':\n result = buildCartesian(data, mapping, 'line', options);\n break;\n case 'chart.area':\n result = buildCartesian(data, mapping, 'line', { ...options, _area: true });\n break;\n case 'chart.pie':\n result = buildPie(data, mapping, options);\n break;\n case 'chart.scatter':\n result = buildScatter(data, mapping, options);\n break;\n case 'chart.radar':\n result = buildRadar(data, mapping, options);\n break;\n case 'chart.heatmap':\n result = buildHeatmap(data, mapping, options);\n break;\n case 'chart.box':\n result = buildBoxplot(data, mapping, options);\n break;\n case 'chart.funnel':\n result = buildFunnel(data, mapping, options);\n break;\n case 'chart.waterfall':\n result = buildWaterfall(data, mapping, options);\n break;\n case 'chart.treemap':\n result = buildTreemap(data, options);\n break;\n case 'chart.histogram':\n result = buildHistogram(data, mapping, options);\n break;\n default:\n return {};\n }\n\n // Apply chart-level options\n if (options.legend === false && result.legend) {\n result.legend = { ...result.legend as Record<string, unknown>, show: false };\n }\n\n if (options.grid === false) {\n // Hide grid lines on axes (handles both single axis and array)\n const hideGrid = (axis: unknown): unknown => {\n if (!axis || typeof axis !== 'object') return axis;\n if (Array.isArray(axis)) return axis.map(hideGrid);\n return { ...axis as Record<string, unknown>, splitLine: { show: false } };\n };\n if (result.xAxis) result.xAxis = hideGrid(result.xAxis);\n if (result.yAxis) result.yAxis = hideGrid(result.yAxis);\n }\n\n if (options.animate === false) {\n result.animation = false;\n }\n\n if (Array.isArray(options.colors) && options.colors.length > 0) {\n result.color = options.colors;\n }\n\n // Apply axis format options\n const locale = options.locale as string | undefined;\n applyAxisFormat(result, 'xAxis', options.xFormat as AxisFormatOption | undefined, locale);\n applyAxisFormat(result, 'yAxis', options.yFormat as AxisFormatOption | undefined, locale);\n\n // Apply echarts passthrough: deep-merge\n const passthrough = options.echarts as Record<string, unknown> | undefined;\n if (passthrough && typeof passthrough === 'object') {\n result = deepMerge(result, passthrough);\n }\n\n return result;\n}\n\nfunction buildCartesian(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n type: string,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const xField = mapping?.x ?? guessStringField(data);\n const yFields = mapping?.y ?? [guessNumberField(data)].filter(Boolean) as string[];\n\n if (!xField || yFields.length === 0) return {};\n\n const categories = data.map((row) => String(row[xField] ?? ''));\n const horizontal = !!options.horizontal;\n\n const seriesOverrides = Array.isArray(options.series) ? options.series as Record<string, unknown>[] : [];\n const condStyles = options.conditionalStyles as ConditionalStyleRule[] | undefined;\n\n const seriesItems = yFields.map((field, i) => {\n const s: Record<string, unknown> = {\n name: field,\n type,\n data: data.map((row) => {\n const val = row[field] ?? null;\n if (condStyles?.length) {\n const match = matchConditionalStyle(row, condStyles);\n if (match) {\n const item: Record<string, unknown> = { value: val, itemStyle: { color: match.color } };\n if (match.symbol) item.symbol = match.symbol;\n if (match.symbolSize) item.symbolSize = match.symbolSize;\n return item;\n }\n }\n return val;\n }),\n };\n if (options._area) s.areaStyle = {};\n if (options.smooth) s.smooth = true;\n if (options.step) s.step = options.step === true ? 'end' : options.step;\n\n // Apply per-series overrides from options.series[i]\n const override = seriesOverrides[i];\n if (override) {\n if (override.color) {\n s.itemStyle = { color: override.color };\n s.lineStyle = { ...(s.lineStyle as Record<string, unknown> ?? {}), color: override.color };\n }\n if (override.lineStyle) {\n s.lineStyle = { ...(s.lineStyle as Record<string, unknown> ?? {}), ...(override.lineStyle as Record<string, unknown>) };\n }\n if (override.symbol !== undefined) s.symbol = override.symbol;\n if (override.label) s.name = override.label as string;\n if (override.type) s.type = override.type as string;\n if (override.yAxisIndex !== undefined) s.yAxisIndex = override.yAxisIndex;\n }\n return s;\n });\n\n const catAxis: Record<string, unknown> = { type: 'category', data: categories };\n const valAxis: Record<string, unknown> = { type: 'value' };\n\n // Histogram mode: remove gaps between bars\n if (options.histogram) {\n catAxis.axisTick = { alignWithLabel: true };\n seriesItems.forEach((s) => { s.barCategoryGap = '0%'; });\n }\n\n // Detect if any series requires a secondary Y axis\n const needsDualYAxis = !horizontal && seriesItems.some((s) => (s.yAxisIndex as number) >= 1);\n let yAxisConfig: unknown;\n if (needsDualYAxis) {\n const secondAxis = Array.isArray(options.yAxis) && (options.yAxis as unknown[]).length >= 2\n ? (options.yAxis as Record<string, unknown>[])[1]\n : { type: 'value' };\n yAxisConfig = [valAxis, secondAxis];\n } else {\n yAxisConfig = horizontal ? catAxis : valAxis;\n }\n\n const result: Record<string, unknown> = {\n xAxis: horizontal ? valAxis : catAxis,\n yAxis: yAxisConfig,\n series: seriesItems,\n tooltip: { trigger: 'axis' },\n };\n\n if (yFields.length > 1) {\n const legendNames = seriesItems.map((s) => s.name as string);\n result.legend = { data: legendNames };\n }\n\n if (options.stack) {\n (result.series as Record<string, unknown>[]).forEach((s) => {\n s.stack = 'total';\n });\n }\n\n // Reference lines → ECharts markLine on first series\n const refLines = options.referenceLines as ReferenceLineOption[] | undefined;\n if (Array.isArray(refLines) && refLines.length > 0 && seriesItems.length > 0) {\n seriesItems[0].markLine = {\n silent: true,\n symbol: 'none',\n data: refLines.map((rl) => {\n const item: Record<string, unknown> = {};\n if (rl.axis === 'x') {\n item.xAxis = rl.value;\n } else {\n item.yAxis = rl.value;\n }\n if (rl.label) item.name = rl.label;\n const lineStyle: Record<string, unknown> = {};\n if (rl.color) lineStyle.color = rl.color;\n if (rl.style) lineStyle.type = rl.style;\n if (Object.keys(lineStyle).length > 0) item.lineStyle = lineStyle;\n if (rl.label) item.label = { formatter: rl.label, position: 'end' };\n return item;\n }),\n };\n }\n\n return result;\n}\n\nfunction buildScatter(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n // For scatter, prefer two numeric fields for x/y\n const numFields = getNumberFields(data);\n const xField = mapping?.x ?? numFields[0];\n const yField = (mapping?.y ?? [numFields[1]])[0];\n const colorField = mapping?.color;\n const sizeField = mapping?.size;\n const opacityField = mapping?.opacity;\n\n if (!xField || !yField) return {};\n\n const result: Record<string, unknown> = {\n xAxis: { type: 'value' },\n yAxis: { type: 'value' },\n tooltip: { trigger: 'item' },\n };\n\n // Pre-compute opacity normalization range if needed\n let opacityMin = Infinity;\n let opacityMax = -Infinity;\n if (opacityField) {\n for (const row of data) {\n const v = Number(row[opacityField] ?? 0);\n if (v < opacityMin) opacityMin = v;\n if (v > opacityMax) opacityMax = v;\n }\n }\n const opacityRange = opacityMax - opacityMin || 1;\n\n const condStyles = options.conditionalStyles as ConditionalStyleRule[] | undefined;\n\n // Helper: build a data point — plain array or object with itemStyle for opacity/conditionalStyles\n const toPoint = (row: Record<string, unknown>): unknown => {\n const pt = [Number(row[xField] ?? 0), Number(row[yField] ?? 0)];\n if (sizeField) pt.push(Number(row[sizeField] ?? 0));\n\n if (condStyles?.length) {\n const match = matchConditionalStyle(row, condStyles);\n if (match) {\n const style: Record<string, unknown> = { color: match.color };\n if (opacityField) {\n const raw = Number(row[opacityField] ?? 0);\n style.opacity = Math.round((0.1 + 0.9 * ((raw - opacityMin) / opacityRange)) * 100) / 100;\n }\n const item: Record<string, unknown> = { value: pt, itemStyle: style };\n if (match.symbol) item.symbol = match.symbol;\n if (match.symbolSize) item.symbolSize = match.symbolSize;\n return item;\n }\n }\n\n if (opacityField) {\n const raw = Number(row[opacityField] ?? 0);\n const norm = 0.1 + 0.9 * ((raw - opacityMin) / opacityRange);\n return { value: pt, itemStyle: { opacity: Math.round(norm * 100) / 100 } };\n }\n return pt;\n };\n\n // symbolSize function that maps the third value to pixel radius\n const symbolSizeFn = sizeField\n ? (val: number[] | { value: number[] }) => {\n const arr = Array.isArray(val) ? val : val.value;\n const raw = arr[2] ?? 0;\n // Clamp to [4, 60] range — square root scale for area perception\n return Math.max(4, Math.min(60, Math.sqrt(raw) * 4));\n }\n : undefined;\n\n if (colorField) {\n // Group data by color field → separate series per group\n const groups = new Map<string, unknown[]>();\n for (const row of data) {\n const key = String(row[colorField] ?? 'unknown');\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(toPoint(row));\n }\n const seriesItems: Record<string, unknown>[] = [];\n for (const [name, points] of groups) {\n const series: Record<string, unknown> = { name, type: 'scatter', data: points };\n if (symbolSizeFn) series.symbolSize = symbolSizeFn;\n seriesItems.push(series);\n }\n result.series = seriesItems;\n result.legend = { data: Array.from(groups.keys()) };\n } else {\n // Single series — all points same color\n const points = data.map((row) => toPoint(row));\n const series: Record<string, unknown> = { type: 'scatter', data: points };\n if (symbolSizeFn) series.symbolSize = symbolSizeFn;\n result.series = [series];\n }\n\n // Reference lines\n const refLines = options.referenceLines as ReferenceLineOption[] | undefined;\n if (Array.isArray(refLines) && refLines.length > 0) {\n const firstSeries = (result.series as Record<string, unknown>[])[0];\n firstSeries.markLine = {\n silent: true,\n symbol: 'none',\n data: refLines.map((rl) => {\n const item: Record<string, unknown> = {};\n if (rl.axis === 'x') item.xAxis = rl.value;\n else item.yAxis = rl.value;\n if (rl.label) item.name = rl.label;\n const lineStyle: Record<string, unknown> = {};\n if (rl.color) lineStyle.color = rl.color;\n if (rl.style) lineStyle.type = rl.style;\n if (Object.keys(lineStyle).length > 0) item.lineStyle = lineStyle;\n if (rl.label) item.label = { formatter: rl.label, position: 'end' };\n return item;\n }),\n };\n }\n\n return result;\n}\n\nfunction buildPie(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const labelField = mapping?.label ?? guessStringField(data);\n const valueField = mapping?.value ?? guessNumberField(data);\n\n if (!labelField || !valueField) return {};\n\n const pieData = data.map((row) => ({\n name: String(row[labelField] ?? ''),\n value: Number(row[valueField] ?? 0),\n }));\n\n const radius = options.donut ? ['40%', '70%'] : '50%';\n const seriesItem: Record<string, unknown> = {\n type: 'pie',\n radius,\n data: pieData,\n label: { overflow: 'truncate', width: 80 },\n };\n\n if (options.showLabel === false) {\n seriesItem.label = { show: false };\n }\n\n const result: Record<string, unknown> = {\n tooltip: { trigger: 'item' },\n legend: { orient: 'vertical', left: 'left' },\n series: [seriesItem],\n };\n\n // Donut center label\n const center = options.center as { label?: string; value?: string } | undefined;\n if (options.donut && center && (center.label || center.value)) {\n const children: Record<string, unknown>[] = [];\n if (center.label) {\n children.push({\n type: 'text',\n top: center.value ? -16 : 0,\n style: { text: center.label, fontSize: 13, fill: '#999', textAlign: 'center' },\n });\n }\n if (center.value) {\n children.push({\n type: 'text',\n top: center.label ? 8 : 0,\n style: { text: center.value, fontSize: 20, fontWeight: 'bold', fill: '#333', textAlign: 'center' },\n });\n }\n result.graphic = [{ type: 'group', left: 'center', top: 'middle', children }];\n }\n\n return result;\n}\n\nfunction buildRadar(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const axisField = mapping?.axis ?? guessStringField(data);\n const yFields = mapping?.y ?? getNumberFields(data);\n\n if (!axisField || yFields.length === 0) return {};\n\n const indicator = data.map((row) => ({\n name: String(row[axisField] ?? ''),\n }));\n\n const series = yFields.map((field) => ({\n name: field,\n value: data.map((row) => Number(row[field] ?? 0)),\n }));\n\n return {\n tooltip: {},\n legend: { data: yFields },\n radar: { indicator },\n series: [\n {\n type: 'radar',\n data: series,\n },\n ],\n };\n}\n\nfunction buildHeatmap(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n // Determine x, y (category), value (number) fields\n const first = data[0] ?? {};\n const keys = Object.keys(first);\n const stringFields = keys.filter((k) => typeof first[k] === 'string');\n const numberFields = keys.filter((k) => typeof first[k] === 'number');\n\n const xField = mapping?.x ?? stringFields[0];\n // For heatmap, y is a category field (string), not a numeric series\n const yField = mapping?.y?.[0] ?? stringFields.find((k) => k !== xField);\n const valueField = mapping?.value ?? numberFields[0];\n\n if (!xField || !yField || !valueField) return {};\n\n // Extract unique categories preserving order of appearance\n const xCats: string[] = [];\n const yCats: string[] = [];\n const xSet = new Set<string>();\n const ySet = new Set<string>();\n\n for (const row of data) {\n const x = String(row[xField] ?? '');\n const y = String(row[yField] ?? '');\n if (!xSet.has(x)) { xSet.add(x); xCats.push(x); }\n if (!ySet.has(y)) { ySet.add(y); yCats.push(y); }\n }\n\n // Build index maps for O(1) lookup\n const xIndex = new Map<string, number>();\n xCats.forEach((v, i) => xIndex.set(v, i));\n const yIndex = new Map<string, number>();\n yCats.forEach((v, i) => yIndex.set(v, i));\n\n // Build [xIndex, yIndex, value] data\n const heatData: (number | null)[][] = [];\n let minVal = Infinity;\n let maxVal = -Infinity;\n\n for (const row of data) {\n const xi = xIndex.get(String(row[xField] ?? '')) ?? 0;\n const yi = yIndex.get(String(row[yField] ?? '')) ?? 0;\n const v = row[valueField] != null ? Number(row[valueField]) : null;\n heatData.push([xi, yi, v]);\n if (v != null) {\n if (v < minVal) minVal = v;\n if (v > maxVal) maxVal = v;\n }\n }\n\n // Handle edge case of empty/no-value data\n if (!isFinite(minVal)) { minVal = 0; maxVal = 1; }\n\n // Determine color range from options or use defaults\n const colorRange = (options.colorRange as string[]) ?? ['#313695', '#4575b4', '#74add1', '#abd9e9', '#fee090', '#fdae61', '#f46d43', '#d73027'];\n\n return {\n xAxis: { type: 'category', data: xCats, splitArea: { show: true } },\n yAxis: { type: 'category', data: yCats, splitArea: { show: true } },\n visualMap: {\n min: options.min != null ? Number(options.min) : minVal,\n max: options.max != null ? Number(options.max) : maxVal,\n calculable: true,\n orient: 'horizontal',\n left: 'center',\n bottom: 0,\n inRange: { color: colorRange },\n },\n tooltip: {\n trigger: 'item',\n formatter: (params: Record<string, unknown>) => {\n const d = params.data as number[];\n if (!d) return '';\n return `${xCats[d[0]]} × ${yCats[d[1]]}: ${d[2] != null ? d[2] : '-'}`;\n },\n },\n grid: { bottom: 60 },\n series: [{\n type: 'heatmap',\n data: heatData,\n label: { show: options.showLabel !== false },\n }],\n };\n}\n\nfunction buildBoxplot(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data) || data.length === 0) return {};\n\n const first = data[0] ?? {};\n const keys = Object.keys(first);\n const stringFields = keys.filter((k) => typeof first[k] === 'string');\n const numberFields = keys.filter((k) => typeof first[k] === 'number');\n\n // Category field (x)\n const xField = mapping?.x ?? stringFields[0];\n\n // Stat fields: use mapping.y if provided (5 fields: min, q1, median, q3, max)\n // Otherwise, try well-known names, then fall back to first 5 number fields\n let statFields: string[];\n if (mapping?.y && mapping.y.length >= 5) {\n statFields = mapping.y.slice(0, 5);\n } else {\n const wellKnown = ['min', 'q1', 'median', 'q3', 'max'];\n const matched = wellKnown.filter((name) => numberFields.includes(name));\n statFields = matched.length === 5 ? matched : numberFields.slice(0, 5);\n }\n\n if (statFields.length < 5) return {};\n\n const categories = xField ? data.map((row) => String(row[xField] ?? '')) : undefined;\n\n const boxData = data.map((row) =>\n statFields.map((f) => Number(row[f] ?? 0)),\n );\n\n const result: Record<string, unknown> = {\n tooltip: { trigger: 'item' },\n series: [{\n type: 'boxplot',\n data: boxData,\n }],\n };\n\n if (categories) {\n result.xAxis = { type: 'category', data: categories };\n result.yAxis = { type: 'value' };\n } else {\n result.xAxis = { type: 'category' };\n result.yAxis = { type: 'value' };\n }\n\n return result;\n}\n\n// ── Helpers ──\n\nfunction guessStringField(data: Record<string, unknown>[]): string | undefined {\n if (data.length === 0) return undefined;\n const first = data[0];\n return Object.keys(first).find((k) => typeof first[k] === 'string');\n}\n\nfunction guessNumberField(data: Record<string, unknown>[]): string | undefined {\n if (data.length === 0) return undefined;\n const first = data[0];\n return Object.keys(first).find((k) => typeof first[k] === 'number');\n}\n\nfunction buildFunnel(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const labelField = mapping?.label ?? guessStringField(data as Record<string, unknown>[]);\n const valueField = (mapping?.value ?? guessNumberField(data as Record<string, unknown>[]));\n\n if (!labelField || !valueField) return {};\n\n const seriesData = (data as Record<string, unknown>[]).map((row) => ({\n name: String(row[labelField] ?? ''),\n value: Number(row[valueField] ?? 0),\n }));\n\n return {\n tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },\n legend: { orient: 'vertical', left: 'left' },\n series: [{\n type: 'funnel',\n data: seriesData,\n sort: 'descending',\n gap: 2,\n label: { show: true, position: 'inside' },\n }],\n };\n}\n\nfunction buildWaterfall(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n const records = data as Record<string, unknown>[];\n const xField = mapping?.x ?? guessStringField(records);\n const yField = (mapping?.y ?? [guessNumberField(records)])[0];\n\n if (!xField || !yField) return {};\n\n const categories: string[] = [];\n const baseValues: number[] = [];\n const positiveValues: (number | null)[] = [];\n const negativeValues: (number | null)[] = [];\n\n let running = 0;\n for (const row of records) {\n const label = String(row[xField] ?? '');\n const value = Number(row[yField] ?? 0);\n categories.push(label);\n\n if (value >= 0) {\n baseValues.push(running);\n positiveValues.push(value);\n negativeValues.push(null);\n } else {\n baseValues.push(running + value);\n positiveValues.push(null);\n negativeValues.push(Math.abs(value));\n }\n running += value;\n }\n\n return {\n tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },\n xAxis: { type: 'category', data: categories },\n yAxis: { type: 'value' },\n series: [\n {\n name: 'Base',\n type: 'bar',\n stack: 'waterfall',\n itemStyle: { borderColor: 'transparent', color: 'transparent' },\n emphasis: { itemStyle: { borderColor: 'transparent', color: 'transparent' } },\n data: baseValues,\n },\n {\n name: 'Positive',\n type: 'bar',\n stack: 'waterfall',\n data: positiveValues,\n },\n {\n name: 'Negative',\n type: 'bar',\n stack: 'waterfall',\n data: negativeValues,\n },\n ],\n };\n}\n\nfunction buildTreemap(\n data: unknown,\n _options: Record<string, unknown>,\n): Record<string, unknown> {\n if (!Array.isArray(data)) return {};\n\n // Treemap data uses name/value/children directly — pass through to ECharts\n const seriesData = (data as Record<string, unknown>[]).map((item) => toTreeNode(item));\n\n return {\n tooltip: { trigger: 'item' },\n series: [{\n type: 'treemap',\n data: seriesData,\n leafDepth: 1,\n roam: false,\n label: { show: true, formatter: '{b}' },\n }],\n };\n}\n\nfunction toTreeNode(item: Record<string, unknown>): Record<string, unknown> {\n const node: Record<string, unknown> = {\n name: String(item.name ?? ''),\n value: Number(item.value ?? 0),\n };\n if (Array.isArray(item.children)) {\n node.children = (item.children as Record<string, unknown>[]).map((child) => toTreeNode(child));\n }\n return node;\n}\n\nfunction buildHistogram(\n data: unknown,\n mapping: NormalizedMapping | undefined,\n options: Record<string, unknown>,\n): Record<string, unknown> {\n // Extract numeric values from flat array or object array\n let values: number[];\n if (!Array.isArray(data) || data.length === 0) return {};\n\n if (typeof data[0] === 'number') {\n values = data as number[];\n } else {\n const field = mapping?.value ?? guessNumberField(data as Record<string, unknown>[]);\n if (!field) return {};\n values = (data as Record<string, unknown>[]).map((row) => Number(row[field] ?? 0));\n }\n\n if (values.length === 0) return {};\n\n // Determine bin count: explicit or Sturges' rule\n const binCount = typeof options.bins === 'number'\n ? options.bins\n : Math.ceil(Math.log2(values.length) + 1);\n\n const min = Math.min(...values);\n const max = Math.max(...values);\n const range = max - min;\n const binWidth = range / binCount || 1;\n\n // Build bins\n const bins: number[] = new Array(binCount).fill(0);\n const labels: string[] = [];\n\n for (let i = 0; i < binCount; i++) {\n const lo = min + i * binWidth;\n const hi = min + (i + 1) * binWidth;\n const fmt = (n: number) => Number.isInteger(n) ? String(n) : n.toFixed(1);\n labels.push(`${fmt(lo)}\\u2013${fmt(hi)}`);\n }\n\n for (const v of values) {\n let idx = Math.floor((v - min) / binWidth);\n if (idx >= binCount) idx = binCount - 1; // clamp max to last bin\n bins[idx]++;\n }\n\n const series: Record<string, unknown> = {\n type: 'bar',\n data: bins,\n barCategoryGap: '0%',\n };\n\n const result: Record<string, unknown> = {\n xAxis: { type: 'category', data: labels, axisTick: { alignWithLabel: true } },\n yAxis: { type: 'value' },\n series: [series],\n tooltip: { trigger: 'axis' },\n };\n\n // Reference lines\n const refLines = options.referenceLines as ReferenceLineOption[] | undefined;\n if (Array.isArray(refLines) && refLines.length > 0) {\n series.markLine = {\n silent: true,\n symbol: 'none',\n data: refLines.map((rl) => {\n const item: Record<string, unknown> = {};\n if (rl.axis === 'x') item.xAxis = rl.value;\n else item.yAxis = rl.value;\n if (rl.label) item.name = rl.label;\n const lineStyle: Record<string, unknown> = {};\n if (rl.color) lineStyle.color = rl.color;\n if (rl.style) lineStyle.type = rl.style;\n if (Object.keys(lineStyle).length > 0) item.lineStyle = lineStyle;\n if (rl.label) item.label = { formatter: rl.label, position: 'end' };\n return item;\n }),\n };\n }\n\n return result;\n}\n\nfunction getNumberFields(data: Record<string, unknown>[]): string[] {\n if (data.length === 0) return [];\n const first = data[0];\n return Object.keys(first).filter((k) => typeof first[k] === 'number');\n}\n\n/**\n * Deep-merge `overrides` into `base` recursively.\n * If both base[key] and overrides[key] are plain objects, merge recursively.\n * Arrays and other values: overrides[key] wins.\n */\nfunction deepMerge(\n base: Record<string, unknown>,\n overrides: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...base };\n for (const key of Object.keys(overrides)) {\n const bv = base[key];\n const ov = overrides[key];\n if (isPlainObject(bv) && isPlainObject(ov)) {\n result[key] = deepMerge(bv as Record<string, unknown>, ov as Record<string, unknown>);\n } else {\n result[key] = ov;\n }\n }\n return result;\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return v != null && typeof v === 'object' && !Array.isArray(v);\n}\n\n/**\n * Build a formatter string or function for ECharts axis labels\n * based on an AxisFormatOption.\n */\nfunction buildAxisFormatter(fmt: AxisFormatOption, locale?: string): (value: number | string) => string {\n return (value: number | string) => {\n let result: string;\n if (fmt.type) {\n const formatStr = fmt.type === 'currency' && fmt.currency\n ? `currency:${fmt.currency}`\n : fmt.type;\n result = formatValue(value, formatStr, locale);\n // For percent type, formatValue divides by 100 — but axis values are already in\n // display units (e.g. 73 means 73%), so use raw suffix instead\n if (fmt.type === 'percent') {\n result = typeof value === 'number'\n ? new Intl.NumberFormat(locale, { maximumFractionDigits: fmt.decimals ?? 2 }).format(value) + '%'\n : String(value) + '%';\n }\n } else {\n result = String(value);\n }\n if (fmt.decimals !== undefined && fmt.type === 'number') {\n const num = Number(value);\n if (!isNaN(num)) {\n result = new Intl.NumberFormat(locale, {\n minimumFractionDigits: fmt.decimals,\n maximumFractionDigits: fmt.decimals,\n }).format(num);\n }\n }\n if (fmt.prefix) result = fmt.prefix + result;\n if (fmt.suffix) result = result + fmt.suffix;\n return result;\n };\n}\n\n/**\n * Apply xFormat/yFormat to the corresponding axis in the ECharts option.\n * Handles both single axis and axis arrays (dual Y axis).\n */\nfunction applyAxisFormat(\n result: Record<string, unknown>,\n axisKey: 'xAxis' | 'yAxis',\n fmt: AxisFormatOption | undefined,\n locale?: string,\n): void {\n if (!fmt || !result[axisKey]) return;\n\n const formatter = buildAxisFormatter(fmt, locale);\n const axis = result[axisKey];\n\n if (Array.isArray(axis)) {\n // Dual axis — apply to all value-type axes\n result[axisKey] = (axis as Record<string, unknown>[]).map((a) => {\n if (a.type === 'value') {\n return { ...a, axisLabel: { ...(a.axisLabel as Record<string, unknown> ?? {}), formatter } };\n }\n return a;\n });\n } else if (isPlainObject(axis)) {\n const a = axis as Record<string, unknown>;\n result[axisKey] = { ...a, axisLabel: { ...(a.axisLabel as Record<string, unknown> ?? {}), formatter } };\n }\n}\n","import { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { UWidgetSpec, UWidgetEvent } from '../core/types.js';\nimport { toEChartsOption } from '../renderers/echarts-adapter.js';\nimport { themeStyles } from '../styles/tokens.js';\n\n// Tree-shakeable ECharts imports\nimport * as echarts from 'echarts/core';\nimport { BarChart, LineChart, PieChart, ScatterChart, RadarChart, HeatmapChart, BoxplotChart, FunnelChart, TreemapChart } from 'echarts/charts';\nimport {\n GridComponent,\n TooltipComponent,\n LegendComponent,\n RadarComponent,\n MarkLineComponent,\n VisualMapComponent,\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\n\necharts.use([\n BarChart,\n LineChart,\n PieChart,\n ScatterChart,\n RadarChart,\n HeatmapChart,\n BoxplotChart,\n FunnelChart,\n TreemapChart,\n GridComponent,\n TooltipComponent,\n LegendComponent,\n RadarComponent,\n MarkLineComponent,\n VisualMapComponent,\n CanvasRenderer,\n]);\n\n@customElement('uw-chart')\nexport class UwChart extends LitElement {\n static styles = [\n themeStyles,\n css`\n :host {\n display: block;\n container: uw-chart / inline-size;\n }\n\n .chart-container {\n width: 100%;\n height: var(--u-widget-chart-height, 300px);\n }\n\n @container uw-chart (max-width: 20rem) {\n .chart-container {\n height: var(--u-widget-chart-height-narrow, 200px);\n }\n }\n `,\n ];\n\n @property({ type: Object })\n spec: UWidgetSpec | null = null;\n\n private _chart: echarts.ECharts | null = null;\n private _container: HTMLDivElement | null = null;\n private _resizeObserver: ResizeObserver | null = null;\n\n render() {\n if (!this.spec) return nothing;\n const label = this.spec.title ?? `${this.spec.widget} chart`;\n return html`<div class=\"chart-container\" part=\"chart\" role=\"img\" aria-label=${label}></div>`;\n }\n\n protected firstUpdated() {\n this._container = this.shadowRoot?.querySelector('.chart-container') as HTMLDivElement | null;\n this._initChart();\n if (this._container) {\n this._resizeObserver = new ResizeObserver(() => this._chart?.resize());\n this._resizeObserver.observe(this._container);\n }\n }\n\n protected updated(changed: Map<string, unknown>) {\n if (changed.has('spec') && this._container) {\n this._updateChart();\n }\n }\n\n private _initChart() {\n if (!this._container || !this.spec) return;\n\n try {\n this._chart = echarts.init(this._container);\n this._chart.on('click', (params: Record<string, unknown>) => {\n this._onChartClick(params);\n });\n this._updateChart();\n } catch (e) {\n console.warn('[uw-chart] Failed to initialize ECharts:', (e as Error).message);\n }\n }\n\n private _onChartClick(params: Record<string, unknown>) {\n if (!this.spec) return;\n const detail: UWidgetEvent = {\n type: 'select',\n widget: this.spec.widget,\n id: this.spec.id,\n data: {\n name: params.name as string,\n seriesName: params.seriesName as string,\n value: params.value,\n dataIndex: params.dataIndex as number,\n },\n };\n this.dispatchEvent(\n new CustomEvent('u-widget-internal', {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _updateChart() {\n if (!this._chart || !this.spec) return;\n\n const option = toEChartsOption(this.spec);\n\n // Inject theme colors from CSS custom properties,\n // but only if the spec didn't provide explicit colors\n const hasSpecColors = Array.isArray(\n (this.spec.options as Record<string, unknown> | undefined)?.colors,\n ) && ((this.spec.options as Record<string, unknown>).colors as unknown[]).length > 0;\n if (!hasSpecColors) {\n const themeColors = this._readThemeColors();\n if (themeColors.length > 0) {\n option.color = themeColors;\n }\n }\n const hasExplicitBg = !!(\n (this.spec.options as Record<string, unknown> | undefined)?.echarts as Record<string, unknown> | undefined\n )?.backgroundColor;\n if (!hasExplicitBg && this._readCSSVar('--u-widget-bg')) {\n option.backgroundColor = 'transparent';\n }\n\n // Inject text/axis/grid theme from CSS variables\n this._applyThemeStyle(option);\n\n this._chart.setOption(option, true);\n }\n\n private _applyThemeStyle(option: Record<string, unknown>) {\n const textColor = this._readCSSVar('--u-widget-text');\n const secondaryColor = this._readCSSVar('--u-widget-text-secondary');\n const borderColor = this._readCSSVar('--u-widget-border');\n\n if (!textColor) return; // no theme vars available\n\n // Global text style\n option.textStyle = { ...(option.textStyle as Record<string, unknown>), color: textColor };\n\n // Axis styling — deep-merge into existing axis config preserving all existing properties\n const mergeAxisTheme = (axis: unknown): unknown => {\n if (!axis || typeof axis !== 'object') return axis;\n if (Array.isArray(axis)) return axis.map(mergeAxisTheme);\n const a = axis as Record<string, unknown>;\n const existingLine = a.axisLine as Record<string, unknown> ?? {};\n const existingLineStyle = existingLine.lineStyle as Record<string, unknown> ?? {};\n const existingSplit = a.splitLine as Record<string, unknown> ?? {};\n const existingSplitStyle = existingSplit.lineStyle as Record<string, unknown> ?? {};\n return {\n ...a,\n axisLabel: { ...(a.axisLabel as Record<string, unknown> ?? {}), color: secondaryColor || textColor },\n axisLine: { ...existingLine, lineStyle: { ...existingLineStyle, color: borderColor || secondaryColor } },\n splitLine: { ...existingSplit, lineStyle: { ...existingSplitStyle, color: borderColor } },\n };\n };\n if (option.xAxis) option.xAxis = mergeAxisTheme(option.xAxis);\n if (option.yAxis) option.yAxis = mergeAxisTheme(option.yAxis);\n\n // Legend — merge textStyle preserving existing properties\n if (option.legend && typeof option.legend === 'object') {\n const leg = option.legend as Record<string, unknown>;\n option.legend = { ...leg, textStyle: { ...(leg.textStyle as Record<string, unknown> ?? {}), color: textColor } };\n }\n }\n\n private _readThemeColors(): string[] {\n const colors: string[] = [];\n // Read --u-widget-chart-color-N (1-based) custom properties\n for (let i = 1; i <= 10; i++) {\n const c = this._readCSSVar(`--u-widget-chart-color-${i}`);\n if (c) colors.push(c);\n else break;\n }\n // Fallback: use --u-widget-primary as first color if no palette defined\n if (colors.length === 0) {\n const primary = this._readCSSVar('--u-widget-primary');\n if (primary) colors.push(primary);\n }\n return colors;\n }\n\n private _readCSSVar(name: string): string {\n return getComputedStyle(this).getPropertyValue(name).trim();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this._chart?.dispose();\n this._chart = null;\n }\n\n /** Resize the chart (call when container size changes). */\n resize() {\n this._chart?.resize();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'uw-chart': UwChart;\n }\n}\n"],"names":["matchConditionalStyle","row","rules","rule","raw","val","aboveOk","belowOk","toEChartsOption","spec","widget","data","mapping","normalizeMapping","options","result","buildCartesian","buildPie","buildScatter","buildRadar","buildHeatmap","buildBoxplot","buildFunnel","buildWaterfall","buildTreemap","buildHistogram","hideGrid","axis","locale","applyAxisFormat","passthrough","deepMerge","type","xField","guessStringField","yFields","guessNumberField","categories","horizontal","seriesOverrides","condStyles","seriesItems","field","i","s","match","item","override","catAxis","valAxis","needsDualYAxis","yAxisConfig","secondAxis","legendNames","refLines","rl","lineStyle","numFields","getNumberFields","yField","colorField","sizeField","opacityField","opacityMin","opacityMax","v","opacityRange","toPoint","pt","style","norm","symbolSizeFn","groups","key","name","points","series","firstSeries","labelField","valueField","pieData","seriesItem","center","children","_options","axisField","indicator","first","keys","stringFields","k","numberFields","xCats","yCats","xSet","ySet","x","y","xIndex","yIndex","heatData","minVal","maxVal","xi","yi","colorRange","params","d","statFields","matched","boxData","f","seriesData","records","baseValues","positiveValues","negativeValues","running","label","value","toTreeNode","node","child","values","binCount","min","binWidth","bins","labels","lo","hi","fmt","n","idx","base","overrides","bv","ov","isPlainObject","buildAxisFormatter","formatStr","formatValue","num","axisKey","formatter","a","echarts","BarChart","LineChart","PieChart","ScatterChart","RadarChart","HeatmapChart","BoxplotChart","FunnelChart","TreemapChart","GridComponent","TooltipComponent","LegendComponent","RadarComponent","MarkLineComponent","VisualMapComponent","CanvasRenderer","UwChart","LitElement","nothing","html","changed","detail","option","themeColors","textColor","secondaryColor","borderColor","mergeAxisTheme","existingLine","existingLineStyle","existingSplit","existingSplitStyle","leg","colors","c","primary","themeStyles","css","__decorateClass","property","customElement"],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import { CSSResult } from 'lit';
2
+ import { LitElement } from 'lit';
3
+ import { nothing } from 'lit';
4
+ import { TemplateResult } from 'lit-html';
5
+
6
+ /** Supported input field types for form widgets. */
7
+ declare type FieldType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'textarea' | 'number' | 'select' | 'multiselect' | 'date' | 'datetime' | 'time' | 'toggle' | 'range' | 'radio' | 'checkbox';
8
+
9
+ /**
10
+ * Action button definition.
11
+ *
12
+ * Reserved actions: `"submit"`, `"cancel"`, `"navigate"`.
13
+ * Custom action strings are forwarded to the host via the `u-widget-event`.
14
+ *
15
+ * @example
16
+ * ```json
17
+ * { "label": "Submit", "action": "submit", "style": "primary" }
18
+ * ```
19
+ */
20
+ declare interface UWidgetAction {
21
+ /** Button display text. */
22
+ label: string;
23
+ /** Action identifier emitted in the widget event. */
24
+ action: string;
25
+ /** Visual style hint. */
26
+ style?: 'primary' | 'danger' | 'default';
27
+ /** Whether the button is disabled. */
28
+ disabled?: boolean;
29
+ /** URL for `"navigate"` actions. */
30
+ url?: string;
31
+ }
32
+
33
+ /**
34
+ * Child widget spec inside a compose widget.
35
+ * Inherits `type` and `version` from the parent — no need to repeat them.
36
+ */
37
+ declare interface UWidgetChildSpec extends Omit<UWidgetSpec, 'type' | 'version'> {
38
+ /** Grid column span within the parent compose layout. */
39
+ span?: number;
40
+ /** When true, the child is initially collapsed (uses native `<details>`). */
41
+ collapsed?: boolean;
42
+ }
43
+
44
+ /**
45
+ * Column definition for table widgets.
46
+ *
47
+ * @example
48
+ * ```json
49
+ * { "field": "price", "label": "Price", "format": "currency", "align": "right" }
50
+ * ```
51
+ */
52
+ declare interface UWidgetColumnDefinition {
53
+ /** Data field name to display in this column. */
54
+ field: string;
55
+ /** Display header label. Defaults to the field name. */
56
+ label?: string;
57
+ /** Value formatting hint (e.g., `"currency"`, `"currency:EUR"`, `"percent"`). */
58
+ format?: 'number' | 'currency' | 'percent' | 'date' | 'datetime' | 'bytes';
59
+ /** Text alignment within the column. */
60
+ align?: 'left' | 'center' | 'right';
61
+ }
62
+
63
+ /**
64
+ * Field definition for form/confirm input widgets.
65
+ *
66
+ * @example
67
+ * ```json
68
+ * { "field": "email", "label": "Email", "type": "email", "required": true }
69
+ * ```
70
+ */
71
+ declare interface UWidgetFieldDefinition {
72
+ /** Data field name (maps to `data[field]` for defaults and output). */
73
+ field: string;
74
+ /** Display label. Defaults to the field name. */
75
+ label?: string;
76
+ /** Input type. Defaults to `"text"`. */
77
+ type?: FieldType;
78
+ /** Whether the field must be filled before submit. */
79
+ required?: boolean;
80
+ /** Placeholder text shown when the field is empty. */
81
+ placeholder?: string;
82
+ /** Options for select, multiselect, radio, and checkbox types. */
83
+ options?: string[];
84
+ /** Minimum character length for text inputs. */
85
+ minLength?: number;
86
+ /** Maximum character length for text inputs. */
87
+ maxLength?: number;
88
+ /** Custom regex pattern for validation (e.g. `"^[A-Z]{3}$"`). */
89
+ pattern?: string;
90
+ /** Number of visible rows for textarea type. */
91
+ rows?: number;
92
+ /** Minimum value (number) or date string. */
93
+ min?: number | string;
94
+ /** Maximum value (number) or date string. */
95
+ max?: number | string;
96
+ /** Step increment for number and range inputs. */
97
+ step?: number;
98
+ /** Custom validation error message (overrides locale default). */
99
+ message?: string;
100
+ }
101
+
102
+ /**
103
+ * Mapping connects data fields to visual channels.
104
+ *
105
+ * Which keys are relevant depends on the widget type:
106
+ * - **chart.bar/line/area:** `x`, `y`
107
+ * - **chart.pie/funnel:** `label`, `value`
108
+ * - **chart.scatter:** `x`, `y`, `color`, `size`
109
+ * - **chart.radar:** `axis`, `value`
110
+ * - **table:** `columns`
111
+ * - **list:** `primary`, `secondary`, `avatar`, `icon`, `trailing`
112
+ *
113
+ * When omitted, mapping is auto-inferred from the data shape.
114
+ */
115
+ declare interface UWidgetMapping {
116
+ /** Category axis field (chart x-axis). */
117
+ x?: string;
118
+ /** Value axis field(s). A string for single series, string[] for multi-series. */
119
+ y?: string | string[];
120
+ /** Label field (pie/funnel charts). */
121
+ label?: string;
122
+ /** Value field (pie/funnel/heatmap). */
123
+ value?: string;
124
+ /** Color grouping field (scatter). */
125
+ color?: string;
126
+ /** Size encoding field (scatter bubble). */
127
+ size?: string;
128
+ /** Opacity encoding field (scatter). Maps data values to point opacity (0.1–1.0). */
129
+ opacity?: string;
130
+ /** Axis field (radar chart indicators). */
131
+ axis?: string;
132
+ /** Explicit column definitions for table widgets. */
133
+ columns?: UWidgetColumnDefinition[];
134
+ /** Primary text field (list widget). */
135
+ primary?: string;
136
+ /** Secondary/subtitle text field (list widget). */
137
+ secondary?: string;
138
+ /** Icon letter field (list widget fallback when no avatar). */
139
+ icon?: string;
140
+ /** Avatar image URL field (list widget). */
141
+ avatar?: string;
142
+ /** Trailing value field displayed on the right (list widget). */
143
+ trailing?: string;
144
+ /** Badge/tag field (list widget). */
145
+ badge?: string;
146
+ }
147
+
148
+ /**
149
+ * The u-widget spec envelope — a single, consistent structure for all widgets.
150
+ *
151
+ * Only `widget` is required. All other fields are optional or auto-inferred.
152
+ *
153
+ * @example
154
+ * ```ts
155
+ * const spec: UWidgetSpec = {
156
+ * widget: 'chart.bar',
157
+ * data: [{ name: 'A', value: 30 }, { name: 'B', value: 70 }],
158
+ * mapping: { x: 'name', y: 'value' },
159
+ * };
160
+ * ```
161
+ */
162
+ declare interface UWidgetSpec {
163
+ /** Widget type identifier (e.g., `"chart.bar"`, `"metric"`, `"form"`). */
164
+ widget: string;
165
+ /** Unique identifier for event correlation and compose children. */
166
+ id?: string;
167
+ /** Optional display title rendered above the widget. */
168
+ title?: string;
169
+ /** Optional description text rendered below the title. */
170
+ description?: string;
171
+ /** Inline data — an object (metric/gauge) or array of records (chart/table). */
172
+ data?: Record<string, unknown> | Record<string, unknown>[];
173
+ /** Maps data fields to visual channels. Auto-inferred when omitted. */
174
+ mapping?: UWidgetMapping;
175
+ /** Field definitions for form/confirm widgets. */
176
+ fields?: UWidgetFieldDefinition[];
177
+ /** Formdown shorthand syntax for form fields (mutually exclusive with `fields`). */
178
+ formdown?: string;
179
+ /**
180
+ * Widget-specific rendering options.
181
+ *
182
+ * Chart widgets support an `echarts` sub-key for native ECharts option passthrough:
183
+ * ```json
184
+ * { "options": { "echarts": { "tooltip": { "trigger": "axis" } } } }
185
+ * ```
186
+ * All keys in `options.echarts` are deep-merged into the generated ECharts option.
187
+ * @see https://echarts.apache.org/en/option.html
188
+ */
189
+ options?: Record<string, unknown>;
190
+ /** Action buttons displayed below the widget. */
191
+ actions?: UWidgetAction[];
192
+ /** Interchange format type marker. Always `"u-widget"` if present. */
193
+ type?: 'u-widget';
194
+ /** Interchange format version string. */
195
+ version?: string;
196
+ /** Layout mode for compose widget: `"stack"` (default), `"row"`, or `"grid"`. */
197
+ layout?: 'stack' | 'row' | 'grid';
198
+ /** Number of grid columns for compose `"grid"` layout. Default: 2. */
199
+ columns?: number;
200
+ /** Child widget specs for compose widget. */
201
+ children?: UWidgetChildSpec[];
202
+ /** Grid column span for children inside a compose `"grid"` layout. */
203
+ span?: number;
204
+ }
205
+
206
+ /**
207
+ * <uw-math> — LaTeX math expression renderer via KaTeX.
208
+ *
209
+ * Uses MathML output for zero-CSS rendering in Shadow DOM.
210
+ * Loaded via the `u-widgets/math` entry point. Requires `katex` as a peer dependency.
211
+ */
212
+ export declare class UwMath extends LitElement {
213
+ static styles: CSSResult[];
214
+ spec: UWidgetSpec | null;
215
+ theme: string | null;
216
+ render(): typeof nothing | TemplateResult<1>;
217
+ }
218
+
219
+ export { }
@@ -0,0 +1,95 @@
1
+ import { css as m, LitElement as u, nothing as p, html as c } from "lit";
2
+ import { property as d, customElement as h } from "lit/decorators.js";
3
+ import { t as f } from "./tokens-byMop3gk.js";
4
+ import g from "katex";
5
+ var v = Object.defineProperty, y = Object.getOwnPropertyDescriptor, l = (o, t, a, r) => {
6
+ for (var e = r > 1 ? void 0 : r ? y(t, a) : t, s = o.length - 1, n; s >= 0; s--)
7
+ (n = o[s]) && (e = (r ? n(t, a, e) : n(e)) || e);
8
+ return r && e && v(t, a, e), e;
9
+ };
10
+ let i = class extends u {
11
+ constructor() {
12
+ super(...arguments), this.spec = null, this.theme = null;
13
+ }
14
+ render() {
15
+ if (!this.spec) return p;
16
+ const o = this.spec.data;
17
+ if (!o) return p;
18
+ const t = String(o.expression ?? "").trim();
19
+ if (!t) return p;
20
+ const r = !!((this.spec.options ?? {}).displayMode ?? !1);
21
+ try {
22
+ const e = g.renderToString(t, {
23
+ displayMode: r,
24
+ throwOnError: !0,
25
+ output: "mathml"
26
+ });
27
+ return c`
28
+ <div
29
+ class="math-block"
30
+ part="math"
31
+ data-display=${String(r)}
32
+ .innerHTML=${e}
33
+ ></div>
34
+ `;
35
+ } catch (e) {
36
+ const s = e instanceof Error ? e.message : "Invalid expression";
37
+ return c`
38
+ <div class="math-error" part="math-error">
39
+ ${s}
40
+ <code>${t}</code>
41
+ </div>
42
+ `;
43
+ }
44
+ }
45
+ };
46
+ i.styles = [f, m`
47
+ :host {
48
+ display: block;
49
+ font-family: system-ui, -apple-system, sans-serif;
50
+ container: uw-math / inline-size;
51
+ }
52
+
53
+ .math-block {
54
+ color: var(--u-widget-text, #1a1a2e);
55
+ overflow-x: auto;
56
+ font-size: 1rem;
57
+ line-height: 1.6;
58
+ }
59
+
60
+ .math-block[data-display="true"] {
61
+ text-align: center;
62
+ padding: 8px 0;
63
+ font-size: 1.2rem;
64
+ }
65
+
66
+ .math-error {
67
+ padding: 8px 12px;
68
+ border-radius: 4px;
69
+ border: 1px solid var(--u-widget-negative, #dc2626);
70
+ background: color-mix(in srgb, var(--u-widget-negative, #dc2626) 8%, var(--u-widget-bg, #fff));
71
+ font-size: 0.8125rem;
72
+ color: var(--u-widget-negative, #dc2626);
73
+ }
74
+
75
+ .math-error code {
76
+ display: block;
77
+ margin-top: 4px;
78
+ font-size: 0.75rem;
79
+ color: var(--u-widget-text-secondary, #64748b);
80
+ word-break: break-all;
81
+ }
82
+ `];
83
+ l([
84
+ d({ type: Object })
85
+ ], i.prototype, "spec", 2);
86
+ l([
87
+ d({ type: String, reflect: !0 })
88
+ ], i.prototype, "theme", 2);
89
+ i = l([
90
+ h("uw-math")
91
+ ], i);
92
+ export {
93
+ i as UwMath
94
+ };
95
+ //# sourceMappingURL=u-widgets-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"u-widgets-math.js","sources":["../src/elements/uw-math.ts"],"sourcesContent":["import { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { UWidgetSpec } from '../core/types.js';\nimport { themeStyles } from '../styles/tokens.js';\nimport katex from 'katex';\n\n/**\n * <uw-math> — LaTeX math expression renderer via KaTeX.\n *\n * Uses MathML output for zero-CSS rendering in Shadow DOM.\n * Loaded via the `u-widgets/math` entry point. Requires `katex` as a peer dependency.\n */\n@customElement('uw-math')\nexport class UwMath extends LitElement {\n static styles = [themeStyles, css`\n :host {\n display: block;\n font-family: system-ui, -apple-system, sans-serif;\n container: uw-math / inline-size;\n }\n\n .math-block {\n color: var(--u-widget-text, #1a1a2e);\n overflow-x: auto;\n font-size: 1rem;\n line-height: 1.6;\n }\n\n .math-block[data-display=\"true\"] {\n text-align: center;\n padding: 8px 0;\n font-size: 1.2rem;\n }\n\n .math-error {\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid var(--u-widget-negative, #dc2626);\n background: color-mix(in srgb, var(--u-widget-negative, #dc2626) 8%, var(--u-widget-bg, #fff));\n font-size: 0.8125rem;\n color: var(--u-widget-negative, #dc2626);\n }\n\n .math-error code {\n display: block;\n margin-top: 4px;\n font-size: 0.75rem;\n color: var(--u-widget-text-secondary, #64748b);\n word-break: break-all;\n }\n `];\n\n @property({ type: Object })\n spec: UWidgetSpec | null = null;\n\n @property({ type: String, reflect: true })\n theme: string | null = null;\n\n render() {\n if (!this.spec) return nothing;\n\n const data = this.spec.data as Record<string, unknown> | undefined;\n if (!data) return nothing;\n\n const expression = String(data.expression ?? '').trim();\n if (!expression) return nothing;\n\n const options = (this.spec.options ?? {}) as Record<string, unknown>;\n const displayMode = Boolean(options.displayMode ?? false);\n\n try {\n // SAFETY: output must be 'mathml' — pure MathML has no script/event vectors,\n // making .innerHTML safe. Switching to 'html' or 'htmlAndMathml' would require\n // KaTeX CSS and introduce potential XSS via custom macros.\n const rendered = katex.renderToString(expression, {\n displayMode,\n throwOnError: true,\n output: 'mathml',\n });\n\n return html`\n <div\n class=\"math-block\"\n part=\"math\"\n data-display=${String(displayMode)}\n .innerHTML=${rendered}\n ></div>\n `;\n } catch (e) {\n const msg = e instanceof Error ? e.message : 'Invalid expression';\n return html`\n <div class=\"math-error\" part=\"math-error\">\n ${msg}\n <code>${expression}</code>\n </div>\n `;\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'uw-math': UwMath;\n }\n}\n"],"names":["UwMath","LitElement","nothing","data","expression","displayMode","rendered","katex","html","msg","themeStyles","css","__decorateClass","property","customElement"],"mappings":";;;;;;;;;AAaO,IAAMA,IAAN,cAAqBC,EAAW;AAAA,EAAhC,cAAA;AAAA,UAAA,GAAA,SAAA,GAwCL,KAAA,OAA2B,MAG3B,KAAA,QAAuB;AAAA,EAAA;AAAA,EAEvB,SAAS;AACP,QAAI,CAAC,KAAK,KAAM,QAAOC;AAEvB,UAAMC,IAAO,KAAK,KAAK;AACvB,QAAI,CAACA,EAAM,QAAOD;AAElB,UAAME,IAAa,OAAOD,EAAK,cAAc,EAAE,EAAE,KAAA;AACjD,QAAI,CAACC,EAAY,QAAOF;AAGxB,UAAMG,IAAc,IADH,KAAK,KAAK,WAAW,CAAA,GACF,eAAe;AAEnD,QAAI;AAIF,YAAMC,IAAWC,EAAM,eAAeH,GAAY;AAAA,QAChD,aAAAC;AAAA,QACA,cAAc;AAAA,QACd,QAAQ;AAAA,MAAA,CACT;AAED,aAAOG;AAAA;AAAA;AAAA;AAAA,yBAIY,OAAOH,CAAW,CAAC;AAAA,uBACrBC,CAAQ;AAAA;AAAA;AAAA,IAG3B,SAAS,GAAG;AACV,YAAMG,IAAM,aAAa,QAAQ,EAAE,UAAU;AAC7C,aAAOD;AAAA;AAAA,YAEDC,CAAG;AAAA,kBACGL,CAAU;AAAA;AAAA;AAAA,IAGxB;AAAA,EACF;AACF;AArFaJ,EACJ,SAAS,CAACU,GAAaC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoC7B;AAGDC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAvCfb,EAwCX,WAAA,QAAA,CAAA;AAGAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA1C9Bb,EA2CX,WAAA,SAAA,CAAA;AA3CWA,IAANY,EAAA;AAAA,EADNE,EAAc,SAAS;AAAA,GACXd,CAAA;"}