Ember中使用D3绘制饼图时出现'pie is not a function'错误
解决Ember中使用d3-shape的pie函数报错'pie is not a function'的问题
我一眼就揪出了问题的根源——你在pieChart方法里不小心覆盖了导入的pie函数!
错误原因分析
你从d3-shape正确导入了pie函数,但在pieChart方法内部,写了let pie = pie()...这段代码。JavaScript的变量提升机制会让这个局部的pie变量优先级高于模块级导入的pie函数,而在赋值语句的右边,此时局部pie还未被赋值,处于undefined状态,调用pie()自然就会抛出pie is not a function的错误。
修正方案
把局部的pie变量改名,比如改成pieGenerator,避免和导入的函数重名:
pieChart(dataIn, dataIndexIn) { let width = this.get('width'), height = this.get('height'), arc = this.arc(), labelArc = this.labelArc(), color = this.color(), that = this; let data = dataIn; // 重命名变量,避免覆盖导入的pie函数 let pieGenerator = pie() .value(function(d) { return d.count; })(data[dataIndexIn]); let svg = select("#pie-chart") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width/2 + ", " + height/2 + ")"); let g = svg.selectAll("arc") .data(pieGenerator) // 同步更新变量名 .enter().append("g") .attr("class", "arc"); // 后续代码保持不变... }
额外优化建议
- 数据传入问题:你的模拟数据是对象数组,但你调用
pie()时传入的是data[dataIndexIn]——这会取到单个对象,不符合pie函数需要的数组输入。如果dataIndexIn是多余的参数,直接传入dataIn即可:
let pieGenerator = pie() .value(d => d.count)(dataIn);
- Ember最佳实践:把组件里的
radius、color等方法改成计算属性,更符合Ember的设计模式:
radius: Ember.computed('width', 'height', function() { let width = this.get('width'), height = this.get('height'); return Math.min(width, height) / 2; }), color: Ember.computed(function() { return scaleOrdinal().range(['#A60F2B', '#648C85', '#B3F2C9', '#528C18', '#C3F25C']); }), arc: Ember.computed('radius', function() { let radius = this.get('radius'); return arc().outerRadius(radius - 10).innerRadius(0); }), labelArc: Ember.computed('radius', function() { let radius = this.get('radius'); return arc().outerRadius(radius - 40).innerRadius(radius - 40); }),
修改后你的饼图应该就能正常渲染了。
内容的提问来源于stack exchange,提问作者Sorvah
相关产品推荐
相关产品推荐

