@rowsncolumns/charts 28.1.16 → 28.1.17

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":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAkEA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAuTrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAiGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBAsvHjB,CAAC"}
1
+ {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAkEA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAwTrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAiGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBAmvHjB,CAAC"}
@@ -33,6 +33,7 @@ var histogram_1 = require("../utils/histogram");
33
33
  var legend_layout_1 = require("../utils/legend-layout");
34
34
  var of_pie_1 = require("../utils/of-pie");
35
35
  var overrides_1 = require("../utils/overrides");
36
+ var overrides_2 = require("../utils/overrides");
36
37
  var pie_explosion_1 = require("../utils/pie-explosion");
37
38
  var radar_1 = require("../utils/radar");
38
39
  var region_map_1 = require("../utils/region-map");
@@ -254,7 +255,7 @@ var defaultLegendConfig = {
254
255
  /** Category-axis title gap: clears one row of tick labels (#986). */
255
256
  var CATEGORY_AXIS_NAME_GAP = (0, legend_layout_1.categoryAxisNameGap)();
256
257
  var BasicChart = function (_a) {
257
- var _b;
258
+ var _b, _c, _d;
258
259
  var width = _a.width, height = _a.height, chart = _a.chart, theme = _a.theme, isDarkMode = _a.isDarkMode, sheetId = _a.sheetId, readonly = _a.readonly, getDomainValuesFromRange = _a.getDomainValuesFromRange, getSeriesValuesFromRange = _a.getSeriesValuesFromRange, getFormattingFromRange = _a.getFormattingFromRange, onDeleteChart = _a.onDeleteChart, onUpdateChart = _a.onUpdateChart, onRequestEdit = _a.onRequestEdit, onRequestCalculate = _a.onRequestCalculate, isSelected = _a.isSelected, fieldButtons = _a.fieldButtons, locale = _a.locale;
259
260
  var spec = chart.spec;
260
261
  var explicitChartTitle = (_b = chart.spec.title) !== null && _b !== void 0 ? _b : undefined;
@@ -310,7 +311,7 @@ var BasicChart = function (_a) {
310
311
  // the chart upgrades from the immediate 2-D fallback to true 3-D.
311
312
  var renderedIn3D = (0, react_1.useRef)(false);
312
313
  var glUpgradeRequested = (0, react_1.useRef)(false);
313
- var _c = tslib_1.__read((0, react_1.useState)(0), 2), glUpgradeTick = _c[0], setGlUpgradeTick = _c[1];
314
+ var _e = tslib_1.__read((0, react_1.useState)(0), 2), glUpgradeTick = _e[0], setGlUpgradeTick = _e[1];
314
315
  // Region-map (choropleth) pipeline state. The map option (geo +
315
316
  // visualMap) doesn't merge back into a cartesian one, so the instance
316
317
  // is re-initialized when entering/leaving the region-map rendering.
@@ -1766,7 +1767,7 @@ var BasicChart = function (_a) {
1766
1767
  return (0, utils_1.chartPaletteColorAt)(seriesPalette, index);
1767
1768
  };
1768
1769
  _loop_1 = function (specSeriesIndex, series) {
1769
- var dataLabel, _189, _190, _191, effectiveChartType, lineLike, domainSources, pieDomainLabels, piePointOffset, data, seriesEchartsType, seriesStyleAttrs, seriesEntry, isBarOrColumn, seriesAny, markerSymbol, wantsMarkers, labelsWithoutMarkers, isolated, marked, isolated_1, isolated_1_1, i, gradientArgs, gradient, overrides_2, _192, _193, dp, fallback_1, overrides_3, _194, _195, dp, positiveColor_1, negativeColor_1;
1770
+ var dataLabel, _189, _190, _191, effectiveChartType, lineLike, domainSources, pieDomainLabels, piePointOffset, data, seriesEchartsType, seriesStyleAttrs, seriesEntry, isBarOrColumn, seriesAny, markerSymbol, wantsMarkers, labelsWithoutMarkers, isolated, marked, isolated_1, isolated_1_1, i, gradientArgs, gradient, overrides_3, _192, _193, dp, fallback_1, overrides_4, _194, _195, dp, positiveColor_1, negativeColor_1;
1770
1771
  var e_12, _196, e_13, _197, e_14, _198;
1771
1772
  return tslib_1.__generator(this, function (_199) {
1772
1773
  switch (_199.label) {
@@ -1912,12 +1913,12 @@ var BasicChart = function (_a) {
1912
1913
  else if (isBarOrColumn &&
1913
1914
  Array.isArray(seriesAny.dataPointColors) &&
1914
1915
  seriesAny.dataPointColors.length) {
1915
- overrides_2 = new Map();
1916
+ overrides_3 = new Map();
1916
1917
  try {
1917
1918
  for (_192 = (e_13 = void 0, tslib_1.__values(seriesAny.dataPointColors)), _193 = _192.next(); !_193.done; _193 = _192.next()) {
1918
1919
  dp = _193.value;
1919
1920
  if (typeof dp.idx === "number" && typeof dp.color === "string") {
1920
- overrides_2.set(dp.idx, dp.color);
1921
+ overrides_3.set(dp.idx, dp.color);
1921
1922
  }
1922
1923
  }
1923
1924
  }
@@ -1929,17 +1930,17 @@ var BasicChart = function (_a) {
1929
1930
  finally { if (e_13) throw e_13.error; }
1930
1931
  }
1931
1932
  fallback_1 = (_119 = series.color) !== null && _119 !== void 0 ? _119 : paletteColorAt(specSeriesIndex);
1932
- seriesEntry.itemStyle = tslib_1.__assign(tslib_1.__assign({}, ((_120 = seriesEntry.itemStyle) !== null && _120 !== void 0 ? _120 : {})), { color: function (params) { var _a; return (_a = overrides_2.get(params.dataIndex)) !== null && _a !== void 0 ? _a : fallback_1; } });
1933
+ seriesEntry.itemStyle = tslib_1.__assign(tslib_1.__assign({}, ((_120 = seriesEntry.itemStyle) !== null && _120 !== void 0 ? _120 : {})), { color: function (params) { var _a; return (_a = overrides_3.get(params.dataIndex)) !== null && _a !== void 0 ? _a : fallback_1; } });
1933
1934
  }
1934
1935
  else if (isCircularChart &&
1935
1936
  Array.isArray(seriesAny.dataPointColors) &&
1936
1937
  seriesAny.dataPointColors.length) {
1937
- overrides_3 = new Map();
1938
+ overrides_4 = new Map();
1938
1939
  try {
1939
1940
  for (_194 = (e_14 = void 0, tslib_1.__values(seriesAny.dataPointColors)), _195 = _194.next(); !_195.done; _195 = _194.next()) {
1940
1941
  dp = _195.value;
1941
1942
  if (typeof dp.idx === "number" && typeof dp.color === "string") {
1942
- overrides_3.set(dp.idx, dp.color);
1943
+ overrides_4.set(dp.idx, dp.color);
1943
1944
  }
1944
1945
  }
1945
1946
  }
@@ -1952,7 +1953,7 @@ var BasicChart = function (_a) {
1952
1953
  }
1953
1954
  seriesEntry.itemStyle = tslib_1.__assign(tslib_1.__assign({}, ((_121 = seriesEntry.itemStyle) !== null && _121 !== void 0 ? _121 : {})), { color: function (params) {
1954
1955
  var _a, _b;
1955
- return (_b = (_a = overrides_3.get(params.dataIndex)) !== null && _a !== void 0 ? _a : series.color) !== null && _b !== void 0 ? _b : paletteColorAt(params.dataIndex);
1956
+ return (_b = (_a = overrides_4.get(params.dataIndex)) !== null && _a !== void 0 ? _a : series.color) !== null && _b !== void 0 ? _b : paletteColorAt(params.dataIndex);
1956
1957
  } });
1957
1958
  }
1958
1959
  else if (isBarOrColumn && series.invertIfNegative) {
@@ -3002,7 +3003,7 @@ var BasicChart = function (_a) {
3002
3003
  // between the cartesian 2-D option and the grid3D / map one and must
3003
3004
  // re-apply these.
3004
3005
  var applyThemeOptions = function () {
3005
- var _a, _b, _c, _d, _e, _f;
3006
+ var _a, _b, _c, _d;
3006
3007
  if (chartRef.current) {
3007
3008
  var textColor = (0, spreadsheet_1.getStringifiedColor)({
3008
3009
  theme: 1,
@@ -3020,21 +3021,23 @@ var BasicChart = function (_a) {
3020
3021
  var options = {
3021
3022
  title: {
3022
3023
  text: title !== null && title !== void 0 ? title : undefined,
3023
- textStyle: tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ color: (_c = authoredTitleFmt === null || authoredTitleFmt === void 0 ? void 0 : authoredTitleFmt.color) !== null && _c !== void 0 ? _c : textColor }, ((authoredTitleFmt === null || authoredTitleFmt === void 0 ? void 0 : authoredTitleFmt.fontFamily)
3024
- ? { fontFamily: authoredTitleFmt.fontFamily }
3025
- : {})), (typeof (authoredTitleFmt === null || authoredTitleFmt === void 0 ? void 0 : authoredTitleFmt.fontSize) === "number"
3026
- ? { fontSize: authoredTitleFmt.fontSize }
3027
- : {})), ((authoredTitleFmt === null || authoredTitleFmt === void 0 ? void 0 : authoredTitleFmt.bold) ? { fontWeight: "bold" } : {})), ((authoredTitleFmt === null || authoredTitleFmt === void 0 ? void 0 : authoredTitleFmt.italic) ? { fontStyle: "italic" } : {})),
3024
+ // Every key is written (echarts merges setOption calls, so a key
3025
+ // left out keeps its previous value — turning bold off used to
3026
+ // leave the title bold, rowsncolumns/spreadsheet#1105).
3027
+ textStyle: (0, overrides_2.themedTextStyle)(authoredTitleFmt, {
3028
+ color: textColor,
3029
+ fontSize: 18,
3030
+ fontWeight: "bold",
3031
+ }),
3028
3032
  },
3029
3033
  legend: {
3030
- textStyle: tslib_1.__assign(tslib_1.__assign({ color: (_d = authoredLegendFmt === null || authoredLegendFmt === void 0 ? void 0 : authoredLegendFmt.color) !== null && _d !== void 0 ? _d : textColor }, ((authoredLegendFmt === null || authoredLegendFmt === void 0 ? void 0 : authoredLegendFmt.fontFamily)
3031
- ? { fontFamily: authoredLegendFmt.fontFamily }
3032
- : {})), (typeof (authoredLegendFmt === null || authoredLegendFmt === void 0 ? void 0 : authoredLegendFmt.fontSize) === "number"
3033
- ? { fontSize: authoredLegendFmt.fontSize }
3034
- : {})),
3034
+ textStyle: (0, overrides_2.themedTextStyle)(authoredLegendFmt, {
3035
+ color: textColor,
3036
+ fontSize: 12,
3037
+ }),
3035
3038
  },
3036
3039
  axisLabel: {
3037
- color: (_e = authoredDataLabelFmt === null || authoredDataLabelFmt === void 0 ? void 0 : authoredDataLabelFmt.color) !== null && _e !== void 0 ? _e : textColor,
3040
+ color: (_c = authoredDataLabelFmt === null || authoredDataLabelFmt === void 0 ? void 0 : authoredDataLabelFmt.color) !== null && _c !== void 0 ? _c : textColor,
3038
3041
  },
3039
3042
  tooltip: {
3040
3043
  backgroundColor: bgColor,
@@ -3055,7 +3058,7 @@ var BasicChart = function (_a) {
3055
3058
  ])),
3056
3059
  // Excel's Format Chart Area fill; `transparent` (echarts' own
3057
3060
  // default) so clearing the fill undoes an earlier setOption.
3058
- backgroundColor: (_f = chart.spec.backgroundColor) !== null && _f !== void 0 ? _f : "transparent",
3061
+ backgroundColor: (_d = chart.spec.backgroundColor) !== null && _d !== void 0 ? _d : "transparent",
3059
3062
  };
3060
3063
  // Skip when rendering 3-D or a region map: merging a cartesian
3061
3064
  // yAxis into a grid3D / map option would create a stray empty
@@ -3074,7 +3077,9 @@ var BasicChart = function (_a) {
3074
3077
  chartRef.current.setOption(options);
3075
3078
  }
3076
3079
  };
3077
- // Update chart properties
3080
+ // Update chart properties — the authored text formats are inputs too, so
3081
+ // a font change applies at once instead of waiting for the next title
3082
+ // edit (rowsncolumns/spreadsheet#1105).
3078
3083
  (0, ui_1.useIsomorphicLayoutEffect)(function () {
3079
3084
  applyThemeOptions();
3080
3085
  }, [
@@ -3084,6 +3089,9 @@ var BasicChart = function (_a) {
3084
3089
  chart.spec.chartType,
3085
3090
  chart.spec.palette,
3086
3091
  chart.spec.backgroundColor,
3092
+ chart.spec.titleTextFormat,
3093
+ (_c = chart.spec.legend) === null || _c === void 0 ? void 0 : _c.textFormat,
3094
+ (_d = chart.spec.dataLabels) === null || _d === void 0 ? void 0 : _d.textFormat,
3087
3095
  ]);
3088
3096
  // Draw chart. `glUpgradeTick` re-runs the draw when the lazily loaded
3089
3097
  // echarts-gl module resolves, upgrading a 3-D spec's immediate 2-D
@@ -1,9 +1,11 @@
1
1
  import type { ChartTextFormat } from "@rowsncolumns/spreadsheet";
2
2
  import React from "react";
3
3
  /**
4
- * Font family / size / colour / bold / italic / underline / strikethrough
5
- * of one text element — the chart title, the legend, an axis or the data
6
- * labels (`ChartTextFormat`, OOXML `<c:txPr>`).
4
+ * Font family / size / colour / bold / italic of one text element — the
5
+ * chart title, the legend, an axis or the data labels (`ChartTextFormat`,
6
+ * OOXML `<c:txPr>`). `underline` / `strikethrough` stay on the spec for the
7
+ * xlsx round trip but have no control: neither renderer draws them
8
+ * (rowsncolumns/spreadsheet#1105).
7
9
  */
8
10
  export declare const TextFormatFields: ({ label, value, onChange, collapsible, ariaLabels, }: {
9
11
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"text-format-fields.d.ts","sourceRoot":"","sources":["../../../../../components/editors/fields/text-format-fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,sDAM9B;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAClD,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,sBA6EA,CAAC"}
1
+ {"version":3,"file":"text-format-fields.d.ts","sourceRoot":"","sources":["../../../../../components/editors/fields/text-format-fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,sDAM9B;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAClD,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,sBAmEA,CAAC"}
@@ -6,9 +6,11 @@ var ui_1 = require("@rowsncolumns/ui");
6
6
  var react_1 = tslib_1.__importStar(require("react"));
7
7
  var primitives_1 = require("./primitives");
8
8
  /**
9
- * Font family / size / colour / bold / italic / underline / strikethrough
10
- * of one text element — the chart title, the legend, an axis or the data
11
- * labels (`ChartTextFormat`, OOXML `<c:txPr>`).
9
+ * Font family / size / colour / bold / italic of one text element — the
10
+ * chart title, the legend, an axis or the data labels (`ChartTextFormat`,
11
+ * OOXML `<c:txPr>`). `underline` / `strikethrough` stay on the spec for the
12
+ * xlsx round trip but have no control: neither renderer draws them
13
+ * (rowsncolumns/spreadsheet#1105).
12
14
  */
13
15
  var TextFormatFields = function (_a) {
14
16
  var _b, _c, _d, _e, _f, _g;
@@ -39,8 +41,6 @@ var TextFormatFields = function (_a) {
39
41
  }, className: "text-xs w-16", placeholder: "Size", "aria-label": (_e = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.size) !== null && _e !== void 0 ? _e : "".concat(label, " size") }),
40
42
  react_1.default.createElement("input", { type: "color", value: (_f = value === null || value === void 0 ? void 0 : value.color) !== null && _f !== void 0 ? _f : "#000000", onChange: function (e) { return set({ color: e.target.value }); }, className: primitives_1.COLOR_CLASS, "aria-label": (_g = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.color) !== null && _g !== void 0 ? _g : "".concat(label, " color") }),
41
43
  react_1.default.createElement(primitives_1.CheckboxField, { label: "Bold", checked: Boolean(value === null || value === void 0 ? void 0 : value.bold), onChange: function (bold) { return set({ bold: bold }); } }),
42
- react_1.default.createElement(primitives_1.CheckboxField, { label: "Italic", checked: Boolean(value === null || value === void 0 ? void 0 : value.italic), onChange: function (italic) { return set({ italic: italic }); } }),
43
- react_1.default.createElement(primitives_1.CheckboxField, { label: "Underline", checked: Boolean(value === null || value === void 0 ? void 0 : value.underline), onChange: function (underline) { return set({ underline: underline }); } }),
44
- react_1.default.createElement(primitives_1.CheckboxField, { label: "Strikethrough", checked: Boolean(value === null || value === void 0 ? void 0 : value.strikethrough), onChange: function (strikethrough) { return set({ strikethrough: strikethrough }); } }))));
44
+ react_1.default.createElement(primitives_1.CheckboxField, { label: "Italic", checked: Boolean(value === null || value === void 0 ? void 0 : value.italic), onChange: function (italic) { return set({ italic: italic }); } }))));
45
45
  };
46
46
  exports.TextFormatFields = TextFormatFields;
@@ -1 +1 @@
1
- {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA+ZxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAmGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBA2rFjB,CAAC"}
1
+ {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAkcxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAmGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBA8rFjB,CAAC"}
@@ -209,7 +209,7 @@ var withTextMode = function (mode) {
209
209
  return base.split("+").includes("text") ? base : "".concat(base, "+text");
210
210
  };
211
211
  var applyDataLabelsToTracePlotly = function (trace, opts, chartType, sourceNumberFormat, locale) {
212
- var _a, _b, _c;
212
+ var _a, _b, _c, _d;
213
213
  if (!(opts === null || opts === void 0 ? void 0 : opts.show))
214
214
  return trace;
215
215
  var next = tslib_1.__assign({}, trace);
@@ -233,10 +233,14 @@ var applyDataLabelsToTracePlotly = function (trace, opts, chartType, sourceNumbe
233
233
  parts.push("percent");
234
234
  next.textinfo = parts.length ? parts.join("+") : "value";
235
235
  next.textposition = position;
236
+ if (opts.textFormat) {
237
+ var fmt = opts.textFormat;
238
+ next.textfont = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, ((_b = next.textfont) !== null && _b !== void 0 ? _b : {})), (fmt.fontFamily ? { family: fmt.fontFamily } : {})), (typeof fmt.fontSize === "number" && fmt.fontSize > 0 ? { size: fmt.fontSize } : {})), (fmt.color ? { color: fmt.color } : {}));
239
+ }
236
240
  // Values format like their source cells (or the authored `<c:numFmt>`):
237
241
  // plotly's own `%{value}` is a raw number, so the formatted strings
238
242
  // ride on `text` and a `texttemplate` mirrors the textinfo parts.
239
- var pattern_1 = (_b = opts.numberFormatPattern) !== null && _b !== void 0 ? _b : sourceNumberFormat;
243
+ var pattern_1 = (_c = opts.numberFormatPattern) !== null && _c !== void 0 ? _c : sourceNumberFormat;
240
244
  if (pattern_1) {
241
245
  var values = Array.isArray(next.values) ? next.values : [];
242
246
  next.text = values.map(function (v) {
@@ -255,7 +259,7 @@ var applyDataLabelsToTracePlotly = function (trace, opts, chartType, sourceNumbe
255
259
  // with the d3-format mini-language, but our patterns are
256
260
  // SpreadsheetML — easier to pre-format the strings. Without an
257
261
  // authored pattern the labels link to the source-cell format.
258
- var pattern_2 = (_c = opts.numberFormatPattern) !== null && _c !== void 0 ? _c : sourceNumberFormat;
262
+ var pattern_2 = (_d = opts.numberFormatPattern) !== null && _d !== void 0 ? _d : sourceNumberFormat;
259
263
  // Horizontal bars carry their values on `x`.
260
264
  var values = next.orientation === "h" ? next.x : next.y;
261
265
  var vals = Array.isArray(values) ? values : [];
@@ -270,6 +274,40 @@ var applyDataLabelsToTracePlotly = function (trace, opts, chartType, sourceNumbe
270
274
  if (isPoint)
271
275
  next.mode = withTextMode(next.mode);
272
276
  }
277
+ return applyDataLabelFontPlotly(next, opts.textFormat);
278
+ };
279
+ /**
280
+ * Excel's Format Data Labels → Font for a plotly trace: `textfont` carries
281
+ * family / size / colour, bold / italic are pseudo-HTML tags around each
282
+ * label (plotly fonts have no weight) — rowsncolumns/spreadsheet#1105.
283
+ */
284
+ var applyDataLabelFontPlotly = function (trace, fmt) {
285
+ var _a;
286
+ if (!fmt)
287
+ return trace;
288
+ var next = tslib_1.__assign({}, trace);
289
+ var textfont = tslib_1.__assign({}, ((_a = next.textfont) !== null && _a !== void 0 ? _a : {}));
290
+ if (fmt.fontFamily)
291
+ textfont.family = fmt.fontFamily;
292
+ if (typeof fmt.fontSize === "number" && fmt.fontSize > 0)
293
+ textfont.size = fmt.fontSize;
294
+ if (fmt.color)
295
+ textfont.color = fmt.color;
296
+ if (Object.keys(textfont).length)
297
+ next.textfont = textfont;
298
+ var wrap = function (text) {
299
+ if (text === null || text === undefined || text === "")
300
+ return text;
301
+ var out = String(text);
302
+ if (fmt.italic)
303
+ out = "<i>".concat(out, "</i>");
304
+ if (fmt.bold)
305
+ out = "<b>".concat(out, "</b>");
306
+ return out;
307
+ };
308
+ if ((fmt.bold || fmt.italic) && next.text !== undefined) {
309
+ next.text = Array.isArray(next.text) ? next.text.map(wrap) : wrap(next.text);
310
+ }
273
311
  return next;
274
312
  };
275
313
  var BUBBLE_CHART_TYPES = new Set([
@@ -662,7 +700,8 @@ var BasicChart = function (_a) {
662
700
  : undefined;
663
701
  var withLabels = function (trace) {
664
702
  return labelText
665
- ? tslib_1.__assign(tslib_1.__assign({}, trace), { mode: withTextMode(trace.mode), text: labelText, textposition: labelPosition }) : trace;
703
+ ? applyDataLabelFontPlotly(tslib_1.__assign(tslib_1.__assign({}, trace), { mode: withTextMode(trace.mode), text: labelText, textposition: labelPosition }), labelOpts === null || labelOpts === void 0 ? void 0 : labelOpts.textFormat)
704
+ : trace;
666
705
  };
667
706
  if (isScatter_1) {
668
707
  // Per-series marker.symbol = "none" → pure line (no markers).
@@ -1,4 +1,24 @@
1
1
  import type { LegendComponentOption } from "echarts";
2
+ /**
3
+ * A complete echarts `textStyle` for a text element: the authored
4
+ * `ChartTextFormat` over the theme defaults, with every key present so a
5
+ * cleared setting (bold off, size blank) resets the element instead of
6
+ * keeping the previous merged value (rowsncolumns/spreadsheet#1105).
7
+ * Underline / strikethrough have no canvas text decoration in echarts and
8
+ * are not drawn.
9
+ */
10
+ export declare const themedTextStyle: (fmt: any, defaults: {
11
+ color: string;
12
+ fontSize: number;
13
+ fontFamily?: string;
14
+ fontWeight?: "normal" | "bold";
15
+ }) => {
16
+ color: any;
17
+ fontFamily: any;
18
+ fontSize: any;
19
+ fontWeight: "bold" | "normal";
20
+ fontStyle: "italic" | "normal";
21
+ };
2
22
  /** Build an echarts `textStyle` from a parsed `ChartTextFormat`. */
3
23
  export declare const textFormatToEchartsTextStyle: (fmt: any) => Record<string, any> | undefined;
4
24
  export declare const applyLegendOverrides: (legend: LegendComponentOption, opts: any) => LegendComponentOption;
@@ -1 +1 @@
1
- {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,SAAS,MAAM,EAEf,eAAa,MACT,QAAQ,GAAG,WAoDhB,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCAlGH,GAAG;aA+GhB,CAAC"}
1
+ {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,GAAG,EACR,UAAU;IACR,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAChC;;;;gBASG,MAAM,GACN,QAAQ;eACsC,QAAQ,GAAG,QAAQ;CACrE,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,SAAS,MAAM,EAEf,eAAa,MACT,QAAQ,GAAG,WAoDhB,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCAlGH,GAAG;aAoHhB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildSeriesLabelOption = exports.resolveSeriesDataLabels = exports.dataLabelFormatter = exports.applyAxisOverrides = exports.applyLegendOverrides = exports.textFormatToEchartsTextStyle = void 0;
3
+ exports.buildSeriesLabelOption = exports.resolveSeriesDataLabels = exports.dataLabelFormatter = exports.applyAxisOverrides = exports.applyLegendOverrides = exports.textFormatToEchartsTextStyle = exports.themedTextStyle = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var axis_number_format_1 = require("./axis-number-format");
6
6
  // Map ChartSpec.legend / dataLabels / axisOptions to ECharts option
@@ -9,6 +9,27 @@ var axis_number_format_1 = require("./axis-number-format");
9
9
  // option assembly and the bubble / hierarchy / radar / stock early
10
10
  // branches in `basic-chart.tsx` so every chart type honors the same
11
11
  // spec-level overrides.
12
+ /**
13
+ * A complete echarts `textStyle` for a text element: the authored
14
+ * `ChartTextFormat` over the theme defaults, with every key present so a
15
+ * cleared setting (bold off, size blank) resets the element instead of
16
+ * keeping the previous merged value (rowsncolumns/spreadsheet#1105).
17
+ * Underline / strikethrough have no canvas text decoration in echarts and
18
+ * are not drawn.
19
+ */
20
+ var themedTextStyle = function (fmt, defaults) {
21
+ var _a, _b, _c, _d;
22
+ return ({
23
+ color: (_a = fmt === null || fmt === void 0 ? void 0 : fmt.color) !== null && _a !== void 0 ? _a : defaults.color,
24
+ fontFamily: (_c = (_b = fmt === null || fmt === void 0 ? void 0 : fmt.fontFamily) !== null && _b !== void 0 ? _b : defaults.fontFamily) !== null && _c !== void 0 ? _c : "sans-serif",
25
+ fontSize: typeof (fmt === null || fmt === void 0 ? void 0 : fmt.fontSize) === "number" && fmt.fontSize > 0
26
+ ? fmt.fontSize
27
+ : defaults.fontSize,
28
+ fontWeight: (fmt ? (fmt.bold ? "bold" : "normal") : (_d = defaults.fontWeight) !== null && _d !== void 0 ? _d : "normal"),
29
+ fontStyle: ((fmt === null || fmt === void 0 ? void 0 : fmt.italic) ? "italic" : "normal"),
30
+ });
31
+ };
32
+ exports.themedTextStyle = themedTextStyle;
12
33
  /** Build an echarts `textStyle` from a parsed `ChartTextFormat`. */
13
34
  var textFormatToEchartsTextStyle = function (fmt) {
14
35
  if (!fmt)
@@ -209,17 +230,17 @@ var POINT_SERIES_TYPES = new Set(["line", "scatter", "effectScatter"]);
209
230
  var resolveSeriesDataLabels = function (chartLevel, series) { var _a; return (_a = series === null || series === void 0 ? void 0 : series.dataLabels) !== null && _a !== void 0 ? _a : chartLevel; };
210
231
  exports.resolveSeriesDataLabels = resolveSeriesDataLabels;
211
232
  var buildSeriesLabelOption = function (opts, seriesType, locale) {
212
- var _a;
233
+ var _a, _b;
213
234
  if (!(opts === null || opts === void 0 ? void 0 : opts.show))
214
235
  return undefined;
215
236
  var positions = seriesType && POINT_SERIES_TYPES.has(seriesType)
216
237
  ? ECHARTS_POINT_DLBL_POS
217
238
  : ECHARTS_DLBL_POS;
218
239
  var position = (_a = (opts.position && positions[opts.position])) !== null && _a !== void 0 ? _a : "top";
219
- return {
220
- show: true,
221
- position: position,
222
- formatter: (0, exports.dataLabelFormatter)(opts, locale),
223
- };
240
+ // Excel's Format Data Labels → Font: colour, family, size, bold, italic
241
+ // (rowsncolumns/spreadsheet#1105). Keys are only written when authored so
242
+ // a label keeps its series-aware default colour otherwise.
243
+ var font = (_b = (0, exports.textFormatToEchartsTextStyle)(opts.textFormat)) !== null && _b !== void 0 ? _b : {};
244
+ return tslib_1.__assign({ show: true, position: position, formatter: (0, exports.dataLabelFormatter)(opts, locale) }, font);
224
245
  };
225
246
  exports.buildSeriesLabelOption = buildSeriesLabelOption;
@@ -1 +1 @@
1
- {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAkEA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAuTrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAiGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBAsvHjB,CAAC"}
1
+ {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAkEA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAwTrD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAiGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBAmvHjB,CAAC"}
@@ -29,6 +29,7 @@ import { aggregateByCategory, binHistogram, computePareto, isParetoSpec, } from
29
29
  import { categoryAxisNameGap, legendLabelsFrom, reserveEchartsLegendBand, } from "../utils/legend-layout";
30
30
  import { clampSecondPieSize, isOfPieChartSpec, otherSliceHalfAngle, resolveOfPieType, splitOfPie, } from "../utils/of-pie";
31
31
  import { applyAxisOverrides, applyLegendOverrides, buildSeriesLabelOption, dataLabelFormatter, resolveSeriesDataLabels, } from "../utils/overrides";
32
+ import { themedTextStyle } from "../utils/overrides";
32
33
  import { explosionOffsetPx, pieRadiusPx, resolveExplosion, } from "../utils/pie-explosion";
33
34
  import { buildRadarIndicators, buildRadarSeriesData } from "../utils/radar";
34
35
  import { buildRegionMapData, buildSequentialColorRamp, isRegionMapSpec, resolveGeoScope, warnOnceForUnmatchedRegions, } from "../utils/region-map";
@@ -3175,28 +3176,20 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
3175
3176
  const options = {
3176
3177
  title: {
3177
3178
  text: title ?? undefined,
3178
- textStyle: {
3179
- color: authoredTitleFmt?.color ?? textColor,
3180
- ...(authoredTitleFmt?.fontFamily
3181
- ? { fontFamily: authoredTitleFmt.fontFamily }
3182
- : {}),
3183
- ...(typeof authoredTitleFmt?.fontSize === "number"
3184
- ? { fontSize: authoredTitleFmt.fontSize }
3185
- : {}),
3186
- ...(authoredTitleFmt?.bold ? { fontWeight: "bold" } : {}),
3187
- ...(authoredTitleFmt?.italic ? { fontStyle: "italic" } : {}),
3188
- },
3179
+ // Every key is written (echarts merges setOption calls, so a key
3180
+ // left out keeps its previous value — turning bold off used to
3181
+ // leave the title bold, rowsncolumns/spreadsheet#1105).
3182
+ textStyle: themedTextStyle(authoredTitleFmt, {
3183
+ color: textColor,
3184
+ fontSize: 18,
3185
+ fontWeight: "bold",
3186
+ }),
3189
3187
  },
3190
3188
  legend: {
3191
- textStyle: {
3192
- color: authoredLegendFmt?.color ?? textColor,
3193
- ...(authoredLegendFmt?.fontFamily
3194
- ? { fontFamily: authoredLegendFmt.fontFamily }
3195
- : {}),
3196
- ...(typeof authoredLegendFmt?.fontSize === "number"
3197
- ? { fontSize: authoredLegendFmt.fontSize }
3198
- : {}),
3199
- },
3189
+ textStyle: themedTextStyle(authoredLegendFmt, {
3190
+ color: textColor,
3191
+ fontSize: 12,
3192
+ }),
3200
3193
  },
3201
3194
  axisLabel: {
3202
3195
  color: authoredDataLabelFmt?.color ?? textColor,
@@ -3239,7 +3232,9 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
3239
3232
  chartRef.current.setOption(options);
3240
3233
  }
3241
3234
  };
3242
- // Update chart properties
3235
+ // Update chart properties — the authored text formats are inputs too, so
3236
+ // a font change applies at once instead of waiting for the next title
3237
+ // edit (rowsncolumns/spreadsheet#1105).
3243
3238
  useIsomorphicLayoutEffect(() => {
3244
3239
  applyThemeOptions();
3245
3240
  }, [
@@ -3249,6 +3244,9 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
3249
3244
  chart.spec.chartType,
3250
3245
  chart.spec.palette,
3251
3246
  chart.spec.backgroundColor,
3247
+ chart.spec.titleTextFormat,
3248
+ chart.spec.legend?.textFormat,
3249
+ chart.spec.dataLabels?.textFormat,
3252
3250
  ]);
3253
3251
  // Draw chart. `glUpgradeTick` re-runs the draw when the lazily loaded
3254
3252
  // echarts-gl module resolves, upgrading a 3-D spec's immediate 2-D
@@ -1,9 +1,11 @@
1
1
  import type { ChartTextFormat } from "@rowsncolumns/spreadsheet";
2
2
  import React from "react";
3
3
  /**
4
- * Font family / size / colour / bold / italic / underline / strikethrough
5
- * of one text element — the chart title, the legend, an axis or the data
6
- * labels (`ChartTextFormat`, OOXML `<c:txPr>`).
4
+ * Font family / size / colour / bold / italic of one text element — the
5
+ * chart title, the legend, an axis or the data labels (`ChartTextFormat`,
6
+ * OOXML `<c:txPr>`). `underline` / `strikethrough` stay on the spec for the
7
+ * xlsx round trip but have no control: neither renderer draws them
8
+ * (rowsncolumns/spreadsheet#1105).
7
9
  */
8
10
  export declare const TextFormatFields: ({ label, value, onChange, collapsible, ariaLabels, }: {
9
11
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"text-format-fields.d.ts","sourceRoot":"","sources":["../../../../../components/editors/fields/text-format-fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,sDAM9B;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAClD,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,sBA6EA,CAAC"}
1
+ {"version":3,"file":"text-format-fields.d.ts","sourceRoot":"","sources":["../../../../../components/editors/fields/text-format-fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,sDAM9B;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAClD,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE,sBAmEA,CAAC"}
@@ -2,9 +2,11 @@ import { Input } from "@rowsncolumns/ui";
2
2
  import React, { useState } from "react";
3
3
  import { CheckboxField, COLOR_CLASS } from "./primitives";
4
4
  /**
5
- * Font family / size / colour / bold / italic / underline / strikethrough
6
- * of one text element — the chart title, the legend, an axis or the data
7
- * labels (`ChartTextFormat`, OOXML `<c:txPr>`).
5
+ * Font family / size / colour / bold / italic of one text element — the
6
+ * chart title, the legend, an axis or the data labels (`ChartTextFormat`,
7
+ * OOXML `<c:txPr>`). `underline` / `strikethrough` stay on the spec for the
8
+ * xlsx round trip but have no control: neither renderer draws them
9
+ * (rowsncolumns/spreadsheet#1105).
8
10
  */
9
11
  export const TextFormatFields = ({ label, value, onChange, collapsible = false, ariaLabels, }) => {
10
12
  const [open, setOpen] = useState(!collapsible);
@@ -28,7 +30,5 @@ export const TextFormatFields = ({ label, value, onChange, collapsible = false,
28
30
  }), className: "text-xs w-16", placeholder: "Size", "aria-label": ariaLabels?.size ?? `${label} size` }),
29
31
  React.createElement("input", { type: "color", value: value?.color ?? "#000000", onChange: (e) => set({ color: e.target.value }), className: COLOR_CLASS, "aria-label": ariaLabels?.color ?? `${label} color` }),
30
32
  React.createElement(CheckboxField, { label: "Bold", checked: Boolean(value?.bold), onChange: (bold) => set({ bold }) }),
31
- React.createElement(CheckboxField, { label: "Italic", checked: Boolean(value?.italic), onChange: (italic) => set({ italic }) }),
32
- React.createElement(CheckboxField, { label: "Underline", checked: Boolean(value?.underline), onChange: (underline) => set({ underline }) }),
33
- React.createElement(CheckboxField, { label: "Strikethrough", checked: Boolean(value?.strikethrough), onChange: (strikethrough) => set({ strikethrough }) }))));
33
+ React.createElement(CheckboxField, { label: "Italic", checked: Boolean(value?.italic), onChange: (italic) => set({ italic }) }))));
34
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA+ZxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAmGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBA2rFjB,CAAC"}
1
+ {"version":3,"file":"basic-chart.d.ts","sourceRoot":"","sources":["../../../../plotly/basic-chart/basic-chart.tsx"],"names":[],"mappings":"AAoCA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAkcxD,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAmGnD,eAAO,MAAM,UAAU,GAAI,gPAkBxB,eAAe,sBA8rFjB,CAAC"}
@@ -230,6 +230,15 @@ const applyDataLabelsToTracePlotly = (trace, opts, chartType, sourceNumberFormat
230
230
  parts.push("percent");
231
231
  next.textinfo = parts.length ? parts.join("+") : "value";
232
232
  next.textposition = position;
233
+ if (opts.textFormat) {
234
+ const fmt = opts.textFormat;
235
+ next.textfont = {
236
+ ...(next.textfont ?? {}),
237
+ ...(fmt.fontFamily ? { family: fmt.fontFamily } : {}),
238
+ ...(typeof fmt.fontSize === "number" && fmt.fontSize > 0 ? { size: fmt.fontSize } : {}),
239
+ ...(fmt.color ? { color: fmt.color } : {}),
240
+ };
241
+ }
233
242
  // Values format like their source cells (or the authored `<c:numFmt>`):
234
243
  // plotly's own `%{value}` is a raw number, so the formatted strings
235
244
  // ride on `text` and a `texttemplate` mirrors the textinfo parts.
@@ -263,6 +272,39 @@ const applyDataLabelsToTracePlotly = (trace, opts, chartType, sourceNumberFormat
263
272
  if (isPoint)
264
273
  next.mode = withTextMode(next.mode);
265
274
  }
275
+ return applyDataLabelFontPlotly(next, opts.textFormat);
276
+ };
277
+ /**
278
+ * Excel's Format Data Labels → Font for a plotly trace: `textfont` carries
279
+ * family / size / colour, bold / italic are pseudo-HTML tags around each
280
+ * label (plotly fonts have no weight) — rowsncolumns/spreadsheet#1105.
281
+ */
282
+ const applyDataLabelFontPlotly = (trace, fmt) => {
283
+ if (!fmt)
284
+ return trace;
285
+ const next = { ...trace };
286
+ const textfont = { ...(next.textfont ?? {}) };
287
+ if (fmt.fontFamily)
288
+ textfont.family = fmt.fontFamily;
289
+ if (typeof fmt.fontSize === "number" && fmt.fontSize > 0)
290
+ textfont.size = fmt.fontSize;
291
+ if (fmt.color)
292
+ textfont.color = fmt.color;
293
+ if (Object.keys(textfont).length)
294
+ next.textfont = textfont;
295
+ const wrap = (text) => {
296
+ if (text === null || text === undefined || text === "")
297
+ return text;
298
+ let out = String(text);
299
+ if (fmt.italic)
300
+ out = `<i>${out}</i>`;
301
+ if (fmt.bold)
302
+ out = `<b>${out}</b>`;
303
+ return out;
304
+ };
305
+ if ((fmt.bold || fmt.italic) && next.text !== undefined) {
306
+ next.text = Array.isArray(next.text) ? next.text.map(wrap) : wrap(next.text);
307
+ }
266
308
  return next;
267
309
  };
268
310
  const BUBBLE_CHART_TYPES = new Set([
@@ -617,12 +659,12 @@ export const BasicChart = ({ width, height, chart, theme, isDarkMode, sheetId, r
617
659
  "top center"
618
660
  : undefined;
619
661
  const withLabels = (trace) => labelText
620
- ? {
662
+ ? applyDataLabelFontPlotly({
621
663
  ...trace,
622
664
  mode: withTextMode(trace.mode),
623
665
  text: labelText,
624
666
  textposition: labelPosition,
625
- }
667
+ }, labelOpts?.textFormat)
626
668
  : trace;
627
669
  if (isScatter) {
628
670
  // Per-series marker.symbol = "none" → pure line (no markers).
@@ -1,4 +1,24 @@
1
1
  import type { LegendComponentOption } from "echarts";
2
+ /**
3
+ * A complete echarts `textStyle` for a text element: the authored
4
+ * `ChartTextFormat` over the theme defaults, with every key present so a
5
+ * cleared setting (bold off, size blank) resets the element instead of
6
+ * keeping the previous merged value (rowsncolumns/spreadsheet#1105).
7
+ * Underline / strikethrough have no canvas text decoration in echarts and
8
+ * are not drawn.
9
+ */
10
+ export declare const themedTextStyle: (fmt: any, defaults: {
11
+ color: string;
12
+ fontSize: number;
13
+ fontFamily?: string;
14
+ fontWeight?: "normal" | "bold";
15
+ }) => {
16
+ color: any;
17
+ fontFamily: any;
18
+ fontSize: any;
19
+ fontWeight: "bold" | "normal";
20
+ fontStyle: "italic" | "normal";
21
+ };
2
22
  /** Build an echarts `textStyle` from a parsed `ChartTextFormat`. */
3
23
  export declare const textFormatToEchartsTextStyle: (fmt: any) => Record<string, any> | undefined;
4
24
  export declare const applyLegendOverrides: (legend: LegendComponentOption, opts: any) => LegendComponentOption;
@@ -1 +1 @@
1
- {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,SAAS,MAAM,EAEf,eAAa,MACT,QAAQ,GAAG,WAoDhB,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCAlGH,GAAG;aA+GhB,CAAC"}
1
+ {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../utils/overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWrD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,GAAG,EACR,UAAU;IACR,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;CAChC;;;;gBASG,MAAM,GACN,QAAQ;eACsC,QAAQ,GAAG,QAAQ;CACrE,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,GAAI,KAAK,GAAG,oCASpD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,qBAAqB,EAC7B,MAAM,GAAG,KACR,qBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,MAAM,GAAG,EACT,sBAAsB,MAAM,EAC5B,SAAS,MAAM,QA4BhB,CAAC;AAgBF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,GAAG,EACT,SAAS,MAAM,EAEf,eAAa,MACT,QAAQ,GAAG,WAoDhB,CAAC;AAgCF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,EACvC,YAAY,CAAC,GAAG,IAAI,GAAG,SAAS,EAChC,QAAQ;IAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,KACnD,CAAC,GAAG,IAAI,GAAG,SAA6C,CAAC;AAE5D,eAAO,MAAM,sBAAsB,GACjC,MAAM,GAAG,EACT,aAAa,MAAM,EACnB,SAAS,MAAM;;;iCAlGH,GAAG;aAoHhB,CAAC"}
@@ -5,6 +5,23 @@ import { formatAxisValue, valueAxisLabelFormatter } from "./axis-number-format";
5
5
  // option assembly and the bubble / hierarchy / radar / stock early
6
6
  // branches in `basic-chart.tsx` so every chart type honors the same
7
7
  // spec-level overrides.
8
+ /**
9
+ * A complete echarts `textStyle` for a text element: the authored
10
+ * `ChartTextFormat` over the theme defaults, with every key present so a
11
+ * cleared setting (bold off, size blank) resets the element instead of
12
+ * keeping the previous merged value (rowsncolumns/spreadsheet#1105).
13
+ * Underline / strikethrough have no canvas text decoration in echarts and
14
+ * are not drawn.
15
+ */
16
+ export const themedTextStyle = (fmt, defaults) => ({
17
+ color: fmt?.color ?? defaults.color,
18
+ fontFamily: fmt?.fontFamily ?? defaults.fontFamily ?? "sans-serif",
19
+ fontSize: typeof fmt?.fontSize === "number" && fmt.fontSize > 0
20
+ ? fmt.fontSize
21
+ : defaults.fontSize,
22
+ fontWeight: (fmt ? (fmt.bold ? "bold" : "normal") : defaults.fontWeight ?? "normal"),
23
+ fontStyle: (fmt?.italic ? "italic" : "normal"),
24
+ });
8
25
  /** Build an echarts `textStyle` from a parsed `ChartTextFormat`. */
9
26
  export const textFormatToEchartsTextStyle = (fmt) => {
10
27
  if (!fmt)
@@ -201,9 +218,14 @@ export const buildSeriesLabelOption = (opts, seriesType, locale) => {
201
218
  ? ECHARTS_POINT_DLBL_POS
202
219
  : ECHARTS_DLBL_POS;
203
220
  const position = (opts.position && positions[opts.position]) ?? "top";
221
+ // Excel's Format Data Labels → Font: colour, family, size, bold, italic
222
+ // (rowsncolumns/spreadsheet#1105). Keys are only written when authored so
223
+ // a label keeps its series-aware default colour otherwise.
224
+ const font = textFormatToEchartsTextStyle(opts.textFormat) ?? {};
204
225
  return {
205
226
  show: true,
206
227
  position,
207
228
  formatter: dataLabelFormatter(opts, locale),
229
+ ...font,
208
230
  };
209
231
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowsncolumns/charts",
3
- "version": "28.1.16",
3
+ "version": "28.1.17",
4
4
  "author": "Vinay M",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "main": "./dist/cjs/index.js",
@@ -72,7 +72,7 @@
72
72
  "@rowsncolumns/icons": ">=7.2.33",
73
73
  "@rowsncolumns/spreadsheet": ">=10.4.13",
74
74
  "@rowsncolumns/spreadsheet-state": ">=29.1.8",
75
- "@rowsncolumns/toolkit": ">=24.5.13",
75
+ "@rowsncolumns/toolkit": ">=24.5.14",
76
76
  "@rowsncolumns/ui": ">=16.0.4",
77
77
  "@rowsncolumns/utils": ">=9.5.5",
78
78
  "@types/react-plotly.js": "^2.6.3",