You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将HTML图例Div添加到mxGraph导出的PNG/SVG顶部?

解决方案:将图例与mxGraph图表一同导出为PNG/SVG

一、导出PNG(结合HTML转Canvas)

因为mxGraph原生导出仅处理自身画布,要合并图例需将图例+图表容器整体转为Canvas再导出,推荐使用html2canvas实现DOM转Canvas:

实现代码

// 假设图例元素为legendDiv,mxGraph容器为graph.container
function exportPNGWithLegend() {
    // 创建临时父容器,用于合并图例和图表
    const tempWrap = document.createElement('div');
    tempWrap.style.width = graph.container.offsetWidth + 'px';
    tempWrap.style.height = (legendDiv.offsetHeight + graph.container.offsetHeight) + 'px';
    tempWrap.style.background = '#ffffff'; // 避免导出透明背景
    tempWrap.style.position = 'relative';
    document.body.appendChild(tempWrap);

    // 将图例和图表移到临时容器内
    tempWrap.appendChild(legendDiv);
    tempWrap.appendChild(graph.container);

    // 转Canvas并导出
    html2canvas(tempWrap).then(canvas => {
        // 触发下载
        const downloadLink = document.createElement('a');
        downloadLink.download = 'chart_with_legend.png';
        downloadLink.href = canvas.toDataURL('image/png');
        downloadLink.click();

        // 恢复原DOM结构
        document.body.appendChild(legendDiv);
        document.body.appendChild(graph.container);
        document.body.removeChild(tempWrap);
    });
}

说明

  • 需要先引入html2canvas库(可通过npm或CDN引入)
  • 临时容器的尺寸要严格匹配图例+图表的总尺寸,避免布局错位
  • 导出完成后必须将元素移回原位置,防止页面结构混乱

二、导出SVG(两种实现方式)

方式1:使用<foreignObject>嵌入图例HTML

直接将图例的HTML结构嵌入到mxGraph导出的SVG中,无需额外依赖:

function exportSVGWithLegend() {
    // 获取mxGraph的SVG字符串
    const graphSvg = graph.getSvg();
    const graphSvgStr = new XMLSerializer().serializeToString(graphSvg);
    const legendHeight = legendDiv.offsetHeight;
    const totalWidth = graphSvg.clientWidth;
    const totalHeight = legendHeight + graphSvg.clientHeight;

    // 克隆图例元素,避免修改原DOM
    const clonedLegend = legendDiv.cloneNode(true);
    const legendHtmlStr = new XMLSerializer().serializeToString(clonedLegend);

    // 构建合并后的SVG
    const combinedSvg = `
        <svg width="${totalWidth}" height="${totalHeight}" xmlns="http://www.w3.org/2000/svg">
            <!-- 嵌入图例HTML -->
            <foreignObject x="0" y="0" width="${totalWidth}" height="${legendHeight}">
                ${legendHtmlStr}
            </foreignObject>
            <!-- 放置mxGraph图表(偏移图例高度) -->
            <g transform="translate(0, ${legendHeight})">
                ${graphSvgStr}
            </g>
        </svg>
    `;

    // 触发SVG下载
    const blob = new Blob([combinedSvg], { type: 'image/svg+xml' });
    const url = URL.createObjectURL(blob);
    const downloadLink = document.createElement('a');
    downloadLink.download = 'chart_with_legend.svg';
    downloadLink.href = url;
    downloadLink.click();
    URL.revokeObjectURL(url);
}

方式2:将图例转为SVG元素(使用dom-to-svg)

若需更好的兼容性,可使用dom-to-svg将图例转为纯SVG元素再合并:

import domtosvg from 'dom-to-svg';

function exportSVGWithLegend() {
    // 获取mxGraph的SVG字符串
    const graphSvg = graph.getSvg();
    const graphSvgStr = new XMLSerializer().serializeToString(graphSvg);
    const legendHeight = legendDiv.offsetHeight;
    const totalWidth = graphSvg.clientWidth;
    const totalHeight = legendHeight + graphSvg.clientHeight;

    // 将图例转为SVG元素
    const legendSvg = domtosvg(legendDiv);
    const legendSvgStr = new XMLSerializer().serializeToString(legendSvg);

    // 构建合并后的SVG
    const combinedSvg = `
        <svg width="${totalWidth}" height="${totalHeight}" xmlns="http://www.w3.org/2000/svg">
            <!-- 放置图例SVG -->
            <g transform="translate(0, 0)">
                ${legendSvgStr}
            </g>
            <!-- 放置mxGraph图表 -->
            <g transform="translate(0, ${legendHeight})">
                ${graphSvgStr}
            </g>
        </svg>
    `;

    // 导出逻辑同方式1
    const blob = new Blob([combinedSvg], { type: 'image/svg+xml' });
    const url = URL.createObjectURL(blob);
    const downloadLink = document.createElement('a');
    downloadLink.download = 'chart_with_legend.svg';
    downloadLink.href = url;
    downloadLink.click();
    URL.revokeObjectURL(url);
}

三、关键注意事项

  1. 样式兼容性:若图例使用外部CSS,需确保样式能被转换工具识别(html2canvas和dom-to-svg优先处理内联样式,复杂样式建议转为内联)
  2. 尺寸匹配:临时容器或SVG的尺寸必须严格匹配图例+图表的实际尺寸,避免导出内容被裁剪
  3. DOM恢复:PNG导出后必须将图例和图表容器移回原位置,防止页面布局异常

内容的提问来源于stack exchange,提问作者M.HUSSAIN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:55:15