自定义图表
import { Chart } from "@lark-ui/core";
import * as echarts from "echarts/core";
import { EChartsOption } from "echarts";
import { useMemo } from "react";
import { useIsDarkMode } from "~/lib/use-is-dark-mode";
export function PieChartDemo() {
const isDarkMode = useIsDarkMode();
const options = useMemo<EChartsOption>(
() => ({
animation: true,
animationDuration: 2000,
tooltip: {
show: true,
},
series: [
{
type: "pie",
data: [
{ value: 101, name: "系列 A" },
{ value: 202, name: "系列 B" },
{ value: 303, name: "系列 C" },
{ value: 404, name: "系列 D" },
{ value: 505, name: "系列 E" },
],
},
],
}),
[],
);
return (
<Chart
echarts={echarts}
options={options}
height={400}
isDarkMode={isDarkMode}
/>
);
}使用 HTML 的自定义工具提示
对于需要自定义 HTML 格式的工具提示(Tooltip),请使用 dangerousHtmlFormatter 属性而不是标准的 formatter。这样可以让安全影响更加明确。
使用 dangerousHtmlFormatter 时,强烈建议使用 echarts.format.encodeHTML 对用户提供的任何内容进行净化处理,以防止 XSS 漏洞。
import { Chart } from "@lark-ui/core";
import * as echarts from "echarts/core";
import { EChartsOption } from "echarts";
import { useMemo } from "react";
import { useIsDarkMode } from "~/lib/use-is-dark-mode";
/**
* 使用 dangerousHtmlFormatter 的 HTML 工具提示自定义图表。
* 谨慎使用:dangerousHtmlFormatter 仅可用于可信的 HTML 内容。
* 请始终使用 echarts.format.encodeHTML 或类似工具对用户提供的数据进行转义,
* 以防止 XSS 漏洞。
*/
export function CustomTooltipChartDemo() {
const isDarkMode = useIsDarkMode();
const options = useMemo<EChartsOption>(
() => ({
tooltip: {
trigger: "item",
formatter: (params: any) => {
// 重要:把所有动态值都用 echarts/format 的 encodeHTML 转义后再放进 HTML。
// 这样可以防止恶意数据引发的 XSS 攻击,例如:
// { name: "<img src=x onerror=alert('xss')>", value: "..." }
const safeName = echarts.format.encodeHTML(params.name);
const safeValue = echarts.format.encodeHTML(String(params.value));
const safePercent = echarts.format.encodeHTML(
String(Math.round(params.percent)),
);
return `
<div style="padding: 8px;">
<div style="font-weight: 600; margin-bottom: 4px;">${safeName}</div>
<div>数值:<strong>${safeValue}</strong></div>
<div style="font-size: 12px; opacity: 0.7; margin-top: 4px;">
占总量的 ${safePercent}%
</div>
</div>
`;
},
},
series: [
{
type: "pie",
data: [
{ value: 101, name: "系列 A" },
{ value: 202, name: "系列 B" },
// 恶意系列名,用于演示 encodeHTML 提供的 XSS 防护。
// 不做编码时它会弹出一个 alert;使用 encodeHTML 后只会安全地显示为纯文本。
{ value: 150, name: "<img src=x onerror=alert('XSS')>" },
{ value: 303, name: "系列 C" },
{ value: 404, name: "系列 D" },
],
},
],
}),
[],
);
return (
<Chart
echarts={echarts}
options={options}
height={400}
isDarkMode={isDarkMode}
/>
);
}