Feat: add async and data params for echarts shortcode (#592)

This commit is contained in:
Cell
2025-04-28 14:57:58 +08:00
committed by GitHub
parent 3053d889e2
commit 6eb582fef7
4 changed files with 70 additions and 24 deletions
+43 -15
View File
@@ -684,25 +684,53 @@ class FixIt {
this._echartsArr = [];
const stagingDOM = this.util.getStagingDOM()
this.util.forEach(document.getElementsByClassName('echarts'), ($echarts) => {
if ($echarts.nextElementSibling.tagName === 'TEMPLATE') {
const chart = echarts.init($echarts, this.isDark ? 'dark' : 'light', { renderer: 'svg' });
stagingDOM.stage($echarts.nextElementSibling.content.cloneNode(true));
let option;
if ($echarts.nextElementSibling.dataset.fmt === 'js') {
// support JS object literal or JS code
const jsCodes = stagingDOM.contentAsText();
option = new Function(
this.util.isObjectString(jsCodes)
? `return ${jsCodes}`
: `${jsCodes} return option`
)();
} else {
// support JSON
option = stagingDOM.contentAsJson();
const $dataEl = $echarts.nextElementSibling;
if ($dataEl.tagName !== 'TEMPLATE') {
return;
}
const chart = echarts.init($echarts, this.isDark ? 'dark' : 'light', { renderer: 'svg' });
chart.showLoading();
stagingDOM.stage($dataEl.content.cloneNode(true));
const _setOption = (option) => {
if (!option) {
chart.hideLoading();
console.warn('ECharts option is missing or invalid. Chart disposed.', {
element: $echarts,
option: $dataEl,
});
chart.dispose();
$echarts.removeAttribute('style');
return;
}
chart.hideLoading();
chart.setOption(option);
this._echartsArr.push(chart);
};
// support JS object literal or JS code
if ($dataEl.dataset.fmt === 'js') {
try {
const jsCodes = stagingDOM.contentAsText();
/**
* Get ECharts option
* @param {Object} fixit FixIt instance
* @param {Object} chart ECharts instance
* @returns {Object|Promise} ECharts option or Promise
*/
const _getOption = new Function('fixit', 'chart',
this.util.isObjectLiteral(jsCodes) ? `return ${jsCodes}` : jsCodes
);
if ($dataEl.dataset.async === 'true') {
return Promise.resolve(_getOption(this, chart)).then(option => {
_setOption(option);
});
}
return _setOption(_getOption(this, chart));
} catch (err) {
return console.error(err);
}
}
// support JSON
_setOption(stagingDOM.contentAsJson());
});
stagingDOM.destroy();
});
+5 -5
View File
@@ -114,15 +114,15 @@ export default class Util {
/**
* check if a string is a JS object string
* @example isObjectString("{a:1,b:2}") // true
* @param {String} str
* @returns
* @example isObjectLiteral("{a:1,b:2}") // true
* @param {String} str string to check
* @returns {Boolean} whether the string is a JS object string
*/
isObjectString(str) {
isObjectLiteral(str) {
if (typeof str !== 'string') {
return false;
}
str = str.replace(/\s+/g, ' ').trim();
str = str.replace(/\s+/g, ' ').trim().replace(/;$/, '')
if (str.startsWith('{') && str.endsWith('}')) {
return true;
}
+19 -3
View File
@@ -2,14 +2,30 @@
{{- $width := .Options.width | default "100%" -}}
{{- $height := .Options.height | default "30rem" -}}
{{- $js := .Options.js | default false -}}
{{- $async := .Options.async | default false -}}
{{- $data := .Options.data -}}
{{- $attrs := printf `style="width: %v; height: %v;"` $width $height -}}
<div class="echarts" {{ $attrs | safeHTMLAttr }}></div>
{{- $content := strings.TrimSpace .Inner -}}
{{- if $js -}}
{{- $content := strings.TrimSpace .Inner -}}
{{- if hugo.IsProduction -}}
{{- $content = replaceRE `[\s]+` " " $content -}}
{{- end -}}
<template data-fmt="js">{{ $content | safeJS }}</template>
{{- if not $content -}}
{{- warnf "ECharts JS Code is empty, please check the content." -}}
{{- end -}}
<template data-fmt="js" data-async="{{ $async }}">{{ $content | safeJS }}</template>
{{- else -}}
<template>{{ .Inner | transform.Unmarshal | jsonify }}</template>
{{ with $data }}
{{- $content = index site.Data.echarts . -}}
{{- if not $content -}}
{{- warnf "ECharts data not found, please ensure the data file \"/data/echarts/%s.{json|yml|yaml|toml}\" exists." . -}}
{{- end -}}
{{- else -}}
{{- $content = $content | transform.Unmarshal -}}
{{- if not $content -}}
{{- warnf "ECharts option is empty, please check the content." -}}
{{- end -}}
{{- end -}}
<template>{{ $content | jsonify }}</template>
{{- end -}}
+3 -1
View File
@@ -1,5 +1,7 @@
{{- $options := .Get "width" | default (.Get 0) | dict "width" -}}
{{- $options = .Get "height" | default (.Get 1) | dict "height" | merge $options -}}
{{- $options = .Get "js" | default (.Get 2) | dict "js" | merge $options -}}
{{- $options = .Get "js" | default false | dict "js" | merge $options -}}
{{- $options = .Get "async" | default false | dict "async" | merge $options -}}
{{- $options = .Get "data" | dict "data" | merge $options -}}
{{- dict "Options" $options "Inner" .Inner | partial "plugin/echarts.html" -}}
{{- .Page.Store.Set "hasEcharts" true -}}