CodePen运行FreeCodeCamp柱状图项目报错d3 is not defined
D3库CodePen运行报错
ReferenceError: d3 is not defined 解决方案 - 修正D3库引入地址与版本
你当前引入的是D3 v3版本且使用http协议,存在两个问题:
- 你代码中使用的
d3.scaleLinear、d3.axisBottom等API是D3 v4及以上版本才支持的接口,v3版本无对应实现 - CodePen是HTTPS站点,会主动拦截HTTP协议的外部资源加载,导致库引入失效
正确的引入方式不要直接在代码中写script标签,走CodePen平台配置即可:
- 打开项目右上角「Settings」
- 切换到「JS」标签栏
- 在外部脚本输入框填入D3 v7官方CDN地址:
https://d3js.org/d3.v7.min.js - 点击添加后保存设置即可
- 你代码中使用的
- 调整代码执行顺序与错误参数
你当前代码第一行就执行let svg = d3.select('svg'),如果D3库还未加载完成就执行该语句,依然会触发未定义报错,同时你请求数据的URL中间多余空格也会导致请求失败,修改后的完整代码如下:
let url = 'https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json' let req = new XMLHttpRequest() let data let values =[] let heightScale let xScale let xAxisScale let yAxisScale let xAxis let yAxis let svg // 仅声明变量,等库与DOM加载完成后再赋值 let width = 800 let height = 600 let padding = 40 let generateScales = () => { heightScale = d3.scaleLinear() .domain([0, d3.max(values, (item) => { return item[1] })]) .range([0, height-(2 * padding)]) xScale = d3.scaleLinear() .domain([0, values.length-1]) .range([padding, width-padding]) } let drawCanvas = () => { svg.attr('width', width) svg.attr('height', height) } let drawBars = () => { let tooltip = d3.select('body').append('div') .attr('id', 'tooltip') .style('visibility', 'hidden') svg.selectAll('rect') .data(values) .enter() .append('rect') .attr('class', 'bar') .attr('height', (item) => { return heightScale(item[1]) }) .attr('width', (width - (2*padding)) / values.length) .attr('x', (item, index) => { return xScale(index) }) .attr('y', (item) => { return (height-padding) - heightScale(item[1]) }) .attr('data-date', (item) => { return item[0] }) .attr('data-gdp', (item) => { return item[1] }) .on('mouseover', (item) => { tooltip.transition() .style('visibility', 'visible') document.querySelector('#tooltip').setAttribute('data-date', item[0]) document.querySelector('#tooltip').textContent = item[0] }) .on('mouseout', (d) => { tooltip.transition() .style('visibility', 'hidden') }) } let generateAxes = () => { let dateArray = values.map((item) => { return new Date(item[0]) }) xAxisScale = d3.scaleTime() .domain([d3.min(dateArray), d3.max(dateArray)]) .range([padding, width-padding]) yAxisScale = d3.scaleLinear() .domain([0, d3.max(values, (item) => { return item[1] })]) .range([height-(2 * padding), 0]) xAxis = d3.axisBottom(xAxisScale) yAxis = d3.axisLeft(yAxisScale) svg.append('g') .call(xAxis) .attr('id', 'x-axis') .attr('transform', 'translate(0, '+ (height - padding) + ')') svg.append('g') .call(yAxis) .attr('id', 'y-axis') .attr('transform', 'translate(' + padding + ', ' + padding + ')') } req.open('GET', url, true) req.onload = () => { data = JSON.parse(req.responseText) values = data['data'] svg = d3.select('svg') // 确认资源加载完成后再操作DOM generateScales() drawCanvas() drawBars() generateAxes() } req.send()
内容的提问来源于stack exchange,提问作者gatwirival
相关产品推荐
相关产品推荐

