d3.js 7.4.4搭配dc.js 4.0.0时图表OnClick事件控制台报错如何解决
问题原因
两个点击报错核心是事件冲突,叠加小版本兼容问题导致的:
- 你直接给三个图表的根容器DOM(
#Country/#WaterType/#Year)绑定了重置筛选的点击事件,当你点击饼图切片、柱状图柱子时,点击事件会向上冒泡到外层容器,先触发你写的filterAll()+redrawAll()逻辑。此时dc内置的点击筛选逻辑正在读取点击元素上绑定的分组数据,但重绘操作已经把旧DOM上绑定的数据集清空了,直接触发Cannot read properties of undefined错误:饼图读不到切片数据的others属性,柱状图读不到柱子数据的key属性,和你控制台看到的报错完全对应。 - dc.js 4.0.0 官方适配的d3版本是6.x系列,你使用的d3.js 7.4.4对事件回调逻辑有小幅调整,会导致内置点击逻辑取数异常,进一步提升报错概率。
修复方案
按以下顺序调整代码即可解决:
- 移除所有直接绑定在图表容器上的点击事件
把原来写在d3.selectAll('#Year')、d3.selectAll('#Country')、d3.selectAll('#WaterType')上的click事件逻辑全部删掉,从根源避免事件冒泡冲突。 - 用独立DOM元素承载重置操作
不要把重置功能绑在图表容器上,单独加独立的按钮元素承载重置逻辑,参考示例:
把原来的重置逻辑绑定到这些独立按钮上:<div class="reset-controls"> <button id="resetAll">重置全部筛选</button> <button id="resetYear">重置年份筛选</button> <button id="resetCountry">重置国家筛选</button> <button id="resetWaterType">重置水体类型筛选</button> </div>
如果一定要实现「点击图表空白区重置筛选」的效果,需要在事件回调里加目标判断,只有点击的是SVG根节点的空白区域、不是切片/柱子/图例这类交互元素时,才触发重置逻辑,避免干扰图表内置的点击筛选。d3.select('#resetAll').on('click', function() { dc.filterAll(); dc.renderAll(); }); d3.select('#resetYear').on('click', function() { yearChart.filterAll(); dc.redrawAll(); }); d3.select('#resetCountry').on('click', function() { CountryChart.filterAll(); dc.redrawAll(); }); d3.select('#resetWaterType').on('click', function() { WaterTypeChart.filterAll(); dc.redrawAll(); }); - 补全配置兼容当前版本
如果你不想调整d3和dc的版本,给两个饼图显式配置othersLabel,给柱状图显式指定x轴domain,避免默认配置读取失败:
更稳妥的版本适配方案是把d3降级到6.x版本,和dc 4.0.0的适配范围完全匹配,从根源避免版本兼容问题。// 两个饼图都加上othersLabel配置 CountryChart .width(220) .height(200) .slicesCap(20) .innerRadius(20) .othersLabel('其他') // 新增配置 .dimension(CountryDim) .group(CountryGroup) .transitionDuration(500); WaterTypeChart .width(220) .height(200) .ordinalColors(['#0096FF', '#40E0D0', '#228B22']) .slicesCap(4) .innerRadius(10) .othersLabel('其他') // 新增配置 .dimension(WaterTypeDim) .group(WaterTypeGroup); // 柱状图x轴scale显式绑定domain yearChart .width(550) .height(350) .dimension(yearDim) .group(yearGroup) .x(d3.scaleBand().domain(yearDim)) // 补全domain配置 .xUnits(dc.units.ordinal) .elasticX(true) .elasticY(true) .brushOn(false) .centerBar(true) .yAxisLabel('Count');
调整完成后刷新页面,点击饼图切片、柱状图柱子即可正常触发交叉筛选,不会再抛出控制台错误,点击重置按钮也能正常清空筛选条件。
内容的提问来源于stack exchange,提问作者Manan Uppadhyay
相关产品推荐
相关产品推荐

