@opendata-ai/openchart-core 6.2.0 → 6.3.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/dist/index.d.ts CHANGED
@@ -177,7 +177,7 @@ interface ColumnConfig {
177
177
  * - 'tick': strip/rug plot marks
178
178
  * - 'rect': heatmaps and 2D binned plots
179
179
  */
180
- type MarkType = 'bar' | 'line' | 'area' | 'point' | 'circle' | 'arc' | 'text' | 'rule' | 'tick' | 'rect';
180
+ type MarkType = 'bar' | 'line' | 'area' | 'point' | 'circle' | 'arc' | 'text' | 'rule' | 'tick' | 'rect' | 'lollipop';
181
181
  /** @deprecated Use MarkType instead. Kept for internal migration references. */
182
182
  type ChartType = MarkType;
183
183
  /**
@@ -618,6 +618,10 @@ interface LegendConfig {
618
618
  offset?: AnnotationOffset;
619
619
  /** Whether to show the legend. Defaults to true. Set to false to hide. */
620
620
  show?: boolean;
621
+ /** Number of columns for horizontal legend layout. Overrides the default row limit. */
622
+ columns?: number;
623
+ /** Max number of legend entries before truncation. Remaining entries show as "+N more". */
624
+ symbolLimit?: number;
621
625
  }
622
626
  /** Data row: a plain object with string keys. */
623
627
  type DataRow = Record<string, unknown>;
@@ -2342,6 +2346,18 @@ interface LabelCandidate {
2342
2346
  * Detect AABB (axis-aligned bounding box) overlap between two rectangles.
2343
2347
  */
2344
2348
  declare function detectCollision(a: Rect, b: Rect): boolean;
2349
+ /** An offset position to try when resolving a label collision. */
2350
+ interface OffsetStrategy {
2351
+ dx: number;
2352
+ dy: number;
2353
+ }
2354
+ /** Offsets to try when a label collides with an existing placement. */
2355
+ declare const OFFSET_STRATEGIES: readonly OffsetStrategy[];
2356
+ /**
2357
+ * Extended offset strategies with additional vertical spread for dense
2358
+ * multi-series endpoints (e.g. 5+ line series converging at similar y-values).
2359
+ */
2360
+ declare const EXTENDED_OFFSET_STRATEGIES: readonly OffsetStrategy[];
2345
2361
  /**
2346
2362
  * Resolve label collisions using a greedy placement algorithm.
2347
2363
  *
@@ -2351,9 +2367,10 @@ declare function detectCollision(a: Rect, b: Rect): boolean;
2351
2367
  * demoted to tooltip-only (visible: false).
2352
2368
  *
2353
2369
  * @param labels - Array of label candidates to position.
2370
+ * @param strategies - Optional offset strategies to use (defaults to OFFSET_STRATEGIES).
2354
2371
  * @returns Array of resolved labels with computed positions and visibility.
2355
2372
  */
2356
- declare function resolveCollisions(labels: LabelCandidate[]): ResolvedLabel[];
2373
+ declare function resolveCollisions(labels: LabelCandidate[], strategies?: readonly OffsetStrategy[]): ResolvedLabel[];
2357
2374
  /**
2358
2375
  * Compute the bounding rect of a resolved label from its position and text.
2359
2376
  * Uses heuristic text measurement so it works without DOM access.
@@ -2401,8 +2418,12 @@ type DateGranularity = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' |
2401
2418
  * @param value - Date object, ISO string, or timestamp number.
2402
2419
  * @param locale - Locale string (currently unused, reserved for i18n).
2403
2420
  * @param granularity - Time granularity for format selection.
2421
+ * @param useUtc - Whether to infer granularity and format using UTC methods.
2422
+ * Pass `false` when formatting ticks from a local-time scale (d3 scaleTime),
2423
+ * so that e.g. midnight local isn't misread as an intra-day UTC time.
2424
+ * Defaults to `true` for backward compatibility.
2404
2425
  */
2405
- declare function formatDate(value: Date | string | number, _locale?: string, granularity?: DateGranularity): string;
2426
+ declare function formatDate(value: Date | string | number, _locale?: string, granularity?: DateGranularity, useUtc?: boolean): string;
2406
2427
  /**
2407
2428
  * Build a formatter for temporal values using a d3-time-format string (e.g. "%Y", "%b %Y").
2408
2429
  * Returns a function that accepts a Date, string, or number and returns the formatted string.
@@ -2613,4 +2634,4 @@ declare function scatterChart(data: DataRow[], x: FieldRef, y: FieldRef, options
2613
2634
  */
2614
2635
  declare function dataTable(data: DataRow[], options?: TableBuilderOptions): TableSpec;
2615
2636
 
2616
- export { type A11yMetadata, type AggregateOp, type Annotation, type AnnotationAnchor, type AnnotationOffset, type AnnotationPosition, type ArcMark, type AreaMark, type AxisConfig, type AxisLabelDensity, type AxisLayout, type AxisTick, BRAND_FONT_SIZE, BRAND_MIN_WIDTH, BRAND_RESERVE_WIDTH, type BarColumnConfig, type BarTableCell, type BinParams, type BinTransform, type Breakpoint, CATEGORICAL_PALETTE, CHART_ENCODING_RULES, CHART_TYPES, type CalculateExpression, type CalculateTransform, type CategoricalPalette, type CategoryColorsConfig, type CategoryTableCell, type CellStyle, type ChannelRule, type ChartBuilderOptions, type ChartEventHandlers, type ChartLayout, type ChartSpec, type ChartSpecOverride, type ChartSpecWithoutData, type ChartType, type Chrome, type ChromeDefaults, type ChromeKey, type ChromeMode, type ChromeText, type ChromeTextStyle, type ColorBlindnessType, type ColumnConfig, type CompileOptions, type CompileTableOptions, type Condition, type ConditionalValueDef, DEFAULT_THEME, DIVERGING_PALETTES, type DarkMode, type DataRow, type DateGranularity, type DivergingPalette, type ElementEdit, type Encoding, type EncodingChannel, type EncodingRule, type FieldPredicate, type FieldRef, type FieldType, type FilterPredicate, type FilterTransform, type FlagTableCell, GRAPH_ENCODING_RULES, type GraphChannelRule, type GraphEdge, type GraphEdgeLayout, type GraphEncoding, type GraphEncodingChannel, type GraphLayout, type GraphLayoutConfig, type GraphNode, type GraphNodeLayout, type GraphSpec, type GraphSpecWithoutData, type Gridline, type HeatmapColumnConfig, type HeatmapTableCell, type HeightClass, type ImageColumnConfig, type ImageTableCell, type LabelCandidate, type LabelConfig, type LabelDensity, type LabelMode, type LabelPriority, type LayerSpec, type LayoutStrategy, type LegendConfig, type LegendEntry, type LegendLayout, type LegendPosition, type LineMark, type LogicalAnd, type LogicalNot, type LogicalOr, MARK_DISPLAY_NAMES, MARK_ENCODING_RULES, MARK_TYPES, type Margins, type Mark, type MarkAria, type MarkDef, type MarkEvent, type MarkType, type MeasureTextFn, type NodeOverride, type PaginationState, type Point, type PointMark, type RangeAnnotation, type Rect, type RectMark, type RefLineAnnotation, type ResolveConfig, type ResolveMode, type ResolvedAnnotation, type ResolvedChrome, type ResolvedChromeElement, type ResolvedColumn, type ResolvedLabel, type ResolvedTheme, type RuleMarkLayout, SEQUENTIAL_PALETTES, type ScaleConfig, type ScaleType, type SequentialPalette, type SeriesStyle, type SortState, type SparklineColumnConfig, type SparklineData, type SparklineTableCell, type StoredVizSpec, type TableBuilderOptions, type TableCell, type TableCellBase, type TableLayout, type TableRow, type TableSpec, type TableSpecWithoutData, type TextAnnotation, type TextMarkLayout, type TextStyle, type TextTableCell, type Theme, type ThemeChromeDefaults, type ThemeColors, type ThemeConfig, type ThemeFontSizes, type ThemeFontWeights, type ThemeFonts, type ThemeSpacing, type TickMarkLayout, type TimeUnit, type TimeUnitTransform, type TooltipContent, type TooltipField, type Transform, type VizSpec, abbreviateNumber, adaptColorForDarkMode, adaptTheme, areaChart, barChart, buildD3Formatter, buildTemporalFormatter, checkPaletteDistinguishability, columnChart, computeChrome, computeLabelBounds, contrastRatio, dataTable, detectCollision, donutChart, dotChart, estimateTextWidth, findAccessibleColor, formatDate, formatNumber, generateAltText, generateAriaLabels, generateDataTable, getBreakpoint, getHeightClass, getLayoutStrategy, inferFieldType, isChartSpec, isConditionalDef, isEncodingChannel, isGraphSpec, isLayerSpec, isRangeAnnotation, isRefLineAnnotation, isTableSpec, isTextAnnotation, lineChart, meetsAA, pieChart, resolveCollisions, resolveMarkDef, resolveMarkType, resolveTheme, scatterChart, simulateColorBlindness };
2637
+ export { type A11yMetadata, type AggregateOp, type Annotation, type AnnotationAnchor, type AnnotationOffset, type AnnotationPosition, type ArcMark, type AreaMark, type AxisConfig, type AxisLabelDensity, type AxisLayout, type AxisTick, BRAND_FONT_SIZE, BRAND_MIN_WIDTH, BRAND_RESERVE_WIDTH, type BarColumnConfig, type BarTableCell, type BinParams, type BinTransform, type Breakpoint, CATEGORICAL_PALETTE, CHART_ENCODING_RULES, CHART_TYPES, type CalculateExpression, type CalculateTransform, type CategoricalPalette, type CategoryColorsConfig, type CategoryTableCell, type CellStyle, type ChannelRule, type ChartBuilderOptions, type ChartEventHandlers, type ChartLayout, type ChartSpec, type ChartSpecOverride, type ChartSpecWithoutData, type ChartType, type Chrome, type ChromeDefaults, type ChromeKey, type ChromeMode, type ChromeText, type ChromeTextStyle, type ColorBlindnessType, type ColumnConfig, type CompileOptions, type CompileTableOptions, type Condition, type ConditionalValueDef, DEFAULT_THEME, DIVERGING_PALETTES, type DarkMode, type DataRow, type DateGranularity, type DivergingPalette, EXTENDED_OFFSET_STRATEGIES, type ElementEdit, type Encoding, type EncodingChannel, type EncodingRule, type FieldPredicate, type FieldRef, type FieldType, type FilterPredicate, type FilterTransform, type FlagTableCell, GRAPH_ENCODING_RULES, type GraphChannelRule, type GraphEdge, type GraphEdgeLayout, type GraphEncoding, type GraphEncodingChannel, type GraphLayout, type GraphLayoutConfig, type GraphNode, type GraphNodeLayout, type GraphSpec, type GraphSpecWithoutData, type Gridline, type HeatmapColumnConfig, type HeatmapTableCell, type HeightClass, type ImageColumnConfig, type ImageTableCell, type LabelCandidate, type LabelConfig, type LabelDensity, type LabelMode, type LabelPriority, type LayerSpec, type LayoutStrategy, type LegendConfig, type LegendEntry, type LegendLayout, type LegendPosition, type LineMark, type LogicalAnd, type LogicalNot, type LogicalOr, MARK_DISPLAY_NAMES, MARK_ENCODING_RULES, MARK_TYPES, type Margins, type Mark, type MarkAria, type MarkDef, type MarkEvent, type MarkType, type MeasureTextFn, type NodeOverride, OFFSET_STRATEGIES, type OffsetStrategy, type PaginationState, type Point, type PointMark, type RangeAnnotation, type Rect, type RectMark, type RefLineAnnotation, type ResolveConfig, type ResolveMode, type ResolvedAnnotation, type ResolvedChrome, type ResolvedChromeElement, type ResolvedColumn, type ResolvedLabel, type ResolvedTheme, type RuleMarkLayout, SEQUENTIAL_PALETTES, type ScaleConfig, type ScaleType, type SequentialPalette, type SeriesStyle, type SortState, type SparklineColumnConfig, type SparklineData, type SparklineTableCell, type StoredVizSpec, type TableBuilderOptions, type TableCell, type TableCellBase, type TableLayout, type TableRow, type TableSpec, type TableSpecWithoutData, type TextAnnotation, type TextMarkLayout, type TextStyle, type TextTableCell, type Theme, type ThemeChromeDefaults, type ThemeColors, type ThemeConfig, type ThemeFontSizes, type ThemeFontWeights, type ThemeFonts, type ThemeSpacing, type TickMarkLayout, type TimeUnit, type TimeUnitTransform, type TooltipContent, type TooltipField, type Transform, type VizSpec, abbreviateNumber, adaptColorForDarkMode, adaptTheme, areaChart, barChart, buildD3Formatter, buildTemporalFormatter, checkPaletteDistinguishability, columnChart, computeChrome, computeLabelBounds, contrastRatio, dataTable, detectCollision, donutChart, dotChart, estimateTextWidth, findAccessibleColor, formatDate, formatNumber, generateAltText, generateAriaLabels, generateDataTable, getBreakpoint, getHeightClass, getLayoutStrategy, inferFieldType, isChartSpec, isConditionalDef, isEncodingChannel, isGraphSpec, isLayerSpec, isRangeAnnotation, isRefLineAnnotation, isTableSpec, isTextAnnotation, lineChart, meetsAA, pieChart, resolveCollisions, resolveMarkDef, resolveMarkType, resolveTheme, scatterChart, simulateColorBlindness };
package/dist/index.js CHANGED
@@ -44,8 +44,8 @@ var MARK_ENCODING_RULES = {
44
44
  detail: optional("nominal")
45
45
  },
46
46
  point: {
47
- x: required("quantitative"),
48
- y: required("quantitative"),
47
+ x: required("quantitative", "temporal", "nominal", "ordinal"),
48
+ y: required("quantitative", "temporal", "nominal", "ordinal"),
49
49
  color: optional("nominal", "ordinal", "quantitative"),
50
50
  size: optional("quantitative"),
51
51
  shape: optional("nominal", "ordinal"),
@@ -66,6 +66,17 @@ var MARK_ENCODING_RULES = {
66
66
  order: optional("quantitative", "ordinal"),
67
67
  detail: optional("nominal")
68
68
  },
69
+ lollipop: {
70
+ x: required("quantitative"),
71
+ y: required("nominal", "ordinal"),
72
+ color: optional("nominal", "ordinal", "quantitative"),
73
+ size: optional("quantitative"),
74
+ opacity: optional("quantitative"),
75
+ tooltip: optional(),
76
+ href: optional(),
77
+ order: optional("quantitative", "ordinal"),
78
+ detail: optional("nominal")
79
+ },
69
80
  arc: {
70
81
  x: optional(),
71
82
  y: required("quantitative"),
@@ -155,7 +166,8 @@ var MARK_TYPES = /* @__PURE__ */ new Set([
155
166
  "text",
156
167
  "rule",
157
168
  "tick",
158
- "rect"
169
+ "rect",
170
+ "lollipop"
159
171
  ]);
160
172
  var CHART_TYPES = MARK_TYPES;
161
173
  function resolveMarkType(mark) {
@@ -196,7 +208,8 @@ var MARK_DISPLAY_NAMES = {
196
208
  text: "Text chart",
197
209
  rule: "Rule chart",
198
210
  tick: "Tick plot",
199
- rect: "Heatmap"
211
+ rect: "Heatmap",
212
+ lollipop: "Lollipop chart"
200
213
  };
201
214
 
202
215
  // ../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/define.js
@@ -1293,7 +1306,22 @@ var OFFSET_STRATEGIES = [
1293
1306
  { dx: -1.1, dy: -1.2 }
1294
1307
  // upper-left
1295
1308
  ];
1296
- function resolveCollisions(labels) {
1309
+ var EXTENDED_OFFSET_STRATEGIES = [
1310
+ ...OFFSET_STRATEGIES,
1311
+ { dx: 0, dy: -2.4 },
1312
+ // further above
1313
+ { dx: 0, dy: 2.4 },
1314
+ // further below
1315
+ { dx: 0, dy: -3.6 },
1316
+ // even further above
1317
+ { dx: 0, dy: 3.6 },
1318
+ // even further below
1319
+ { dx: 1.1, dy: -2.4 },
1320
+ // upper-right far
1321
+ { dx: 1.1, dy: 2.4 }
1322
+ // lower-right far
1323
+ ];
1324
+ function resolveCollisions(labels, strategies = OFFSET_STRATEGIES) {
1297
1325
  const sorted = [...labels].sort(
1298
1326
  (a, b) => PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]
1299
1327
  );
@@ -1303,7 +1331,7 @@ function resolveCollisions(labels) {
1303
1331
  let bestRect = null;
1304
1332
  let bestX = label.anchorX;
1305
1333
  let bestY = label.anchorY;
1306
- for (const offset of OFFSET_STRATEGIES) {
1334
+ for (const offset of strategies) {
1307
1335
  const candidateX = label.anchorX + offset.dx * label.width;
1308
1336
  const candidateY = label.anchorY + offset.dy * label.height;
1309
1337
  const candidateRect = {
@@ -2403,16 +2431,16 @@ var GRANULARITY_FORMATS = {
2403
2431
  hour: "%b %d %H:%M",
2404
2432
  minute: "%H:%M"
2405
2433
  };
2406
- function formatDate(value, _locale, granularity) {
2434
+ function formatDate(value, _locale, granularity, useUtc = true) {
2407
2435
  const date = value instanceof Date ? value : new Date(value);
2408
2436
  if (Number.isNaN(date.getTime())) return String(value);
2409
- const gran = granularity ?? inferGranularity(date);
2437
+ const gran = granularity ?? inferGranularity(date, useUtc);
2410
2438
  if (gran === "quarter") {
2411
- const q = Math.ceil((date.getMonth() + 1) / 3);
2439
+ const q = useUtc ? Math.ceil((date.getUTCMonth() + 1) / 3) : Math.ceil((date.getMonth() + 1) / 3);
2412
2440
  return `Q${q} ${date.getFullYear()}`;
2413
2441
  }
2414
2442
  const formatStr = GRANULARITY_FORMATS[gran];
2415
- if (["year", "month", "day"].includes(gran)) {
2443
+ if (useUtc) {
2416
2444
  return utcFormat(formatStr)(date);
2417
2445
  }
2418
2446
  return timeFormat(formatStr)(date);
@@ -2426,12 +2454,16 @@ function buildTemporalFormatter(formatStr) {
2426
2454
  return fmt(date);
2427
2455
  };
2428
2456
  }
2429
- function inferGranularity(date) {
2430
- if (date.getUTCHours() !== 0 || date.getUTCMinutes() !== 0) {
2431
- return date.getUTCMinutes() !== 0 ? "minute" : "hour";
2457
+ function inferGranularity(date, useUtc = true) {
2458
+ const hours = useUtc ? date.getUTCHours() : date.getHours();
2459
+ const minutes = useUtc ? date.getUTCMinutes() : date.getMinutes();
2460
+ const day = useUtc ? date.getUTCDate() : date.getDate();
2461
+ const month = useUtc ? date.getUTCMonth() : date.getMonth();
2462
+ if (hours !== 0 || minutes !== 0) {
2463
+ return minutes !== 0 ? "minute" : "hour";
2432
2464
  }
2433
- if (date.getUTCDate() !== 1) return "day";
2434
- if (date.getUTCMonth() !== 0) return "month";
2465
+ if (day !== 1) return "day";
2466
+ if (month !== 0) return "month";
2435
2467
  return "year";
2436
2468
  }
2437
2469
 
@@ -2694,10 +2726,12 @@ export {
2694
2726
  CHART_TYPES,
2695
2727
  DEFAULT_THEME,
2696
2728
  DIVERGING_PALETTES,
2729
+ EXTENDED_OFFSET_STRATEGIES,
2697
2730
  GRAPH_ENCODING_RULES,
2698
2731
  MARK_DISPLAY_NAMES,
2699
2732
  MARK_ENCODING_RULES,
2700
2733
  MARK_TYPES,
2734
+ OFFSET_STRATEGIES,
2701
2735
  SEQUENTIAL_PALETTES,
2702
2736
  abbreviateNumber,
2703
2737
  adaptColorForDarkMode,