Skip to content

Commit 8eb0a87

Browse files
committed
feat(labels): add boolean shorthand for labels spec
Accept `labels: false` to disable all labels or `labels: true` for defaults, in addition to the existing LabelConfig object. Works in top-level specs, layer specs, and responsive breakpoint overrides.
1 parent ccc2a1d commit 8eb0a87

5 files changed

Lines changed: 46 additions & 21 deletions

File tree

packages/core/src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export type {
127127
GraphSpecWithoutData,
128128
LabelConfig,
129129
LabelDensity,
130+
LabelSpec,
130131
LayerSpec,
131132
LegendConfig,
132133
LinearGradient,

packages/core/src/types/spec.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,9 @@ export interface LabelConfig {
705705
offsets?: Record<string, AnnotationOffset>;
706706
}
707707

708+
/** Shorthand: `false` disables all labels, `true` uses defaults, or pass a full config object. */
709+
export type LabelSpec = boolean | LabelConfig;
710+
708711
// ---------------------------------------------------------------------------
709712
// Legend configuration
710713
// ---------------------------------------------------------------------------
@@ -813,7 +816,7 @@ export interface ChartSpecOverride {
813816
/** Override editorial chrome at this breakpoint. */
814817
chrome?: Chrome;
815818
/** Override label configuration at this breakpoint. */
816-
labels?: LabelConfig;
819+
labels?: LabelSpec;
817820
/** Override legend configuration at this breakpoint. */
818821
legend?: LegendConfig;
819822
/** Override annotations at this breakpoint. */
@@ -846,8 +849,8 @@ export interface ChartSpec {
846849
chrome?: Chrome;
847850
/** Data annotations (text callouts, highlighted ranges, reference lines). */
848851
annotations?: Annotation[];
849-
/** Label display configuration (density, format). */
850-
labels?: LabelConfig;
852+
/** Label display configuration. `false` disables all labels, `true` uses defaults. */
853+
labels?: LabelSpec;
851854
/** Legend display configuration (position override). */
852855
legend?: LegendConfig;
853856
/** Whether the chart adapts to container width. Defaults to true. */
@@ -1019,8 +1022,8 @@ export interface LayerSpec {
10191022
chrome?: Chrome;
10201023
/** Annotations on the layered view. */
10211024
annotations?: Annotation[];
1022-
/** Label display configuration. */
1023-
labels?: LabelConfig;
1025+
/** Label display configuration. `false` disables all labels, `true` uses defaults. */
1026+
labels?: LabelSpec;
10241027
/** Legend display configuration. */
10251028
legend?: LegendConfig;
10261029
/** Whether the chart adapts to container width. Defaults to true. */

packages/engine/src/compile.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -237,14 +237,23 @@ export function compileChart(spec: unknown, options: CompileOptions): ChartLayou
237237
},
238238
};
239239
}
240-
if (bp.labels) {
241-
chartSpec = {
242-
...chartSpec,
243-
labels: {
244-
...chartSpec.labels,
245-
...(bp.labels as NormalizedChartSpec['labels']),
246-
},
247-
};
240+
if (bp.labels !== undefined) {
241+
if (typeof bp.labels === 'boolean') {
242+
chartSpec = {
243+
...chartSpec,
244+
labels: bp.labels
245+
? { density: 'auto', format: '', prefix: '' }
246+
: { density: 'none', format: '', prefix: '' },
247+
};
248+
} else {
249+
chartSpec = {
250+
...chartSpec,
251+
labels: {
252+
...chartSpec.labels,
253+
...(bp.labels as NormalizedChartSpec['labels']),
254+
},
255+
};
256+
}
248257
}
249258
if (bp.legend) {
250259
chartSpec = {

packages/engine/src/compiler/normalize.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
Encoding,
1818
FieldType,
1919
GraphSpec,
20+
LabelSpec,
2021
LayerSpec,
2122
SankeySpec,
2223
TableSpec,
@@ -189,6 +190,21 @@ function normalizeAnnotations(annotations: Annotation[] | undefined): Annotation
189190
});
190191
}
191192

193+
// ---------------------------------------------------------------------------
194+
// Label normalization
195+
// ---------------------------------------------------------------------------
196+
197+
function normalizeLabels(labels?: LabelSpec): NormalizedChartSpec['labels'] {
198+
if (labels === false) return { density: 'none', format: '', prefix: '' };
199+
if (labels === true || labels === undefined) return { density: 'auto', format: '', prefix: '' };
200+
return {
201+
density: labels.density ?? 'auto',
202+
format: labels.format ?? '',
203+
prefix: labels.prefix ?? '',
204+
offsets: labels.offsets,
205+
};
206+
}
207+
192208
// ---------------------------------------------------------------------------
193209
// Spec-level normalization
194210
// ---------------------------------------------------------------------------
@@ -205,12 +221,7 @@ function normalizeChartSpec(spec: ChartSpec, warnings: string[]): NormalizedChar
205221
encoding,
206222
chrome: normalizeChrome(spec.chrome),
207223
annotations: normalizeAnnotations(spec.annotations),
208-
labels: {
209-
density: spec.labels?.density ?? 'auto',
210-
format: spec.labels?.format ?? '',
211-
prefix: spec.labels?.prefix ?? '',
212-
offsets: spec.labels?.offsets,
213-
},
224+
labels: normalizeLabels(spec.labels),
214225
legend: spec.legend,
215226
responsive: spec.responsive ?? true,
216227
theme: spec.theme ?? {},

packages/vanilla/src/mount.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,8 +1181,9 @@ function wireSeriesLabelDrag(
11811181
const labels = svg.querySelectorAll('.oc-mark-label');
11821182
const cleanups: Array<() => void> = [];
11831183

1184-
// Read existing label offsets from the spec
1185-
const labelsConfig = 'labels' in spec ? spec.labels : undefined;
1184+
// Read existing label offsets from the spec (skip boolean shorthand)
1185+
const rawLabels = 'labels' in spec ? spec.labels : undefined;
1186+
const labelsConfig = typeof rawLabels === 'object' ? rawLabels : undefined;
11861187

11871188
for (const label of labels) {
11881189
const labelEl = label as SVGTextElement;

0 commit comments

Comments
 (0)