如何在Django中通过JS绘制带州界的美国本土48州空白底图
最简实现方案(Django + D3 仅绘制美国州界容器)
前置配置修正
JSON加载失败核心原因是Django静态文件路由规则和普通静态页面不一样,直接写相对路径无法命中服务端路由:
- 在对应Django app目录下创建
static/目录,将us-states.json、D3库文件、自定义JS文件全部存入该目录 - 所用模板顶部添加
{% load static %},所有静态资源引用统一用Django模板标签生成路径,不要手写../这类相对路径 - 调试直接用
python manage.py runserver启动开发服务,确保settings.py中DEBUG=True、STATIC_URL配置正确即可,不需要额外用模块化参数绕开Django路由加载资源。
可直接运行的最简代码
旧教程基于D3 v3编写,API写法、文件加载逻辑均已过时,直接替换为以下无冗余效果的代码即可,仅保留州界绘制能力,预留自定义数据填充入口:
{% load static %} <!-- 提前将下载好的d3.min.js存入static/js目录 --> <script src="{% static 'js/d3.min.js' %}"></script> <!-- 地图专属div容器 --> <div id="us-map-container" style="width: 960px; height: 500px;"></div> <script> async function initBaseMap() { const mapWidth = 960; const mapHeight = 500; // 配置美国本土Albers投影 const projection = d3.geoAlbersUsa() .translate([mapWidth / 2, mapHeight / 2]) .scale(1000); // 地理路径生成器 const pathGenerator = d3.geoPath().projection(projection); // 在指定div内挂载SVG画布 const svg = d3.select("#us-map-container") .append("svg") .attr("width", mapWidth) .attr("height", mapHeight); try { // 加载州界GeoJSON数据 const statesData = await d3.json("{% static 'us-states.json' %}"); // 绘制州界 svg.selectAll("path") .data(statesData.features) .join("path") .attr("d", pathGenerator) .style("stroke", "#ffffff") .style("stroke-width", "1px") .style("fill", "#f0f0f0") // 默认空白底色 // 自定义数据填充逻辑直接写在这里即可 // .style("fill", (feature) => { // 用feature.properties.name匹配你的业务数据,返回对应色值即可 // }) } catch (e) { console.error("底图加载异常:", e); } } // 页面DOM加载完成后初始化地图 document.addEventListener("DOMContentLoaded", initBaseMap); </script>
旧代码存在的明确问题
- D3 v4+版本后,原
d3.geo.path()更名为d3.geoPath(),原回调式d3.json加载改为Promise风格,支持async/await写法,旧写法在新版D3中直接报错 - 原代码中
dataState、dataValue变量未定义,属于旧教程未补全的残留逻辑,不影响基础底图绘制,后续接入业务数据时再补全匹配逻辑即可 - 所有静态资源不要放在模板目录下,必须放入Django识别的static目录,否则开发服务不会对外暴露该文件,必然出现404加载错误。
内容的提问来源于stack exchange,提问作者Zach Rieck
相关产品推荐
相关产品推荐

