@object-ui/plugin-charts 6.2.3 → 7.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,184 @@
1
1
  # @object-ui/plugin-charts
2
2
 
3
+ ## 7.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 677f7ed: feat(charts,dashboard): data-screen customization primitives
8
+
9
+ - object-metric `variant:'bare'` — big tinted number + label, no card chrome
10
+ (data-screen KPIs that stay data-bound).
11
+ - object-chart `colors` prop overrides the theme `--chart-1..n` palette so a
12
+ page/dashboard can brand its charts; compact metric formatting (`'0.0a'` →
13
+ "1.1M").
14
+ - ObjectChartSchema.chartType widened to donut/horizontal-bar/column.
15
+
16
+ ### Patch Changes
17
+
18
+ - 08c47da: feat(dashboard): dataset chart widgets paint select/lookup dimensions in their option colors
19
+
20
+ A dashboard `DatasetWidget` chart grouped by a select/lookup dimension (e.g.
21
+ project `health`) painted its categories from the generic `--chart-1..5`
22
+ palette — the same gap the chart view (`object-chart`) had before #1932. It now
23
+ resolves the dimension field's option colors (using the dataset's base `object`
24
+ - dimension→field map the query already returns) and threads them to the
25
+ renderer as a per-category `categoryColors` map, so health green/red/yellow
26
+ paints semantically.
27
+
28
+ The value/label→color resolution is extracted into a shared `buildOptionColorMap`
29
+ (`@object-ui/core`) now used by both `DatasetWidget` and `ObjectChart`.
30
+
31
+ - 93cf2b1: fix(charts): use field option colors for categorical chart dimensions
32
+
33
+ An `object-chart` grouped by a select/lookup field (e.g. project `health`)
34
+ painted its categories from the generic `--chart-1..5` palette, so a "Red"
35
+ health slice rendered teal and "Green" rendered blue. The chart now resolves
36
+ the category dimension's option colors — both the `objectName` + `groupBy`
37
+ path and the dataset path (via the dataset's `object` + dimension `field`) —
38
+ and threads them to the renderer as a per-category `categoryColors` map. That
39
+ map wins over the positional palette and falls back to it for categories
40
+ without an option color, so pie/donut slices and bar cells render in their
41
+ semantic colors.
42
+
43
+ - Updated dependencies [677f7ed]
44
+ - Updated dependencies [08c47da]
45
+ - Updated dependencies [a71be60]
46
+ - Updated dependencies [cb03bc3]
47
+ - @object-ui/types@7.1.0
48
+ - @object-ui/core@7.1.0
49
+ - @object-ui/react@7.1.0
50
+ - @object-ui/components@7.1.0
51
+ - @object-ui/i18n@7.1.0
52
+
53
+ ## 7.0.0
54
+
55
+ ### Patch Changes
56
+
57
+ - c5a7d6f: Bar-chart X-axis labels no longer overlap on narrow widgets. When a chart has
58
+ many categories (>4) or any long label (>8 chars), the tick labels are angled
59
+ (-32°) and truncated with a hover `title`; few short labels stay horizontal.
60
+ - cb2fdb1: feat(dashboard): expand drill-in — table/list row→record + scatter/treemap/sankey drill-through
61
+
62
+ Drill-in now covers the widgets that were missing it, and formalizes the two
63
+ interaction semantics mainstream BI/low-code platforms separate. `DrillDownConfig`
64
+ gains a `mode` discriminator: `'filter'` (drill-through: aggregate bucket → filtered
65
+ record list) and `'record'` (drill-to-record: a table/list row → that record's detail).
66
+
67
+ - Scatter, treemap and sankey charts now wire click → the existing filtered-record
68
+ drill drawer (radar excluded — no single clickable category point). The
69
+ Recharts-payload → drill-event mapping is extracted to pure, tested functions.
70
+ - Object-backed table/list widgets drill to the clicked record in a read-only detail
71
+ drawer (Sheet/Dialog), on by default (`drillDown:{enabled:false}` opts out). Field
72
+ labels and value formatting (incl. tenant-default currency) are shared with the
73
+ table cells so a value reads identically in both. An author-supplied `onRowClick`
74
+ still wins.
75
+ - The chart/KPI drill-through record lists now drill into a record too, completing the
76
+ segment → list → record chain.
77
+
78
+ - c3749eb: feat(dashboard): dataset chart widgets drill through to records
79
+
80
+ Dataset-bound **chart** widgets (bar/line/pie/area/donut/funnel/…) are now
81
+ click-drillable, matching table/pivot. Clicking a segment maps it back to its
82
+ dataset row and opens the same governed drill drawer (raw group keys preserved),
83
+ so a chart-only dashboard is no longer an exploration dead-end. This closes the
84
+ "object-backed chart drills but dataset chart doesn't" inconsistency and aligns
85
+ with mainstream BI (click a chart → see records).
86
+
87
+ - `@object-ui/core`: `findChartSeriesRow` — inverse of `buildChartSeries`,
88
+ maps a clicked `{category, series}` back to the source dataset row index
89
+ (matches both dims when a 2nd dimension is pivoted into series).
90
+ - `ObjectChart`: optional `onSegmentClick` lets a host own the chart click
91
+ (and suppress the widget's own object-drill).
92
+ - `DatasetWidget`: lifts the drill machinery to cover both table/pivot and
93
+ chart, and wires the chart's segment click to the precise dataset drill.
94
+
95
+ - 6cfa330: feat(dashboard): drill "Open in list" escape hatch + unify report drill
96
+
97
+ Adopts the mainstream BI peek-then-escalate drill model. Drill-through opens an
98
+ in-place drawer (keep context) and offers an "Open in list →" affordance to
99
+ escalate to the object's full list page (sort / bulk-select / export / shareable
100
+ URL) — the Looker / Power BI "see records → open in page" pattern.
101
+
102
+ - New `DrillNavigationContext` (`@object-ui/react`): the app shell provides
103
+ `openRecordList`; the renderer stays decoupled from console routing.
104
+ - The drill drawers (pivot / dataset / chart / KPI) render the escape hatch when
105
+ a host navigation handler is present, and hide it otherwise (self-contained
106
+ peek). `DashboardView` provides the handler via `useOpenRecordList`.
107
+ - `DrillDownConfig.target` gains `'navigate'` — skip the drawer and open the
108
+ list directly; degrades to `'drawer'` when no host handler is available.
109
+ - `ReportView` drill-through now opens the same in-place drawer (peek records →
110
+ click a row to open a record) instead of navigating away; the escape hatch
111
+ preserves the previous navigate-to-list behavior. Dashboard and report drill
112
+ are now unified.
113
+ - i18n: `dashboard.openInList` (en / zh).
114
+
115
+ - e270c7d: fix(chart): consume ADR-0021 `dataset` binding in list/object chart views
116
+
117
+ Chart views authored to the current spec (ADR-0021: `dataset` + `dimensions` +
118
+ `values`) previously rendered nothing — the renderers only read the **removed**
119
+ legacy inline `xAxisField` / `yAxisFields` / `aggregation` shape, so a
120
+ spec-compliant chart view showed an empty canvas. `ObjectChart` now runs the
121
+ governed `queryDataset` path when a chart binds to a dataset (the same path the
122
+ dashboard `DatasetWidget` uses, so numbers stay consistent), and `ListView` /
123
+ `ObjectView` emit the dataset shape. The legacy inline aggregate is kept as a
124
+ deprecated fallback so pre-ADR-0021 metadata keeps rendering.
125
+
126
+ Refs objectstack-ai/framework#1890
127
+
128
+ - ab168e4: Dashboard charts no longer render blank on first paint. Recharts'
129
+ `ResponsiveContainer` was a child of a `flex … justify-center` box, so it
130
+ collapsed to content width (0) on first paint inside react-grid-layout,
131
+ measured `width(-1)` and skipped drawing until a later resize fired its
132
+ ResizeObserver. The chart wrapper is now a definite-width block in both the
133
+ dashboard chart container (`plugin-charts/ChartContainerImpl`) and the shadcn
134
+ base (`components/ui/chart`). Follow-up changeset for #1634.
135
+ - Updated dependencies [5976ba3]
136
+ - Updated dependencies [a00e16d]
137
+ - Updated dependencies [eaccefd]
138
+ - Updated dependencies [f7f325d]
139
+ - Updated dependencies [c12986e]
140
+ - Updated dependencies [71d7ce0]
141
+ - Updated dependencies [053c948]
142
+ - Updated dependencies [89e113c]
143
+ - Updated dependencies [ddbe4a2]
144
+ - Updated dependencies [2d47e94]
145
+ - Updated dependencies [9049bbe]
146
+ - Updated dependencies [77cc6bb]
147
+ - Updated dependencies [6c0c92c]
148
+ - Updated dependencies [97c6831]
149
+ - Updated dependencies [cb2fdb1]
150
+ - Updated dependencies [c3749eb]
151
+ - Updated dependencies [c09f44e]
152
+ - Updated dependencies [6cfa330]
153
+ - Updated dependencies [ad8ade6]
154
+ - Updated dependencies [d54346c]
155
+ - Updated dependencies [3870c20]
156
+ - Updated dependencies [2eb3096]
157
+ - Updated dependencies [b88c560]
158
+ - Updated dependencies [0ad72a6]
159
+ - Updated dependencies [3fa23a7]
160
+ - Updated dependencies [18d0339]
161
+ - Updated dependencies [59b6bbb]
162
+ - Updated dependencies [d16566f]
163
+ - Updated dependencies [90acb7f]
164
+ - Updated dependencies [7913390]
165
+ - Updated dependencies [1394e34]
166
+ - Updated dependencies [e95cc25]
167
+ - Updated dependencies [abe8ebc]
168
+ - Updated dependencies [300d755]
169
+ - Updated dependencies [bd8b054]
170
+ - Updated dependencies [4eb9cb6]
171
+ - Updated dependencies [7c239fd]
172
+ - Updated dependencies [858ad94]
173
+ - Updated dependencies [2270239]
174
+ - Updated dependencies [2f31406]
175
+ - Updated dependencies [8d1195d]
176
+ - @object-ui/core@7.0.0
177
+ - @object-ui/components@7.0.0
178
+ - @object-ui/react@7.0.0
179
+ - @object-ui/i18n@7.0.0
180
+ - @object-ui/types@7.0.0
181
+
3
182
  ## 6.2.3
4
183
 
5
184
  ### Patch Changes
@@ -0,0 +1,61 @@
1
+ import { ChartConfig } from './ChartContainerImpl';
2
+ /**
3
+ * ObjectUI
4
+ * Copyright (c) 2024-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ import * as React from "react";
10
+ export interface AdvancedChartImplProps {
11
+ chartType?: 'bar' | 'column' | 'horizontal-bar' | 'line' | 'area' | 'pie' | 'donut' | 'radar' | 'scatter' | 'funnel' | 'combo' | 'treemap' | 'sankey';
12
+ data?: Array<Record<string, any>>;
13
+ config?: ChartConfig;
14
+ xAxisKey?: string;
15
+ series?: Array<{
16
+ dataKey: string;
17
+ chartType?: 'bar' | 'line' | 'area';
18
+ variant?: 'current' | 'comparison';
19
+ opacity?: number;
20
+ dashArray?: string;
21
+ label?: string;
22
+ }>;
23
+ className?: string;
24
+ /** Categorical/series colour palette. Overrides the theme's `--chart-1..n`
25
+ * defaults so a page/dashboard can brand its charts (data-screens). */
26
+ colors?: string[];
27
+ /**
28
+ * Per-category colour map keyed by the category value OR its display label
29
+ * (e.g. `{ green: '#10B981', Green: '#10B981' }`). When the chart's category
30
+ * dimension is a select/lookup field, ObjectChart resolves the field's option
31
+ * colours into this map so a "Red" health slice paints red instead of taking
32
+ * the next positional palette slot. A category found here WINS over `colors`;
33
+ * categories absent here fall back to the positional palette, then the theme.
34
+ */
35
+ categoryColors?: Record<string, string>;
36
+ /**
37
+ * Optional drill-down click handler. Fires when a chart segment is clicked
38
+ * with `{ category, series, value }`. Wired for bar/horizontal-bar/line/
39
+ * area/pie/donut. Other chart types are no-ops in L1.
40
+ */
41
+ onChartClick?: (event: {
42
+ category?: string;
43
+ series?: string;
44
+ value?: number;
45
+ }) => void;
46
+ /**
47
+ * Disable Recharts' entrance animation when `false`. Animations drive the
48
+ * reveal via `requestAnimationFrame`, which browsers throttle/pause in
49
+ * hidden/background tabs — so a chart rendered off-screen (analytics export,
50
+ * a report opened in an inactive tab, headless capture) can freeze at frame 0
51
+ * and look empty (esp. pie/donut: sectors at angle 0 = no ring, legend only).
52
+ * Reports pass `false` for a deterministic, instant, export-safe render.
53
+ * Omitted/true preserves the animated default everywhere else (dashboards).
54
+ */
55
+ isAnimationActive?: boolean;
56
+ }
57
+ /**
58
+ * AdvancedChartImpl - The heavy implementation that imports Recharts with full features
59
+ * This component is lazy-loaded to avoid including Recharts in the initial bundle
60
+ */
61
+ export default function AdvancedChartImpl({ chartType: rawChartType, data: rawData, config, xAxisKey, series, className, colors, categoryColors, onChartClick, isAnimationActive, }: AdvancedChartImplProps): React.JSX.Element;
@@ -26,13 +26,13 @@ export type ChartConfig = {
26
26
  declare function ChartContainer({ id, className, children, config, ...props }: React.ComponentProps<"div"> & {
27
27
  config: ChartConfig;
28
28
  children: React.ComponentProps<typeof ResponsiveContainer>["children"];
29
- }): import("react/jsx-runtime").JSX.Element;
29
+ }): React.JSX.Element;
30
30
  declare const ChartStyle: ({ id, config }: {
31
31
  id: string;
32
32
  config: ChartConfig;
33
- }) => import("react/jsx-runtime").JSX.Element | null;
33
+ }) => React.JSX.Element | null;
34
34
  declare const ChartTooltip: typeof Tooltip;
35
- declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }: any): import("react/jsx-runtime").JSX.Element | null;
35
+ declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }: any): React.JSX.Element | null;
36
36
  declare const ChartLegend: React.MemoExoticComponent<(outsideProps: import('recharts').LegendProps) => React.ReactPortal | null>;
37
- declare function ChartLegendContent({ className, hideIcon, payload, verticalAlign, nameKey, }: any): import("react/jsx-runtime").JSX.Element | null;
37
+ declare function ChartLegendContent({ className, hideIcon, payload, verticalAlign, nameKey, }: any): React.JSX.Element | null;
38
38
  export { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, ChartStyle, };
@@ -17,4 +17,4 @@ export interface ChartImplProps {
17
17
  * ChartImpl - The heavy implementation that imports Recharts
18
18
  * This component is lazy-loaded to avoid including Recharts in the initial bundle
19
19
  */
20
- export default function ChartImpl({ data, dataKey, xAxisKey, height, className, color, }: ChartImplProps): import("react/jsx-runtime").JSX.Element;
20
+ export default function ChartImpl({ data, dataKey, xAxisKey, height, className, color, }: ChartImplProps): import("react").JSX.Element;
@@ -20,7 +20,7 @@ export interface ChartRendererProps {
20
20
  type: string;
21
21
  id?: string;
22
22
  className?: string;
23
- chartType?: 'bar' | 'column' | 'horizontal-bar' | 'line' | 'area' | 'pie' | 'donut' | 'radar' | 'scatter' | 'funnel' | 'combo';
23
+ chartType?: 'bar' | 'column' | 'horizontal-bar' | 'line' | 'area' | 'pie' | 'donut' | 'radar' | 'scatter' | 'funnel' | 'combo' | 'treemap' | 'sankey';
24
24
  data?: Array<Record<string, any>>;
25
25
  config?: Record<string, any>;
26
26
  xAxisKey?: string;
@@ -32,6 +32,14 @@ export interface ChartRendererProps {
32
32
  dashArray?: string;
33
33
  chartType?: 'bar' | 'line' | 'area';
34
34
  }>;
35
+ colors?: string[];
36
+ /** Per-category colour map (value/label → colour). Wins over `colors` per
37
+ * category; see AdvancedChartImpl. Set by ObjectChart from select/lookup
38
+ * dimension option colours and/or an explicit author map. */
39
+ categoryColors?: Record<string, string>;
40
+ /** Pass `false` for a deterministic, export-safe render with no entrance
41
+ * animation (see AdvancedChartImpl). Omitted → animated default. */
42
+ isAnimationActive?: boolean;
35
43
  };
36
44
  /** Drill-down click handler — wired by ObjectChart when drillDown is enabled. */
37
45
  onChartClick?: (event: {
@@ -1,3 +1,4 @@
1
+ import { default as React } from 'react';
1
2
  /**
2
3
  * Humanize a snake_case or kebab-case string into Title Case.
3
4
  * Local implementation to avoid a dependency on @object-ui/fields.
@@ -27,5 +28,5 @@ export declare function aggregateRecords(records: any[], aggregate: {
27
28
  * to perform any value→label conversion.
28
29
  */
29
30
  export declare function resolveGroupByLabels(data: any[], groupByField: string, objectSchema: any, dataSource?: any, translateOption?: (value: string, fallbackLabel: string) => string): Promise<any[]>;
30
- export { extractRecords } from '../../core/src';
31
- export declare const ObjectChart: (props: any) => import("react/jsx-runtime").JSX.Element;
31
+ export { extractRecords } from '@object-ui/core';
32
+ export declare const ObjectChart: (props: any) => React.JSX.Element;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * Pure mappers from a Recharts element-click payload to the shared
9
+ * `{ category, series, value }` drill event consumed by ObjectChart's drill
10
+ * drawer. Kept separate from AdvancedChartImpl so the (Recharts-shape-sensitive)
11
+ * payload extraction can be unit-tested without rendering a chart.
12
+ */
13
+ export interface ChartDrillEvent {
14
+ category?: string;
15
+ series?: string;
16
+ value?: number;
17
+ }
18
+ interface SeriesLike {
19
+ dataKey?: string;
20
+ }
21
+ /**
22
+ * Scatter point click. Recharts spreads the data row onto the node and also
23
+ * exposes it under `.payload`; we read the category (xAxisKey) and the
24
+ * y-measure from whichever is present. Returns `null` when there's no category.
25
+ */
26
+ export declare function mapScatterClick(node: any, xAxisKey: string, series: SeriesLike[] | undefined): ChartDrillEvent | null;
27
+ /**
28
+ * Treemap tile click. The node carries the category label as `name` and the
29
+ * measure as `value`/`size`. Returns `null` when there's no name.
30
+ */
31
+ export declare function mapTreemapClick(node: any, series: SeriesLike[] | undefined): ChartDrillEvent | null;
32
+ /**
33
+ * Sankey click. Drill only on flow *nodes* (categories): links carry
34
+ * source/target indices but no `name`, and the synthetic root node (depth 0)
35
+ * aggregates everything. Returns `null` for those so they don't drill.
36
+ */
37
+ export declare function mapSankeyClick(payload: any, series: SeriesLike[] | undefined): ChartDrillEvent | null;
38
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,2 +1,8 @@
1
- export * from './packages/plugin-charts/src/index'
2
- export {}
1
+ import { ChartBarRenderer, ChartRenderer } from './ChartRenderer';
2
+ export type { BarChartSchema } from './types';
3
+ export { ChartBarRenderer, ChartRenderer };
4
+ export { ObjectChart } from './ObjectChart';
5
+ export declare const chartComponents: {
6
+ 'bar-chart': import('react').FC<import('./ChartRenderer').ChartBarRendererProps>;
7
+ chart: import('react').FC<import('./ChartRenderer').ChartRendererProps>;
8
+ };