@techie_doubts/editor-plugin-chart 3.0.1 → 3.1.1

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,6 +1,6 @@
1
1
  /*!
2
2
  * TOAST UI Editor : Chart Plugin
3
- * @version 3.0.1 | Sat Feb 21 2026
3
+ * @version 3.1.1 | Sun Mar 01 2026
4
4
  * @author NHN Cloud FE Development Lab <dl_javascript@nhn.com>
5
5
  * @license MIT
6
6
  */
@@ -6449,6 +6449,7 @@ var DEFAULT_DIMENSION_OPTIONS = {
6449
6449
  };
6450
6450
  var FALLBACK_CONTAINER_WIDTH = 600;
6451
6451
  var RESERVED_KEYS = ['type', 'url'];
6452
+ var TOOLTIP_FRACTION_DIGITS = 2;
6452
6453
  var chart = {
6453
6454
  bar: (tui_chart_2026_root_toastui_Chart_default()).barChart,
6454
6455
  column: (tui_chart_2026_root_toastui_Chart_default()).columnChart,
@@ -6457,7 +6458,9 @@ var chart = {
6457
6458
  pie: (tui_chart_2026_root_toastui_Chart_default()).pieChart,
6458
6459
  };
6459
6460
  var chartMap = {};
6461
+ var chartRenderVersionMap = {};
6460
6462
  var effectiveDarkMode = null;
6463
+ var chartStyleInjected = false;
6461
6464
  var DARK_CHART_THEME = {
6462
6465
  chart: { backgroundColor: '#1a1a1a' },
6463
6466
  title: { color: '#e0e0e0' },
@@ -6483,6 +6486,16 @@ var DARK_CHART_THEME = {
6483
6486
  body: { color: '#d1d5db' },
6484
6487
  },
6485
6488
  };
6489
+ function ensureChartStyles() {
6490
+ if (chartStyleInjected || typeof document === 'undefined') {
6491
+ return;
6492
+ }
6493
+ var style = document.createElement('style');
6494
+ style.setAttribute('data-toastui-chart-plugin', '1');
6495
+ style.textContent = "\n.toastui-chart-block {\n text-align: center;\n}\n\n.toastui-chart-block > * {\n margin-left: auto;\n margin-right: auto;\n}\n\n.toastui-chart-block svg,\n.toastui-chart-block canvas {\n max-width: 100%;\n}\n ".trim();
6496
+ document.head.appendChild(style);
6497
+ chartStyleInjected = true;
6498
+ }
6486
6499
  function parse(text, callback) {
6487
6500
  var _a;
6488
6501
  text = trimKeepingTabs(text);
@@ -6644,11 +6657,331 @@ function getChartDimension(chartOptions, pluginOptions, chartContainer) {
6644
6657
  height: clamp(height, minHeight, maxHeight),
6645
6658
  };
6646
6659
  }
6647
- function setDefaultOptions(chartOptions, pluginOptions, chartContainer) {
6660
+ function isPlainObject(value) {
6661
+ return !!value && typeof value === 'object' && !Array.isArray(value);
6662
+ }
6663
+ function mergeChartOptions(baseOptions, overrideOptions) {
6664
+ var base = isPlainObject(baseOptions) ? baseOptions : {};
6665
+ var override = isPlainObject(overrideOptions) ? overrideOptions : {};
6666
+ var merged = __assign({}, base);
6667
+ Object.keys(override).forEach(function (key) {
6668
+ var baseValue = merged[key];
6669
+ var overrideValue = override[key];
6670
+ merged[key] =
6671
+ isPlainObject(baseValue) && isPlainObject(overrideValue)
6672
+ ? mergeChartOptions(baseValue, overrideValue)
6673
+ : overrideValue;
6674
+ });
6675
+ return merged;
6676
+ }
6677
+ function getPluginChartOptions(pluginOptions) {
6678
+ var chartOptions = pluginOptions.chartOptions;
6679
+ return isPlainObject(chartOptions) ? chartOptions : {};
6680
+ }
6681
+ function normalizeSeriesStyleKey(value) {
6682
+ var normalized = typeof value.normalize === 'function' ? value.normalize('NFKC') : value;
6683
+ return normalized
6684
+ .replace(/\uFEFF/g, '')
6685
+ .trim()
6686
+ .replace(/^['"]|['"]$/g, '')
6687
+ .trim()
6688
+ .replace(/\s+/g, ' ')
6689
+ .toLowerCase();
6690
+ }
6691
+ function assignSeriesStyleByIndex(chartOptions, chartData) {
6692
+ if (!chartData || !isPlainObject(chartOptions.series)) {
6693
+ return;
6694
+ }
6695
+ var seriesOptions = chartOptions.series;
6696
+ if (!isPlainObject(seriesOptions.styles)) {
6697
+ return;
6698
+ }
6699
+ var styles = seriesOptions.styles;
6700
+ var indexBySeriesName = new Map();
6701
+ chartData.series.forEach(function (seriesItem, seriesIndex) {
6702
+ if (typeof (seriesItem === null || seriesItem === void 0 ? void 0 : seriesItem.name) === 'string' && seriesItem.name.trim()) {
6703
+ indexBySeriesName.set(normalizeSeriesStyleKey(seriesItem.name), seriesIndex);
6704
+ }
6705
+ });
6706
+ Object.keys(styles).forEach(function (styleKey) {
6707
+ if (/^\d+$/.test(styleKey.trim())) {
6708
+ return;
6709
+ }
6710
+ var seriesIndex = indexBySeriesName.get(normalizeSeriesStyleKey(styleKey));
6711
+ if (typeof seriesIndex !== 'number') {
6712
+ return;
6713
+ }
6714
+ var indexKey = String(seriesIndex);
6715
+ if (typeof styles[indexKey] === 'undefined') {
6716
+ styles[indexKey] = styles[styleKey];
6717
+ }
6718
+ });
6719
+ }
6720
+ function escapeHTML(value) {
6721
+ return String(value !== null && value !== void 0 ? value : '')
6722
+ .replace(/&/g, '&amp;')
6723
+ .replace(/</g, '&lt;')
6724
+ .replace(/>/g, '&gt;')
6725
+ .replace(/"/g, '&quot;')
6726
+ .replace(/'/g, '&#39;');
6727
+ }
6728
+ function isNil(value) {
6729
+ return value === null || typeof value === 'undefined';
6730
+ }
6731
+ function isThousandsOptions(value) {
6732
+ return (isPlainObject(value) &&
6733
+ typeof value.mode === 'string' &&
6734
+ ['none', 'locale', 'custom'].includes(value.mode));
6735
+ }
6736
+ function resolveThousandsOptions(value) {
6737
+ if (typeof value === 'string') {
6738
+ return value.length ? { mode: 'custom', separator: value } : { mode: 'none' };
6739
+ }
6740
+ if (value === true || value === 1) {
6741
+ return { mode: 'locale' };
6742
+ }
6743
+ return { mode: 'none' };
6744
+ }
6745
+ function splitNumericText(value) {
6746
+ var matched = value.match(/^([+-]?)(\d+)(\.\d+)?$/);
6747
+ if (!matched) {
6748
+ return null;
6749
+ }
6750
+ return {
6751
+ sign: matched[1] || '',
6752
+ integer: matched[2],
6753
+ fraction: matched[3] || '',
6754
+ };
6755
+ }
6756
+ function applyCustomThousandsSeparator(value, separator) {
6757
+ var parts = splitNumericText(value);
6758
+ if (!parts) {
6759
+ return value;
6760
+ }
6761
+ return "" + parts.sign + parts.integer.replace(/\B(?=(\d{3})+(?!\d))/g, separator) + parts.fraction;
6762
+ }
6763
+ function formatAxisValueWithThousands(value, options) {
6764
+ if (options.mode === 'none') {
6765
+ return value;
6766
+ }
6767
+ if (options.mode === 'custom') {
6768
+ return applyCustomThousandsSeparator(value, options.separator || ' ');
6769
+ }
6770
+ var numericValue = Number(value);
6771
+ if (!Number.isFinite(numericValue)) {
6772
+ return value;
6773
+ }
6774
+ var fractionMatched = value.match(/\.(\d+)$/);
6775
+ var fractionLength = fractionMatched ? fractionMatched[1].length : 0;
6776
+ return numericValue.toLocaleString([], {
6777
+ useGrouping: true,
6778
+ minimumFractionDigits: fractionLength,
6779
+ maximumFractionDigits: fractionLength,
6780
+ });
6781
+ }
6782
+ function inferThousandsOptionsFromFormatter(formatter) {
6783
+ try {
6784
+ var probe = String(formatter('1000'));
6785
+ var matched = probe.match(/1([^0-9])000/);
6786
+ if (matched) {
6787
+ return { mode: 'custom', separator: matched[1] };
6788
+ }
6789
+ }
6790
+ catch (error) {
6791
+ return { mode: 'none' };
6792
+ }
6793
+ return { mode: 'none' };
6794
+ }
6795
+ function getYAxisThousandsOptions(tooltipComponent) {
6796
+ var _a, _b, _c;
6797
+ var chartOptions = (_b = (_a = tooltipComponent === null || tooltipComponent === void 0 ? void 0 : tooltipComponent.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.options;
6798
+ var yAxisOptions = Array.isArray(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.yAxis)
6799
+ ? chartOptions.yAxis[0]
6800
+ : chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.yAxis;
6801
+ if (!isPlainObject(yAxisOptions)) {
6802
+ return { mode: 'none' };
6803
+ }
6804
+ var metadata = yAxisOptions.__editorThousands;
6805
+ if (isThousandsOptions(metadata)) {
6806
+ return metadata;
6807
+ }
6808
+ if (metadata === true) {
6809
+ return { mode: 'locale' };
6810
+ }
6811
+ var yAxisFormatter = (_c = yAxisOptions.label) === null || _c === void 0 ? void 0 : _c.formatter;
6812
+ if (typeof yAxisFormatter === 'function') {
6813
+ return inferThousandsOptionsFromFormatter(yAxisFormatter);
6814
+ }
6815
+ return { mode: 'none' };
6816
+ }
6817
+ function getTooltipFontStyle(themePart) {
6818
+ if (!themePart || typeof themePart !== 'object') {
6819
+ return '';
6820
+ }
6821
+ var declarations = [];
6822
+ if (!isNil(themePart.fontWeight)) {
6823
+ declarations.push("font-weight: " + themePart.fontWeight);
6824
+ }
6825
+ if (themePart.fontFamily) {
6826
+ declarations.push("font-family: " + themePart.fontFamily);
6827
+ }
6828
+ if (!isNil(themePart.fontSize)) {
6829
+ declarations.push("font-size: " + themePart.fontSize + "px");
6830
+ }
6831
+ if (themePart.color) {
6832
+ declarations.push("color: " + themePart.color);
6833
+ }
6834
+ return declarations.join('; ');
6835
+ }
6836
+ function formatTooltipNumber(value, tooltipComponent) {
6837
+ var thousandsOptions = getYAxisThousandsOptions(tooltipComponent);
6838
+ if (typeof value === 'number' && Number.isFinite(value)) {
6839
+ if (thousandsOptions.mode === 'locale') {
6840
+ return value.toLocaleString([], {
6841
+ useGrouping: true,
6842
+ minimumFractionDigits: TOOLTIP_FRACTION_DIGITS,
6843
+ maximumFractionDigits: TOOLTIP_FRACTION_DIGITS,
6844
+ });
6845
+ }
6846
+ var formatted = value.toFixed(TOOLTIP_FRACTION_DIGITS);
6847
+ if (thousandsOptions.mode === 'custom') {
6848
+ return applyCustomThousandsSeparator(formatted, thousandsOptions.separator || ' ');
6849
+ }
6850
+ return formatted;
6851
+ }
6852
+ if (Array.isArray(value)) {
6853
+ return value.map(function (item) { return formatTooltipNumber(item, tooltipComponent); }).join(' - ');
6854
+ }
6855
+ return String(value !== null && value !== void 0 ? value : '');
6856
+ }
6857
+ function getTooltipSeriesCollection(tooltipComponent) {
6858
+ var _a, _b;
6859
+ var seriesState = (_b = (_a = tooltipComponent === null || tooltipComponent === void 0 ? void 0 : tooltipComponent.store) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.series;
6860
+ if (!seriesState || typeof seriesState !== 'object') {
6861
+ return [];
6862
+ }
6863
+ var supportedSeriesTypes = ['line', 'area', 'column', 'bar', 'scatter', 'bubble', 'radar'];
6864
+ for (var _i = 0, supportedSeriesTypes_1 = supportedSeriesTypes; _i < supportedSeriesTypes_1.length; _i++) {
6865
+ var seriesType = supportedSeriesTypes_1[_i];
6866
+ var seriesCollection = seriesState[seriesType];
6867
+ if (Array.isArray(seriesCollection === null || seriesCollection === void 0 ? void 0 : seriesCollection.data) && seriesCollection.data.length) {
6868
+ return seriesCollection.data;
6869
+ }
6870
+ }
6871
+ return [];
6872
+ }
6873
+ function getTooltipCategoryIndex(model) {
6874
+ if (!Array.isArray(model === null || model === void 0 ? void 0 : model.data)) {
6875
+ return null;
6876
+ }
6877
+ var indexOwner = model.data.find(function (item) { return Number.isInteger(item === null || item === void 0 ? void 0 : item.index); });
6878
+ return indexOwner ? indexOwner.index : null;
6879
+ }
6880
+ function getTooltipSeriesColor(colorValue) {
6881
+ if (Array.isArray(colorValue)) {
6882
+ var firstColor = colorValue.find(function (value) { return typeof value === 'string' && value.trim(); });
6883
+ return firstColor || '#8ea0bf';
6884
+ }
6885
+ if (typeof colorValue === 'string' && colorValue.trim()) {
6886
+ return colorValue;
6887
+ }
6888
+ return '#8ea0bf';
6889
+ }
6890
+ function normalizeTooltipSeriesValue(rawValue) {
6891
+ if (isNil(rawValue)) {
6892
+ return null;
6893
+ }
6894
+ if (typeof rawValue === 'number') {
6895
+ return Number.isFinite(rawValue) ? rawValue : null;
6896
+ }
6897
+ if (typeof rawValue === 'string') {
6898
+ var trimmed = rawValue.trim();
6899
+ if (!trimmed) {
6900
+ return null;
6901
+ }
6902
+ var asNumber = Number(trimmed);
6903
+ return Number.isFinite(asNumber) ? asNumber : trimmed;
6904
+ }
6905
+ if (Array.isArray(rawValue)) {
6906
+ if (!rawValue.length) {
6907
+ return null;
6908
+ }
6909
+ if (rawValue.length >= 2) {
6910
+ var secondValue = normalizeTooltipSeriesValue(rawValue[1]);
6911
+ if (!isNil(secondValue)) {
6912
+ return secondValue;
6913
+ }
6914
+ }
6915
+ for (var index = rawValue.length - 1; index >= 0; index -= 1) {
6916
+ var candidate = normalizeTooltipSeriesValue(rawValue[index]);
6917
+ if (!isNil(candidate)) {
6918
+ return candidate;
6919
+ }
6920
+ }
6921
+ return null;
6922
+ }
6923
+ if (typeof rawValue === 'object') {
6924
+ if ('y' in rawValue) {
6925
+ return normalizeTooltipSeriesValue(rawValue.y);
6926
+ }
6927
+ if ('value' in rawValue) {
6928
+ return normalizeTooltipSeriesValue(rawValue.value);
6929
+ }
6930
+ }
6931
+ return null;
6932
+ }
6933
+ function wrapTooltipTemplate(theme, headerMarkup, bodyMarkup) {
6934
+ var borderWidth = Number.isFinite(theme === null || theme === void 0 ? void 0 : theme.borderWidth) ? theme.borderWidth : 1;
6935
+ var borderStyle = (theme === null || theme === void 0 ? void 0 : theme.borderStyle) || 'solid';
6936
+ var borderColor = (theme === null || theme === void 0 ? void 0 : theme.borderColor) || '#d7dce8';
6937
+ var borderRadius = Number.isFinite(theme === null || theme === void 0 ? void 0 : theme.borderRadius) ? theme.borderRadius : 8;
6938
+ var background = (theme === null || theme === void 0 ? void 0 : theme.background) || '#ffffff';
6939
+ var containerStyle = "border: " + borderWidth + "px " + borderStyle + " " + borderColor + ";border-radius: " + borderRadius + "px;background: " + background + ";";
6940
+ return "<div class=\"td-chart-tooltip\" style=\"" + containerStyle + "\">" + headerMarkup + bodyMarkup + "</div>";
6941
+ }
6942
+ function buildFullSeriesTooltip(tooltipComponent, model, defaultTemplate, theme) {
6943
+ var seriesCollection = getTooltipSeriesCollection(tooltipComponent);
6944
+ var categoryIndex = getTooltipCategoryIndex(model);
6945
+ if (!seriesCollection.length || isNil(categoryIndex) || categoryIndex < 0) {
6946
+ return wrapTooltipTemplate(theme, (defaultTemplate === null || defaultTemplate === void 0 ? void 0 : defaultTemplate.header) || '', (defaultTemplate === null || defaultTemplate === void 0 ? void 0 : defaultTemplate.body) || '');
6947
+ }
6948
+ var visibleModelSeries = new Map();
6949
+ for (var _i = 0, _a = model.data || []; _i < _a.length; _i++) {
6950
+ var tooltipData = _a[_i];
6951
+ if (Number.isInteger(tooltipData === null || tooltipData === void 0 ? void 0 : tooltipData.seriesIndex)) {
6952
+ visibleModelSeries.set(tooltipData.seriesIndex, tooltipData);
6953
+ }
6954
+ }
6955
+ var seriesRows = seriesCollection
6956
+ .map(function (seriesItem, seriesIndex) {
6957
+ var _a, _b;
6958
+ var tooltipData = visibleModelSeries.get(seriesIndex);
6959
+ var label = (tooltipData === null || tooltipData === void 0 ? void 0 : tooltipData.label) || (seriesItem === null || seriesItem === void 0 ? void 0 : seriesItem.name) || "Series " + (seriesIndex + 1);
6960
+ var color = getTooltipSeriesColor((_a = tooltipData === null || tooltipData === void 0 ? void 0 : tooltipData.color) !== null && _a !== void 0 ? _a : seriesItem === null || seriesItem === void 0 ? void 0 : seriesItem.color);
6961
+ var rawSeriesValue = Array.isArray(seriesItem === null || seriesItem === void 0 ? void 0 : seriesItem.rawData)
6962
+ ? seriesItem.rawData[categoryIndex]
6963
+ : null;
6964
+ var rawValue = (_b = tooltipData === null || tooltipData === void 0 ? void 0 : tooltipData.value) !== null && _b !== void 0 ? _b : rawSeriesValue;
6965
+ var normalizedValue = normalizeTooltipSeriesValue(rawValue);
6966
+ var valueMarkup = isNil(normalizedValue)
6967
+ ? '<span class="td-chart-tooltip-none">None</span>'
6968
+ : escapeHTML(formatTooltipNumber(normalizedValue, tooltipComponent));
6969
+ return "<div class=\"td-chart-tooltip-series\">\n <span class=\"td-chart-series-name\">\n <i class=\"td-chart-icon\" style=\"background: " + escapeHTML(color) + "\"></i>\n <span class=\"td-chart-name\">" + escapeHTML(label) + "</span>\n </span>\n <span class=\"td-chart-series-value\">" + valueMarkup + "</span>\n </div>";
6970
+ })
6971
+ .join('');
6972
+ var headerMarkup = model.category
6973
+ ? "<div class=\"td-chart-tooltip-category\" style=\"" + getTooltipFontStyle(theme === null || theme === void 0 ? void 0 : theme.header) + "\">" + escapeHTML(model.category) + "</div>"
6974
+ : '';
6975
+ var bodyMarkup = "<div class=\"td-chart-tooltip-series-wrapper\" style=\"" + getTooltipFontStyle(theme === null || theme === void 0 ? void 0 : theme.body) + "\">" + seriesRows + "</div>";
6976
+ return wrapTooltipTemplate(theme, headerMarkup, bodyMarkup);
6977
+ }
6978
+ function setDefaultOptions(chartOptions, pluginOptions, chartContainer, chartData) {
6979
+ chartOptions = mergeChartOptions(getPluginChartOptions(pluginOptions), chartOptions);
6648
6980
  chartOptions = Object.assign({
6649
6981
  editorChart: {},
6650
6982
  chart: {},
6651
6983
  exportMenu: {},
6984
+ tooltip: {},
6652
6985
  }, chartOptions);
6653
6986
  var _a = getChartDimension(chartOptions, pluginOptions, chartContainer), width = _a.width, height = _a.height;
6654
6987
  chartOptions.chart.width = width;
@@ -6657,28 +6990,49 @@ function setDefaultOptions(chartOptions, pluginOptions, chartContainer) {
6657
6990
  chartOptions.editorChart.type = chartOptions.editorChart.type || 'column';
6658
6991
  // default visibility of export menu
6659
6992
  chartOptions.exportMenu.visible = !!chartOptions.exportMenu.visible;
6993
+ if (typeof chartOptions.tooltip.transition === 'undefined') {
6994
+ chartOptions.tooltip.transition = false;
6995
+ }
6996
+ if (typeof chartOptions.tooltip.formatter !== 'function') {
6997
+ chartOptions.tooltip.formatter = function formatter(value) {
6998
+ return formatTooltipNumber(value, this);
6999
+ };
7000
+ }
7001
+ if (typeof chartOptions.tooltip.template !== 'function') {
7002
+ chartOptions.tooltip.template = function template(model, defaultTemplate, theme) {
7003
+ return buildFullSeriesTooltip(this, model, defaultTemplate, theme);
7004
+ };
7005
+ }
6660
7006
  ['xAxis', 'yAxis'].forEach(function (axis) {
6661
7007
  var axisOpts = chartOptions[axis];
6662
7008
  if (!axisOpts) {
6663
7009
  return;
6664
7010
  }
6665
- var suffix = axisOpts.suffix, thousands = axisOpts.thousands;
6666
- delete axisOpts.suffix;
6667
- delete axisOpts.thousands;
6668
- if (suffix || thousands) {
6669
- axisOpts.label = axisOpts.label || {};
6670
- axisOpts.label.formatter = function (value) {
6671
- var result = String(value);
6672
- if (thousands) {
6673
- result = result.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
6674
- }
6675
- if (suffix) {
6676
- result = "" + result + suffix;
6677
- }
6678
- return result;
6679
- };
6680
- }
7011
+ var axisList = Array.isArray(axisOpts) ? axisOpts : [axisOpts];
7012
+ axisList.forEach(function (axisOption) {
7013
+ if (!isPlainObject(axisOption)) {
7014
+ return;
7015
+ }
7016
+ var normalizedAxisOption = axisOption;
7017
+ var _a = normalizedAxisOption, suffix = _a.suffix, thousands = _a.thousands;
7018
+ var thousandsOptions = resolveThousandsOptions(thousands);
7019
+ normalizedAxisOption.__editorThousands = thousandsOptions;
7020
+ delete normalizedAxisOption.suffix;
7021
+ delete normalizedAxisOption.thousands;
7022
+ if (suffix || thousandsOptions.mode !== 'none') {
7023
+ normalizedAxisOption.label = normalizedAxisOption.label || {};
7024
+ normalizedAxisOption.label.formatter = function (value) {
7025
+ var result = String(value);
7026
+ result = formatAxisValueWithThousands(result, thousandsOptions);
7027
+ if (suffix) {
7028
+ result = "" + result + suffix;
7029
+ }
7030
+ return result;
7031
+ };
7032
+ }
7033
+ });
6681
7034
  });
7035
+ assignSeriesStyleByIndex(chartOptions, chartData);
6682
7036
  return chartOptions;
6683
7037
  }
6684
7038
  function isDarkMode(el) {
@@ -6687,19 +7041,42 @@ function isDarkMode(el) {
6687
7041
  }
6688
7042
  function destroyChart() {
6689
7043
  Object.keys(chartMap).forEach(function (id) {
6690
- var container = document.querySelector("[data-chart-id=" + id + "]");
7044
+ var container = document.querySelector("[data-chart-id=\"" + id + "\"]");
6691
7045
  if (!container) {
6692
7046
  chartMap[id].destroy();
6693
7047
  delete chartMap[id];
7048
+ delete chartRenderVersionMap[id];
6694
7049
  }
6695
7050
  });
6696
7051
  }
7052
+ function clearChartById(id, chartContainer) {
7053
+ var existed = chartMap[id];
7054
+ if (existed) {
7055
+ existed.destroy();
7056
+ delete chartMap[id];
7057
+ }
7058
+ if (chartContainer) {
7059
+ chartContainer.innerHTML = '';
7060
+ }
7061
+ }
6697
7062
  function doRenderChart(id, text, usageStatistics, pluginOptions, chartContainer) {
7063
+ var renderVersion = (chartRenderVersionMap[id] || 0) + 1;
7064
+ chartRenderVersionMap[id] = renderVersion;
6698
7065
  chartContainer.setAttribute('data-chart-text', encodeURIComponent(text));
7066
+ clearChartById(id, chartContainer);
6699
7067
  try {
6700
7068
  parse(text, function (parsedInfo) {
7069
+ if (chartRenderVersionMap[id] !== renderVersion) {
7070
+ return;
7071
+ }
7072
+ if (!chartContainer.isConnected) {
7073
+ return;
7074
+ }
7075
+ if (chartContainer.getAttribute('data-chart-id') !== id) {
7076
+ return;
7077
+ }
6701
7078
  var _a = parsedInfo || {}, data = _a.data, options = _a.options;
6702
- var chartOptions = setDefaultOptions(options, pluginOptions, chartContainer);
7079
+ var chartOptions = setDefaultOptions(options, pluginOptions, chartContainer, data);
6703
7080
  var chartType = chartOptions.editorChart.type;
6704
7081
  var dark = effectiveDarkMode !== null ? effectiveDarkMode : isDarkMode(chartContainer);
6705
7082
  if (dark) {
@@ -6709,9 +7086,11 @@ function doRenderChart(id, text, usageStatistics, pluginOptions, chartContainer)
6709
7086
  (CATEGORY_CHART_TYPES.indexOf(chartType) > -1 &&
6710
7087
  data.categories.length !== data.series[0].data.length)) {
6711
7088
  chartContainer.innerHTML = 'invalid chart data';
7089
+ delete chartMap[id];
6712
7090
  }
6713
7091
  else if (SUPPORTED_CHART_TYPES.indexOf(chartType) < 0) {
6714
7092
  chartContainer.innerHTML = "invalid chart type. type: bar, column, line, area, pie";
7093
+ delete chartMap[id];
6715
7094
  }
6716
7095
  else {
6717
7096
  var toastuiChart = chart[chartType];
@@ -6723,15 +7102,23 @@ function doRenderChart(id, text, usageStatistics, pluginOptions, chartContainer)
6723
7102
  }
6724
7103
  catch (e) {
6725
7104
  chartContainer.innerHTML = 'invalid chart data';
7105
+ delete chartMap[id];
6726
7106
  }
6727
7107
  }
6728
- function renderChart(id, text, usageStatistics, pluginOptions) {
7108
+ function renderChart(id, text, usageStatistics, pluginOptions, retryCount) {
7109
+ if (retryCount === void 0) { retryCount = 0; }
6729
7110
  // should draw the chart after rendering container element
6730
- var chartContainer = document.querySelector("[data-chart-id=" + id + "]");
6731
- destroyChart();
6732
- if (chartContainer) {
6733
- doRenderChart(id, text, usageStatistics, pluginOptions, chartContainer);
7111
+ var chartContainer = document.querySelector("[data-chart-id=\"" + id + "\"]");
7112
+ if (!chartContainer) {
7113
+ if (retryCount < 8) {
7114
+ requestAnimationFrame(function () {
7115
+ renderChart(id, text, usageStatistics, pluginOptions, retryCount + 1);
7116
+ });
7117
+ }
7118
+ return;
6734
7119
  }
7120
+ destroyChart();
7121
+ doRenderChart(id, text, usageStatistics, pluginOptions, chartContainer);
6735
7122
  }
6736
7123
  function reRenderAllCharts(usageStatistics, pluginOptions, forceDark) {
6737
7124
  effectiveDarkMode = forceDark;
@@ -6742,6 +7129,7 @@ function reRenderAllCharts(usageStatistics, pluginOptions, forceDark) {
6742
7129
  chartMap[id].destroy();
6743
7130
  delete chartMap[id];
6744
7131
  }
7132
+ delete chartRenderVersionMap[id];
6745
7133
  container.innerHTML = '';
6746
7134
  var text = decodeURIComponent(container.getAttribute('data-chart-text'));
6747
7135
  doRenderChart(id, text, usageStatistics, pluginOptions, container);
@@ -6750,15 +7138,8 @@ function reRenderAllCharts(usageStatistics, pluginOptions, forceDark) {
6750
7138
  function generateId() {
6751
7139
  return "chart-" + Math.random().toString(36).substr(2, 10);
6752
7140
  }
6753
- var timer = null;
6754
- function clearTimer() {
6755
- if (timer) {
6756
- clearTimeout(timer);
6757
- timer = null;
6758
- }
6759
- }
6760
7141
  function getEditorRoot(instance) {
6761
- var _a, _b, _c;
7142
+ var _a;
6762
7143
  var elements = null;
6763
7144
  try {
6764
7145
  elements = (_a = instance.getEditorElements) === null || _a === void 0 ? void 0 : _a.call(instance);
@@ -6766,13 +7147,19 @@ function getEditorRoot(instance) {
6766
7147
  catch (e) {
6767
7148
  elements = null;
6768
7149
  }
6769
- return (((_b = elements === null || elements === void 0 ? void 0 : elements.mdPreview) === null || _b === void 0 ? void 0 : _b.closest('.toastui-editor-defaultUI')) ||
6770
- ((_c = elements === null || elements === void 0 ? void 0 : elements.wwEditor) === null || _c === void 0 ? void 0 : _c.closest('.toastui-editor-defaultUI')) ||
6771
- document.querySelector('.toastui-editor-defaultUI'));
7150
+ var selectors = ['.toastui-editor-defaultUI', '.td-editor-defaultUI'];
7151
+ return (selectors
7152
+ .map(function (selector) { var _a, _b; return ((_a = elements === null || elements === void 0 ? void 0 : elements.mdPreview) === null || _a === void 0 ? void 0 : _a.closest(selector)) || ((_b = elements === null || elements === void 0 ? void 0 : elements.wwEditor) === null || _b === void 0 ? void 0 : _b.closest(selector)); })
7153
+ .find(Boolean) ||
7154
+ selectors.map(function (selector) { return document.querySelector(selector); }).find(Boolean) ||
7155
+ null);
6772
7156
  }
6773
7157
  function detectDarkMode(instance) {
6774
- var _a;
6775
- return !!((_a = getEditorRoot(instance)) === null || _a === void 0 ? void 0 : _a.classList.contains('toastui-editor-dark'));
7158
+ var root = getEditorRoot(instance);
7159
+ if (!root) {
7160
+ return false;
7161
+ }
7162
+ return (root.classList.contains('toastui-editor-dark') || root.classList.contains('td-editor-dark'));
6776
7163
  }
6777
7164
  /**
6778
7165
  * Chart plugin
@@ -6786,6 +7173,7 @@ function detectDarkMode(instance) {
6786
7173
  * @param {number|string} [options.height='auto'] - default height
6787
7174
  */
6788
7175
  function chartPlugin(context, options) {
7176
+ ensureChartStyles();
6789
7177
  var _a = context.usageStatistics, usageStatistics = _a === void 0 ? true : _a;
6790
7178
  var instance = context.instance;
6791
7179
  var scheduled = false;
@@ -6833,7 +7221,11 @@ function chartPlugin(context, options) {
6833
7221
  rootObserver.observe(root, { attributes: true, attributeFilter: ['class'] });
6834
7222
  };
6835
7223
  context.eventEmitter.listen('changeTheme', function (theme) {
6836
- scheduleReRender({ themeOverride: theme === 'dark' });
7224
+ if (theme === 'dark' || theme === 'light') {
7225
+ scheduleReRender({ themeOverride: theme === 'dark' });
7226
+ return;
7227
+ }
7228
+ scheduleReRender({ deferFrames: 2 });
6837
7229
  });
6838
7230
  context.eventEmitter.listen('changeMode', function () {
6839
7231
  bindThemeObserver();
@@ -6854,8 +7246,8 @@ function chartPlugin(context, options) {
6854
7246
  toHTMLRenderers: {
6855
7247
  chart: function (node) {
6856
7248
  var id = generateId();
6857
- clearTimer();
6858
- timer = setTimeout(function () {
7249
+ var encodedText = encodeURIComponent(node.literal || '');
7250
+ requestAnimationFrame(function () {
6859
7251
  renderChart(id, node.literal, usageStatistics, options);
6860
7252
  });
6861
7253
  return [
@@ -6863,7 +7255,11 @@ function chartPlugin(context, options) {
6863
7255
  type: 'openTag',
6864
7256
  tagName: 'div',
6865
7257
  outerNewLine: true,
6866
- attributes: { 'data-chart-id': id },
7258
+ attributes: {
7259
+ class: 'toastui-chart-block',
7260
+ 'data-chart-id': id,
7261
+ 'data-chart-text': encodedText,
7262
+ },
6867
7263
  },
6868
7264
  { type: 'closeTag', tagName: 'div', outerNewLine: true },
6869
7265
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techie_doubts/editor-plugin-chart",
3
- "version": "3.0.1",
3
+ "version": "3.1.1",
4
4
  "description": "TOAST UI Editor : Chart Plugin",
5
5
  "keywords": [
6
6
  "nhn",
package/types/index.d.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import type { PluginContext, PluginInfo } from '@techie_doubts/tui.editor.2026';
2
+ import type { BaseOptions } from '@techie_doubts/tui.chart.2026';
2
3
 
3
4
  export interface PluginOptions {
4
- minWidth: number;
5
- maxWidth: number;
6
- minHeight: number;
7
- maxHeight: number;
8
- width: number | 'auto';
9
- height: number | 'auto';
5
+ minWidth?: number;
6
+ maxWidth?: number;
7
+ minHeight?: number;
8
+ maxHeight?: number;
9
+ width?: number | 'auto';
10
+ height?: number | 'auto';
11
+ chartOptions?: BaseOptions;
10
12
  }
11
13
 
12
14
  export default function chartPlugin(context: PluginContext, options: PluginOptions): PluginInfo;