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

Svelte中D3可视化图表图片下载失败,求排查解决方案

解决Svelte中D3图表无法下载的问题

问题根源

  1. 序列化的是包含SVG的<div id="chart">而非SVG本身,导致生成的Blob不是有效SVG内容
  2. Canvas未设置与SVG匹配的宽高,绘制时丢失尺寸信息
  3. canvas.toBlob()默认生成PNG格式,但指定保存为JPG,格式不匹配引发下载异常

修改后的代码

App.svelte

<script>
    import Chart from "./Chart.svelte";
    import saveAs from "./FileSaver.min.js";

    function downloadChart() {
        // 选中SVG元素而非外层div
        const svg = document.querySelector("#chart svg");
        const svgString = new XMLSerializer().serializeToString(svg);
        const canvas = document.createElement("canvas");
        // 设置canvas宽高与SVG一致
        canvas.width = svg.getAttribute("width");
        canvas.height = svg.getAttribute("height");
        const ctx = canvas.getContext("2d");
        const data = new Blob([svgString], {type: "image/svg+xml"});
        const url = URL.createObjectURL(data);
        const img = new Image();
        
        // 跨域兼容处理(测试用例无需,但保留更稳妥)
        img.crossOrigin = "anonymous";
        
        img.onload = () => {
            ctx.drawImage(img, 0, 0);
            // 指定生成JPG格式,第二个参数为质量(0-1)
            canvas.toBlob((blob) => {
                saveAs(blob, "chart.jpg");
                // 释放URL对象,避免内存泄漏
                URL.revokeObjectURL(url);
            }, "image/jpeg", 0.9);
        };
        img.src = url;
    }
</script>

<Chart/>
<button on:click={downloadChart}>Download Image</button>

Chart.svelte(无需修改,确保SVG宽高属性正确即可)

<script>
    import { onMount } from "svelte";
    import * as d3 from "d3";

    let data = [10, 20, 30, 40, 50];

    onMount(() => {
        const svg = d3
            .select("#chart")
            .append("svg")
            .attr("width", 500)
            .attr("height", 500);

        svg
            .selectAll("rect")
            .data(data)
            .enter()
            .append("rect")
            .attr("x", (d, i) => i * 50)
            .attr("y", (d, i) => 500 - d)
            .attr("width", 50)
            .attr("height", (d) => d)
            .attr("fill", "teal");
    });
</script>

<div id="chart" />

关键修改说明

  • 目标元素修正:改为选中SVG元素,确保序列化内容为纯SVG格式
  • 尺寸同步:让Canvas宽高与SVG一致,保证绘制的图表尺寸准确
  • 格式匹配:明确指定canvas.toBlob()生成JPG格式,与保存文件名对应
  • 内存清理:下载完成后释放URL对象,避免内存泄漏

内容的提问来源于stack exchange,提问作者sprucegoose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:16:14