先看看效果展示,实现鼠标点击提示框链接进入跑步详情页面,整体效果 跑步总结。
为了实现提示框可以点击,来回折腾浪费了很长时间,记录下来以备不时之需。
在ECharts的示例编辑里的tooltip
配置项内容:
"tooltip": {
"triggerOn": "click",
"enterable": true,
"formatter":function (params) {
if (params.value[1] <= 3) {
return '';
} else {
return (
'<a href="/posts/run/' + params.value[2] + '/" target="_blank\">' +
params.value[0].slice(-5) +
'</a> <br>' +
Number(params.value[1]).toFixed(2) +
'km '
);
}
}
}
Hugo编译时报如下错误:
Error: error building site: "xx/content/posts/run/run_stats.md:135:1": "xx/layouts/_default/_markup/render-codeblock-echarts.html:6:37": execute of template failed: template: _default/_markup/render-codeblock-echarts.html:6:37: executing "_default/_markup/render-codeblock-echarts.html" at <transform.Unmarshal>: error calling Unmarshal: "_stream.json:5:1": unmarshal failed: invalid character 'u' in literal false (expecting 'a')
Hugo编译时会使用transform.Unmarshal
校验json内容,formmater
的参数内容不符合规范内容。
有事问OpenAI
,js 对象包含函数的序列化
,得到如下的答案。
const obj = {
name: "Alice",
value: {
greet: function() {
console.log("Hello!");
}
}
};
// 自定义序列化函数
function serialize(obj) {
return JSON.stringify(obj, function(key, value) {
if (typeof value === 'function') {
return value.toString();
}
return value;
});
}
// 自定义反序列化函数
function deserialize(serialized) {
return JSON.parse(serialized, function(key, value) {
if (typeof value === 'string' && value.startsWith('function')) {
return eval('(' + value + ')');
}
return value;
});
}
const serialized = serialize(obj);
console.log(serialized);
// 输出: {"name":"Alice","value":{"greet":"function() {\n console.log(\"Hello!\");\n }"}}
const deserialized = deserialize(serialized);
console.log(deserialized);
deserialized.value.greet(); // 输出: Hello!
于是将formmater
的函数内容序列化成字符串。
"tooltip": {
"triggerOn": "click",
"enterable": true,
"formatter":"function (params) {\\n if (params.value[1] <= 3) {\\n return '';\\n } else {\\n return (\\n '<a href=\\"/posts/run/' + params.value[2] + '/\\" target=\\"_blank\\">' +\\n params.value[0].slice(-5) +\\n '</a> <br>' +\\n Number(params.value[1]).toFixed(2) +\\n 'km '\\n );\\n }\\n }"
}
接下来就是修改Hugo集成EChart插件的内容,配置参考Hugo集成ECharts生成心仪的图表
修改/assets/mods/echarts/index.ts
文件,在declare global
下方加入如下代码:
declare global {
interface Window {
echarts: any
}
}
function deserialize(serialized: string): any {
return JSON.parse(serialized, (key: string, value: any) => {
if (typeof value === 'string' && value.startsWith('function')) {
return eval('(' + value + ')');
}
return value;
});
}
(() => {
...
代码可以实现将函数反序列化成对象设置到配置项。需要注意的是序列化和反序列化函数时,要小心安全性问题,尤其是在处理不受信任的输入时,使用 eval
函数可能会带来安全风险。
修改后重新运行Hugo的编译命令。