A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {addScript} from "../util/addScript";
2import {Constants} from "../../constants";
3import {hasClosestByClassName} from "../util/hasClosest";
4import {looseJsonParse} from "../../util/functions";
5import {genIconHTML} from "./util";
6
7export const chartRender = (element: Element, cdn = Constants.PROTYLE_CDN) => {
8 let echartsElements: Element[] = [];
9 if (element.getAttribute("data-subtype") === "echarts") {
10 // 编辑器内代码块编辑渲染
11 echartsElements = [element];
12 } else {
13 echartsElements = Array.from(element.querySelectorAll('[data-subtype="echarts"]'));
14 }
15 if (echartsElements.length === 0) {
16 return;
17 }
18 if (echartsElements.length > 0) {
19 addScript(`${cdn}/js/echarts/echarts.min.js?v=5.3.2`, "protyleEchartsScript").then(() => {
20 addScript(`${cdn}/js/echarts/echarts-gl.min.js?v=2.0.9`, "protyleEchartsGLScript").then(() => {
21 const wysiswgElement = hasClosestByClassName(element, "protyle-wysiwyg", true);
22 let width: number = undefined;
23 if (wysiswgElement && wysiswgElement.clientWidth > 0 && echartsElements[0].firstElementChild.clientWidth === 0 && wysiswgElement.firstElementChild) {
24 width = wysiswgElement.firstElementChild.clientWidth;
25 }
26 echartsElements.forEach(async (e: HTMLDivElement) => {
27 if (e.getAttribute("data-render") === "true") {
28 return;
29 }
30 if (!e.firstElementChild.classList.contains("protyle-icons")) {
31 e.insertAdjacentHTML("afterbegin", genIconHTML(wysiswgElement, ["refresh", "edit", "more"]));
32 }
33 const renderElement = e.firstElementChild.nextElementSibling as HTMLElement;
34 if (!e.getAttribute("data-content")) {
35 renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span>`;
36 return;
37 }
38 try {
39 if (!renderElement.lastElementChild || renderElement.childElementCount === 1) {
40 renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div style="height:${e.style.height || "420px"}" contenteditable="false"></div>`;
41 } else {
42 renderElement.lastElementChild.classList.remove("ft__error");
43 }
44 const chartInstance = window.echarts.getInstanceById(renderElement.lastElementChild?.getAttribute("_echarts_instance_"));
45 const option = await looseJsonParse(Lute.UnEscapeHTMLStr(e.getAttribute("data-content")));
46 if (chartInstance) {
47 if (chartInstance.getOption().series[0]?.type !== option.series[0]?.type) {
48 chartInstance.clear();
49 }
50 chartInstance?.resize();
51 }
52 window.echarts.init(renderElement.lastElementChild, window.siyuan.config.appearance.mode === 1 ? "dark" : undefined, {width}).setOption(option);
53 } catch (error) {
54 window.echarts.dispose(renderElement.lastElementChild);
55 renderElement.innerHTML = `<span style="position: absolute;left:0;top:0;width: 1px;">${Constants.ZWSP}</span><div class="ft__error" style="height:${e.style.height || "420px"}" contenteditable="false">echarts render error: <br>${error}</div>`;
56 }
57 e.setAttribute("data-render", "true");
58 });
59 });
60 });
61 }
62};