@opendata-ai/openchart-engine 6.11.0 → 6.12.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
@@ -101,6 +101,8 @@ interface GraphCompilation {
101
101
  };
102
102
  /** Force simulation configuration. */
103
103
  simulationConfig: SimulationConfig;
104
+ /** Whether to show the brand watermark. */
105
+ watermark: boolean;
104
106
  }
105
107
 
106
108
  /**
@@ -212,6 +214,8 @@ interface NormalizedChartSpec {
212
214
  responsive: boolean;
213
215
  theme: ThemeConfig;
214
216
  darkMode: DarkMode;
217
+ /** Whether the tryOpenData.ai watermark is enabled. */
218
+ watermark: boolean;
215
219
  /** Series names to hide from rendering. */
216
220
  hiddenSeries: string[];
217
221
  /** Per-series visual style overrides. */
@@ -226,6 +230,7 @@ interface NormalizedTableSpec {
226
230
  chrome: NormalizedChrome;
227
231
  theme: ThemeConfig;
228
232
  darkMode: DarkMode;
233
+ watermark: boolean;
229
234
  search: boolean;
230
235
  pagination: boolean | {
231
236
  pageSize: number;
@@ -247,6 +252,7 @@ interface NormalizedGraphSpec {
247
252
  annotations: Annotation[];
248
253
  theme: ThemeConfig;
249
254
  darkMode: DarkMode;
255
+ watermark: boolean;
250
256
  }
251
257
  /** Discriminated union of all normalized spec types. */
252
258
  type NormalizedSpec = NormalizedChartSpec | NormalizedTableSpec | NormalizedGraphSpec | NormalizedSankeySpec;
@@ -303,6 +309,7 @@ interface NormalizedSankeySpec {
303
309
  legend?: LegendConfig;
304
310
  theme: ThemeConfig;
305
311
  darkMode: DarkMode;
312
+ watermark: boolean;
306
313
  animation?: AnimationSpec;
307
314
  valueFormat?: string;
308
315
  linkOpacity?: number;
package/dist/index.js CHANGED
@@ -6244,7 +6244,8 @@ function normalizeChartSpec(spec, warnings) {
6244
6244
  theme: spec.theme ?? {},
6245
6245
  darkMode: spec.darkMode ?? "off",
6246
6246
  hiddenSeries: spec.hiddenSeries ?? [],
6247
- seriesStyles: spec.seriesStyles ?? {}
6247
+ seriesStyles: spec.seriesStyles ?? {},
6248
+ watermark: spec.watermark ?? true
6248
6249
  };
6249
6250
  }
6250
6251
  function normalizeTableSpec(spec, _warnings) {
@@ -6261,7 +6262,8 @@ function normalizeTableSpec(spec, _warnings) {
6261
6262
  stickyFirstColumn: spec.stickyFirstColumn ?? false,
6262
6263
  compact: spec.compact ?? false,
6263
6264
  responsive: spec.responsive ?? true,
6264
- animation: spec.animation
6265
+ animation: spec.animation,
6266
+ watermark: spec.watermark ?? true
6265
6267
  };
6266
6268
  }
6267
6269
  function normalizeSankeySpec(spec, _warnings) {
@@ -6281,7 +6283,8 @@ function normalizeSankeySpec(spec, _warnings) {
6281
6283
  darkMode: spec.darkMode ?? "off",
6282
6284
  animation: spec.animation,
6283
6285
  valueFormat: spec.valueFormat,
6284
- linkOpacity: spec.linkOpacity
6286
+ linkOpacity: spec.linkOpacity,
6287
+ watermark: spec.watermark ?? true
6285
6288
  };
6286
6289
  }
6287
6290
  function normalizeGraphSpec(spec, _warnings) {
@@ -6304,7 +6307,8 @@ function normalizeGraphSpec(spec, _warnings) {
6304
6307
  chrome: normalizeChrome(spec.chrome),
6305
6308
  annotations: normalizeAnnotations(spec.annotations),
6306
6309
  theme: spec.theme ?? {},
6307
- darkMode: spec.darkMode ?? "off"
6310
+ darkMode: spec.darkMode ?? "off",
6311
+ watermark: spec.watermark ?? true
6308
6312
  };
6309
6313
  }
6310
6314
  function normalizeSpec(spec, warnings = []) {
@@ -6331,14 +6335,23 @@ function normalizeSpec(spec, warnings = []) {
6331
6335
  `Unknown spec shape. Expected mark (chart), layer, type: 'table', type: 'graph', or type: 'sankey'.`
6332
6336
  );
6333
6337
  }
6334
- function flattenLayers(spec, parentData, parentEncoding, parentTransforms) {
6338
+ function flattenLayers(spec, parentData, parentEncoding, parentTransforms, parentWatermark) {
6335
6339
  const resolvedData = spec.data ?? parentData;
6336
6340
  const resolvedEncoding = parentEncoding && spec.encoding ? { ...parentEncoding, ...spec.encoding } : spec.encoding ?? parentEncoding;
6337
6341
  const resolvedTransforms = [...parentTransforms ?? [], ...spec.transform ?? []];
6342
+ const resolvedWatermark = spec.watermark ?? parentWatermark;
6338
6343
  const leaves = [];
6339
6344
  for (const child of spec.layer) {
6340
6345
  if (isLayerSpec(child)) {
6341
- leaves.push(...flattenLayers(child, resolvedData, resolvedEncoding, resolvedTransforms));
6346
+ leaves.push(
6347
+ ...flattenLayers(
6348
+ child,
6349
+ resolvedData,
6350
+ resolvedEncoding,
6351
+ resolvedTransforms,
6352
+ resolvedWatermark
6353
+ )
6354
+ );
6342
6355
  } else {
6343
6356
  const mergedData = child.data ?? resolvedData ?? [];
6344
6357
  const mergedEncoding = resolvedEncoding ? { ...resolvedEncoding, ...child.encoding } : child.encoding;
@@ -6347,7 +6360,9 @@ function flattenLayers(spec, parentData, parentEncoding, parentTransforms) {
6347
6360
  ...child,
6348
6361
  data: mergedData,
6349
6362
  encoding: mergedEncoding,
6350
- transform: mergedTransforms.length > 0 ? mergedTransforms : void 0
6363
+ transform: mergedTransforms.length > 0 ? mergedTransforms : void 0,
6364
+ // Inherit parent watermark if child doesn't explicitly set one
6365
+ ...child.watermark === void 0 && resolvedWatermark !== void 0 ? { watermark: resolvedWatermark } : {}
6351
6366
  });
6352
6367
  }
6353
6368
  }
@@ -7406,6 +7421,8 @@ function compileGraph(spec, options) {
7406
7421
  );
7407
7422
  }
7408
7423
  const graphSpec = normalized;
7424
+ const rawWatermark = spec.watermark;
7425
+ const watermark = rawWatermark !== void 0 ? graphSpec.watermark : options.watermark ?? true;
7409
7426
  const mergedThemeConfig = options.theme ? { ...graphSpec.theme, ...options.theme } : graphSpec.theme;
7410
7427
  let theme = resolveTheme(mergedThemeConfig);
7411
7428
  if (options.darkMode) {
@@ -7473,7 +7490,10 @@ function compileGraph(spec, options) {
7473
7490
  },
7474
7491
  theme,
7475
7492
  options.width,
7476
- options.measureText
7493
+ options.measureText,
7494
+ "full",
7495
+ void 0,
7496
+ watermark
7477
7497
  );
7478
7498
  return {
7479
7499
  nodes: compiledNodes,
@@ -7487,7 +7507,8 @@ function compileGraph(spec, options) {
7487
7507
  width: options.width,
7488
7508
  height: options.height
7489
7509
  },
7490
- simulationConfig
7510
+ simulationConfig,
7511
+ watermark
7491
7512
  };
7492
7513
  }
7493
7514
  var DEFAULT_COLLISION_PADDING = 5;
@@ -7786,7 +7807,7 @@ function scalePadding(basePadding, width, height) {
7786
7807
  }
7787
7808
  var MIN_CHART_WIDTH = 60;
7788
7809
  var MIN_CHART_HEIGHT = 40;
7789
- function computeDimensions(spec, options, legendLayout, theme, strategy) {
7810
+ function computeDimensions(spec, options, legendLayout, theme, strategy, watermark = true) {
7790
7811
  const { width, height } = options;
7791
7812
  const padding = scalePadding(theme.spacing.padding, width, height);
7792
7813
  const axisMargin = theme.spacing.axisMargin;
@@ -7797,7 +7818,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy) {
7797
7818
  width,
7798
7819
  options.measureText,
7799
7820
  chromeMode,
7800
- padding
7821
+ padding,
7822
+ watermark
7801
7823
  );
7802
7824
  const total = { x: 0, y: 0, width, height };
7803
7825
  const isRadial = spec.markType === "arc";
@@ -7955,7 +7977,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy) {
7955
7977
  width,
7956
7978
  options.measureText,
7957
7979
  fallbackMode,
7958
- padding
7980
+ padding,
7981
+ watermark
7959
7982
  );
7960
7983
  const fallbackTopAxisGap = isRadial && fallbackChrome.topHeight === 0 ? 0 : axisMargin;
7961
7984
  const newTop = padding + fallbackChrome.topHeight + fallbackTopAxisGap;
@@ -8441,7 +8464,7 @@ function truncateEntries(entries, maxCount) {
8441
8464
  });
8442
8465
  return truncated;
8443
8466
  }
8444
- function computeLegend(spec, strategy, theme, chartArea) {
8467
+ function computeLegend(spec, strategy, theme, chartArea, watermark = true) {
8445
8468
  if (spec.legend?.show === false || strategy.legendMaxHeight === 0) {
8446
8469
  return {
8447
8470
  position: "top",
@@ -8518,7 +8541,7 @@ function computeLegend(spec, strategy, theme, chartArea) {
8518
8541
  entryGap: 4
8519
8542
  };
8520
8543
  }
8521
- const availableWidth = chartArea.width - LEGEND_PADDING * 2 - BRAND_RESERVE_WIDTH;
8544
+ const availableWidth = chartArea.width - LEGEND_PADDING * 2 - (watermark ? BRAND_RESERVE_WIDTH : 0);
8522
8545
  if (spec.legend?.symbolLimit != null) {
8523
8546
  const limit = Math.max(1, spec.legend.symbolLimit);
8524
8547
  if (limit < entries.length) {
@@ -9137,6 +9160,8 @@ function compileSankey(spec, options) {
9137
9160
  );
9138
9161
  }
9139
9162
  const sankeySpec = normalized;
9163
+ const rawWatermark = spec.watermark;
9164
+ const watermark = rawWatermark !== void 0 ? sankeySpec.watermark : options.watermark ?? true;
9140
9165
  const mergedThemeConfig = options.theme ? { ...sankeySpec.theme, ...options.theme } : sankeySpec.theme;
9141
9166
  const lightTheme = resolveTheme2(mergedThemeConfig);
9142
9167
  let theme = lightTheme;
@@ -9157,7 +9182,10 @@ function compileSankey(spec, options) {
9157
9182
  },
9158
9183
  theme,
9159
9184
  options.width,
9160
- options.measureText
9185
+ options.measureText,
9186
+ "full",
9187
+ void 0,
9188
+ watermark
9161
9189
  );
9162
9190
  const padding = theme.spacing.padding;
9163
9191
  const fullArea = {
@@ -9167,7 +9195,7 @@ function compileSankey(spec, options) {
9167
9195
  height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
9168
9196
  };
9169
9197
  if (fullArea.width <= 0 || fullArea.height <= 0) {
9170
- return emptyLayout(fullArea, chrome, theme, options);
9198
+ return emptyLayout(fullArea, chrome, theme, options, watermark);
9171
9199
  }
9172
9200
  const sourceField = sankeySpec.encoding.source.field;
9173
9201
  const targetField = sankeySpec.encoding.target.field;
@@ -9203,7 +9231,7 @@ function compileSankey(spec, options) {
9203
9231
  height: fullArea.height - legend.bounds.height - legendGap
9204
9232
  };
9205
9233
  if (area.height <= 0) {
9206
- return emptyLayout(area, chrome, theme, options);
9234
+ return emptyLayout(area, chrome, theme, options, watermark);
9207
9235
  }
9208
9236
  const labelFontSize = theme.fonts.sizes.small;
9209
9237
  const labelFontWeight = theme.fonts.weights.normal;
@@ -9347,7 +9375,8 @@ function compileSankey(spec, options) {
9347
9375
  width: options.width,
9348
9376
  height: options.height
9349
9377
  },
9350
- animation: resolvedAnimation
9378
+ animation: resolvedAnimation,
9379
+ watermark
9351
9380
  };
9352
9381
  }
9353
9382
  function buildSankeyLegend(nodeColorMap, colorField, data, sourceField, targetField, theme, area) {
@@ -9454,7 +9483,7 @@ function buildTooltipDescriptors(nodes, links, valueFormat) {
9454
9483
  }
9455
9484
  return descriptors;
9456
9485
  }
9457
- function emptyLayout(area, chrome, theme, options) {
9486
+ function emptyLayout(area, chrome, theme, options, watermark) {
9458
9487
  return {
9459
9488
  area,
9460
9489
  chrome,
@@ -9486,7 +9515,8 @@ function emptyLayout(area, chrome, theme, options) {
9486
9515
  dimensions: {
9487
9516
  width: options.width,
9488
9517
  height: options.height
9489
- }
9518
+ },
9519
+ watermark
9490
9520
  };
9491
9521
  }
9492
9522
 
@@ -10086,6 +10116,7 @@ function compileTableLayout(spec, options, theme) {
10086
10116
  });
10087
10117
  return { id: rowId, cells, data: row };
10088
10118
  });
10119
+ const watermark = spec.watermark;
10089
10120
  const chrome = computeChrome4(
10090
10121
  {
10091
10122
  title: spec.chrome.title,
@@ -10096,7 +10127,10 @@ function compileTableLayout(spec, options, theme) {
10096
10127
  },
10097
10128
  theme,
10098
10129
  options.width,
10099
- options.measureText
10130
+ options.measureText,
10131
+ "full",
10132
+ void 0,
10133
+ watermark
10100
10134
  );
10101
10135
  const titleText = spec.chrome.title?.text ?? "";
10102
10136
  const caption = titleText ? `Table: ${titleText}` : `Data table with ${data.length} rows`;
@@ -10118,7 +10152,8 @@ function compileTableLayout(spec, options, theme) {
10118
10152
  summary: `${resolvedColumns.length} columns, ${totalFiltered} rows`
10119
10153
  },
10120
10154
  theme,
10121
- animation: resolveAnimation(spec.animation)
10155
+ animation: resolveAnimation(spec.animation),
10156
+ watermark
10122
10157
  };
10123
10158
  }
10124
10159
 
@@ -10564,6 +10599,8 @@ function compileChart(spec, options) {
10564
10599
  throw new Error("compileChart received a sankey spec. Use compileSankey instead.");
10565
10600
  }
10566
10601
  let chartSpec = normalized;
10602
+ const rawWatermark = spec.watermark;
10603
+ const watermark = rawWatermark !== void 0 ? chartSpec.watermark : options.watermark ?? true;
10567
10604
  const rawTransforms = spec.transform;
10568
10605
  if (rawTransforms && rawTransforms.length > 0) {
10569
10606
  chartSpec = { ...chartSpec, data: runTransforms(chartSpec.data, rawTransforms) };
@@ -10622,8 +10659,8 @@ function compileChart(spec, options) {
10622
10659
  width: options.width,
10623
10660
  height: options.height
10624
10661
  };
10625
- const legendLayout = computeLegend(chartSpec, strategy, theme, preliminaryArea);
10626
- const dims = computeDimensions(chartSpec, options, legendLayout, theme, strategy);
10662
+ const legendLayout = computeLegend(chartSpec, strategy, theme, preliminaryArea, watermark);
10663
+ const dims = computeDimensions(chartSpec, options, legendLayout, theme, strategy, watermark);
10627
10664
  const chartArea = dims.chartArea;
10628
10665
  const legendArea = { ...chartArea };
10629
10666
  if (legendLayout.entries.length > 0) {
@@ -10641,7 +10678,7 @@ function compileChart(spec, options) {
10641
10678
  break;
10642
10679
  }
10643
10680
  }
10644
- const finalLegend = computeLegend(chartSpec, strategy, theme, legendArea);
10681
+ const finalLegend = computeLegend(chartSpec, strategy, theme, legendArea, watermark);
10645
10682
  let renderData = chartSpec.data;
10646
10683
  if (chartSpec.hiddenSeries.length > 0 && chartSpec.encoding.color && "field" in chartSpec.encoding.color) {
10647
10684
  const colorField = chartSpec.encoding.color.field;
@@ -10708,12 +10745,14 @@ function compileChart(spec, options) {
10708
10745
  obstacles.push(computeLabelBounds(mark.label));
10709
10746
  }
10710
10747
  }
10711
- const brandPadding = theme.spacing.padding;
10712
- const brandX = dims.total.width - brandPadding - BRAND_RESERVE_WIDTH2;
10713
- const xAxisExtent = axes.x?.label ? 48 : axes.x ? 26 : 0;
10714
- const firstBottomChrome = dims.chrome.source ?? dims.chrome.byline ?? dims.chrome.footer;
10715
- const brandY = firstBottomChrome ? chartArea.y + chartArea.height + xAxisExtent + firstBottomChrome.y : chartArea.y + chartArea.height + xAxisExtent + theme.spacing.chartToFooter;
10716
- obstacles.push({ x: brandX, y: brandY, width: BRAND_RESERVE_WIDTH2, height: 30 });
10748
+ if (watermark) {
10749
+ const brandPadding = theme.spacing.padding;
10750
+ const brandX = dims.total.width - brandPadding - BRAND_RESERVE_WIDTH2;
10751
+ const xAxisExtent = axes.x?.label ? 48 : axes.x ? 26 : 0;
10752
+ const firstBottomChrome = dims.chrome.source ?? dims.chrome.byline ?? dims.chrome.footer;
10753
+ const brandY = firstBottomChrome ? chartArea.y + chartArea.height + xAxisExtent + firstBottomChrome.y : chartArea.y + chartArea.height + xAxisExtent + theme.spacing.chartToFooter;
10754
+ obstacles.push({ x: brandX, y: brandY, width: BRAND_RESERVE_WIDTH2, height: 30 });
10755
+ }
10717
10756
  const annotations = computeAnnotations(
10718
10757
  chartSpec,
10719
10758
  scales,
@@ -10794,7 +10833,8 @@ function compileChart(spec, options) {
10794
10833
  width: options.width,
10795
10834
  height: options.height
10796
10835
  },
10797
- animation: resolvedAnimation
10836
+ animation: resolvedAnimation,
10837
+ watermark
10798
10838
  };
10799
10839
  }
10800
10840
  function getMarkPrimaryValue(mark) {
@@ -10864,6 +10904,7 @@ function buildPrimarySpec(leaves, layerSpec) {
10864
10904
  responsive: layerSpec.responsive ?? leaves[0].responsive,
10865
10905
  theme: layerSpec.theme ?? leaves[0].theme,
10866
10906
  darkMode: layerSpec.darkMode ?? leaves[0].darkMode,
10907
+ watermark: layerSpec.watermark ?? leaves[0].watermark,
10867
10908
  hiddenSeries: layerSpec.hiddenSeries ?? leaves[0].hiddenSeries
10868
10909
  };
10869
10910
  return primary;
@@ -10880,7 +10921,9 @@ function compileTable(spec, options) {
10880
10921
  if (options.darkMode) {
10881
10922
  theme = adaptTheme3(theme);
10882
10923
  }
10883
- return compileTableLayout(tableSpec, options, theme);
10924
+ const rawWatermark = spec.watermark;
10925
+ const watermark = rawWatermark !== void 0 ? tableSpec.watermark : options.watermark ?? true;
10926
+ return compileTableLayout({ ...tableSpec, watermark }, options, theme);
10884
10927
  }
10885
10928
  function compileGraph2(spec, options) {
10886
10929
  return compileGraph(spec, options);