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

使用d3.js的HTML本地打开无图表问题求助

本地直接打开D3.js HTML文件无法加载图表的解决办法

问题情况

  • 通过VS Code的Live Server打开HTML文件时,D3.js生成的图表显示正常
  • 直接双击本地HTML文件打开时,图表无法生成
  • 已尝试在CSV数据路径前添加./,问题仍未解决

相关代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Proyecto II</title>
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <style>
        .bar {
            fill: url(#gradient);
            stroke: #fff;
        }
        .label {
            font-size: 10px;
            text-anchor: middle;
        }
        .center-label {
            font-size: 14px;
            text-anchor: middle;
            font-weight: bold;
        }
        .legend {
            font-size: 12px;
        }
        .legend rect {
            stroke: none;
        }
        .legend text {
            fill: #000;
            font-weight: bold;
            alignment-baseline: middle;
        }
    </style>

</head>
<body>
    <h1>Sundown Chart</h1>
    <p>Shows population of each city</p>
    <div id="chart2"></div>
    <div id="chart1"></div>

<script>
    const dataUrl = "./files/distritos.csv";

    d3.csv(dataUrl).then(function(data) {
        data.forEach(d => {
            d.POPULATION = +d.POPULATION;
        });

        const width = 800;
        const height = 400;
        const radius = Math.min(width, height * 2) / 2;

        const groupedData = d3.group(data, d => d.ID.split('.')[0]);

        const colorScale = d3.scaleOrdinal()
            .domain(groupedData.keys())
            .range(d3.schemeCategory10);

        const radialScale = d3.scaleLinear()
            .domain([0, d3.max(data, d => d.POPULATION)])
            .range([0, radius]);

        const arc = d3.arc()
            .innerRadius(0)
            .outerRadius(d => radialScale(d.data.POPULATION));

        const pie = d3.pie()
            .sort(null)
            .value(d => d.POPULATION)
            .startAngle(-Math.PI / 2)
            .endAngle(Math.PI / 2);

        const svg1 = d3.select("#chart1").append("svg")
            .attr("width", width)
            .attr("height", height + 50);

        const g1 = svg1.append("g")
            .attr("transform", `translate(${width / 2}, ${height})`);

        const gArcs1 = g1.selectAll(".arc")
            .data(pie(data))
            .enter().append("g")
            .attr("class", "arc");

        gArcs1.append("path")
            .attr("d", arc)
            .style("fill", d => colorScale(d.data.ID.split('.')[0]));

        gArcs1.append("text")
            .attr("transform", function(d) {
                const [x, y] = arc.centroid(d);
                const midAngle = (d.startAngle + d.endAngle) / 2;
                const offset = midAngle < Math.PI ? 1 : -1;
                return `translate(${x * 1.1 * offset}, ${y * 1.1 * offset})`;
            })
            .attr("dy", ".35em")
            .attr("class", "label")
            .text(d => d.data.CITY);

        const svg2 = d3.select("#chart2").append("svg")
            .attr("width", width)
            .attr("height", height + 50);

        const g2 = svg2.append("g")
            .attr("transform", `translate(${width / 2}, ${height})`);

        const gArcs2 = g2.selectAll(".arc")
            .data(pie(data))
            .enter().append("g")
            .attr("class", "arc");

        gArcs2.append("path")
            .attr("d", arc);

        gArcs2.append("text")
            .attr("transform", function(d) {
                const [x, y] = arc.centroid(d);
                const midAngle = (d.startAngle + d.endAngle) / 2;
                const offset = midAngle < Math.PI ? 1 : -1;
                return `translate(${x * 1.1 * offset}, ${y * 1.1 * offset})`;
            })
            .attr("dy", ".35em")
            .attr("class", "label")
            .text(d => d.data.CITY);
    });
</script>
</body>
</html>

问题原因

直接本地打开文件时,浏览器使用file://协议访问资源,出于安全限制,浏览器会阻止JavaScript读取本地文件(比如你的CSV),而Live Server是通过http://协议提供服务,不存在这个跨域限制,所以能正常加载数据生成图表。

解决办法

1. 启用浏览器本地文件访问权限(Chrome为例)

  • 关闭所有Chrome窗口
  • 右键点击Chrome快捷方式,选择「属性」
  • 在「目标」栏末尾添加 --allow-file-access-from-files(注意前面有空格)
  • 启动Chrome,再打开本地HTML文件即可加载CSV数据

2. 将CSV数据内嵌到HTML中

如果数据量不大,可以直接把CSV内容转换成JSON格式,内嵌到JavaScript代码里,避免文件读取操作:

// 替换原来的d3.csv(dataUrl).then(...)部分
const data = [
    {ID: "1.1", CITY: "城市1", POPULATION: 100000},
    {ID: "1.2", CITY: "城市2", POPULATION: 150000},
    // 这里添加所有CSV数据行
];
// 后面的图表生成代码保持不变

3. 使用本地服务器(推荐)

继续使用VS Code的Live Server,或者用其他简单的本地服务器:

  • Python 3:在项目目录打开终端,运行 python -m http.server 8000,然后访问http://localhost:8000/你的文件名.html
  • Node.js:安装http-server包后,运行http-server,访问对应地址

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:05:05