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

Django集成d3.js折线图不显示 如何正确添加HTML SVG对象

问题定位

代码存在3个核心问题导致折线图无法展示:

  • 前置冗余代码错误:提前编写的SVG初始化逻辑里,错误使用append("chart")创建了无效的自定义标签(SVG根节点标签必须为svg),且这部分逻辑和LineChart函数内部的SVG创建逻辑完全重复,属于无效代码。
  • 图表节点未挂载到DOM:LineChart函数执行后返回了生成好的SVG节点,但没有将节点插入到页面的#chart容器中,浏览器不会渲染不在DOM树里的节点。
  • 测试数据异常:测试用的aapl数组中存在两条完全相同的Date时间戳,会导致折线绘制出现重叠折返,虽不阻断渲染但不符合时序数据规范。
修复步骤
  1. 删除所有前置冗余的SVG初始化代码(即从// set the dimensions and margins of the graph开始到translate偏移的<g>节点创建的全部代码),LineChart函数已经完整封装了SVG创建、边距计算、坐标轴绘制的全流程,无需额外提前初始化。
  2. 在LineChart调用完成拿到chart节点后,添加挂载逻辑,将节点插入到#chart容器内。
  3. 修正测试数据中重复的时间戳,保证x轴时序值唯一。
修复后完整代码
{% load static %}
<html>
<script src="https://d3js.org/d3.v6.js"></script>
<body> 
    <h1> Hello! </h1>
    <div id="chart"></div>
</body>

<script>
    // Copyright 2021 Observable, Inc.
    // Released under the ISC license.
    function LineChart(data, {
    x = ([x]) => x,
    y = ([, y]) => y,
    defined,
    curve = d3.curveLinear,
    marginTop = 20,
    marginRight = 30,
    marginBottom = 30,
    marginLeft = 40,
    width = 640,
    height = 400,
    xType = d3.scaleUtc,
    xDomain,
    xRange = [marginLeft, width - marginRight],
    yType = d3.scaleLinear,
    yDomain,
    yRange = [height - marginBottom, marginTop],
    yFormat,
    yLabel,
    color = "currentColor",
    strokeLinecap = "round",
    strokeLinejoin = "round",
    strokeWidth = 1.5,
    strokeOpacity = 1,
    } = {}) {
    const X = d3.map(data, x);
    const Y = d3.map(data, y);
    const I = d3.range(X.length);
    if (defined === undefined) defined = (d, i) => !isNaN(X[i]) && !isNaN(Y[i]);
    const D = d3.map(data, defined);

    if (xDomain === undefined) xDomain = d3.extent(X);
    if (yDomain === undefined) yDomain = [0, d3.max(Y)];

    const xScale = xType(xDomain, xRange);
    const yScale = yType(yDomain, yRange);
    const xAxis = d3.axisBottom(xScale).ticks(width / 80).tickSizeOuter(0);
    const yAxis = d3.axisLeft(yScale).ticks(height / 40, yFormat);

    const line = d3.line()
        .defined(i => D[i])
        .curve(curve)
        .x(i => xScale(X[i]))
        .y(i => yScale(Y[i]));

    const svg = d3.create("svg")
        .attr("width", width)
        .attr("height", height)
        .attr("viewBox", [0, 0, width, height])
        .attr("style", "max-width: 100%; height: auto; height: intrinsic;");

    svg.append("g")
        .attr("transform", `translate(0,${height - marginBottom})`)
        .call(xAxis);

    svg.append("g")
        .attr("transform", `translate(${marginLeft},0)`)
        .call(yAxis)
        .call(g => g.select(".domain").remove())
        .call(g => g.selectAll(".tick line").clone()
            .attr("x2", width - marginLeft - marginRight)
            .attr("stroke-opacity", 0.1))
        .call(g => g.append("text")
            .attr("x", -marginLeft)
            .attr("y", 10)
            .attr("fill", "currentColor")
            .attr("text-anchor", "start")
            .text(yLabel));

    svg.append("path")
        .attr("fill", "none")
        .attr("stroke", color)
        .attr("stroke-width", strokeWidth)
        .attr("stroke-linecap", strokeLinecap)
        .attr("stroke-linejoin", strokeLinejoin)
        .attr("stroke-opacity", strokeOpacity)
        .attr("d", line(I));

    return svg.node();
    };

    const aapl = [
       {
         "Date": 1641081600000,
         "Close": 182.01
       },
       {
         "Date": 1641168000000,
         "Close": 179.7
       },
       {
         "Date": 1641254400000,
         "Close": 174.92
       },
    ];

    const chart = LineChart(aapl, {
        x: d => d.Date,
        y: d => d.Close,
        yLabel: "↑ Daily close ($)",
        width: 400,
        height: 500,
        color: "steelblue"
    })
    // 挂载图表到页面容器
    document.querySelector("#chart").appendChild(chart)
</script>
</html>

修复后直接运行即可正常渲染折线图,后续替换真实接口返回的时序数据就能正常使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:06:27