feat: 增加 ECharts 渲染与预览交互增强
- 新增可复用的 markdown-echarts 工作区,支持安全的 YAML 围栏、默认值、语义校验、错误占位和 SVG 渲染 - 将 ECharts 接入统一 Markdown、快速预览、精确预览与 PDF 链路,并复用 Mermaid 的不可跨页和超高图单页适配策略 - 默认示例加入 ECharts,增加源文本折叠、顶部文档状态、页码输入跳转与滚动同步 - 快速预览改用外层容器滚动,使滚动条与精确预览统一贴在预览区域右侧,并兼容显示缩放 - 完善 Docker 工作区复制、可配置 Compose 镜像、测试覆盖和进度文档
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import highlightCss from "highlight.js/styles/github.css?inline";
|
||||
import katexCss from "katex/dist/katex.min.css?inline";
|
||||
import echartsCss from "@md-to-pdf/markdown-echarts/styles.css?inline";
|
||||
import type {
|
||||
PagedDocumentRenderResult,
|
||||
PagedDocumentTimings
|
||||
} from "@md-to-pdf/core";
|
||||
import { Previewer } from "pagedjs";
|
||||
import { fitOversizedEChartsToPage } from "./echarts-page-fit";
|
||||
import { createMermaidSiteConfig } from "./mermaid-config";
|
||||
import {
|
||||
fitOversizedMermaidToPage,
|
||||
@@ -82,6 +84,7 @@ function mountMeasurementContainer(
|
||||
documentBaseCss,
|
||||
highlightCss,
|
||||
katexCss,
|
||||
echartsCss,
|
||||
themeCss,
|
||||
documentGeometryCss
|
||||
].join("\n");
|
||||
@@ -159,6 +162,11 @@ export class PagedDocumentRuntime {
|
||||
private mermaidPromise:
|
||||
| Promise<(typeof import("mermaid"))["default"]>
|
||||
| undefined;
|
||||
private echartsPromise:
|
||||
| Promise<
|
||||
typeof import("@md-to-pdf/markdown-echarts/browser")
|
||||
>
|
||||
| undefined;
|
||||
|
||||
constructor(private readonly root: HTMLElement) {}
|
||||
|
||||
@@ -188,6 +196,42 @@ export class PagedDocumentRuntime {
|
||||
return this.mermaidPromise;
|
||||
}
|
||||
|
||||
private loadECharts() {
|
||||
if (!this.echartsPromise) {
|
||||
this.echartsPromise = import(
|
||||
"@md-to-pdf/markdown-echarts/browser"
|
||||
);
|
||||
}
|
||||
return this.echartsPromise;
|
||||
}
|
||||
|
||||
private async renderECharts(
|
||||
container: ParentNode,
|
||||
payload: PagedPreviewPayload
|
||||
) {
|
||||
if (!payload.features.includes("echarts")) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { renderEChartsBlocks } = await this.loadECharts();
|
||||
const outcomes = await renderEChartsBlocks(container, {
|
||||
outputMode: "inline-svg",
|
||||
animation: false,
|
||||
concurrency: 2,
|
||||
timeoutMs: 5_000
|
||||
});
|
||||
|
||||
return outcomes.flatMap((outcome, index) =>
|
||||
outcome.success
|
||||
? []
|
||||
: [
|
||||
`图表 ${index + 1}:${
|
||||
outcome.error?.message ?? "未知错误"
|
||||
}`
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private async renderMermaid(
|
||||
container: DocumentFragment,
|
||||
payload: PagedPreviewPayload
|
||||
@@ -276,9 +320,15 @@ export class PagedDocumentRuntime {
|
||||
const mermaidErrors = await this.renderMermaid(content, payload);
|
||||
const mermaidMs = performance.now() - mermaidStartedAt;
|
||||
|
||||
let echartsErrors: string[] = [];
|
||||
let echartsMs = 0;
|
||||
let echartsFitMs = 0;
|
||||
let mermaidFitMs = 0;
|
||||
let mermaidConversionMs = 0;
|
||||
if (content.querySelector(".mermaid svg")) {
|
||||
if (
|
||||
payload.features.includes("echarts") ||
|
||||
content.querySelector(".mermaid svg")
|
||||
) {
|
||||
const measurement = mountMeasurementContainer(
|
||||
documentRef,
|
||||
content,
|
||||
@@ -287,8 +337,23 @@ export class PagedDocumentRuntime {
|
||||
);
|
||||
try {
|
||||
await documentRef.fonts.ready;
|
||||
|
||||
const echartsStartedAt = performance.now();
|
||||
echartsErrors = await this.renderECharts(
|
||||
measurement.host,
|
||||
payload
|
||||
);
|
||||
echartsMs = performance.now() - echartsStartedAt;
|
||||
await waitForImages(measurement.host);
|
||||
|
||||
const echartsFitStartedAt = performance.now();
|
||||
fitOversizedEChartsToPage(
|
||||
measurement.host,
|
||||
payload.exportConfig
|
||||
);
|
||||
echartsFitMs =
|
||||
performance.now() - echartsFitStartedAt;
|
||||
|
||||
const mermaidFitStartedAt = performance.now();
|
||||
fitOversizedMermaidToPage(
|
||||
measurement.host,
|
||||
@@ -326,6 +391,7 @@ export class PagedDocumentRuntime {
|
||||
stylesheet(documentRef, documentBaseCss, "document-base"),
|
||||
stylesheet(documentRef, highlightCss, "highlight"),
|
||||
stylesheet(documentRef, katexCss, "katex"),
|
||||
stylesheet(documentRef, echartsCss, "echarts"),
|
||||
stylesheet(documentRef, payload.themeCss, "theme"),
|
||||
stylesheet(
|
||||
documentRef,
|
||||
@@ -355,9 +421,12 @@ export class PagedDocumentRuntime {
|
||||
|
||||
return {
|
||||
pageCount: flow.total,
|
||||
echartsErrors,
|
||||
mermaidErrors,
|
||||
timings: {
|
||||
setupMs,
|
||||
echartsMs,
|
||||
echartsFitMs,
|
||||
mermaidMs,
|
||||
mermaidFitMs,
|
||||
mermaidConversionMs,
|
||||
|
||||
Reference in New Issue
Block a user