如何解决使用 dc.js 生成的图表比例返回 NaN
我对 DC/D3 库非常陌生。我试图通过拥有一个单独的纯 JS 文件来将 DC 与 ReactJS 合并,该文件是一个可重用的 D3 组件。我在这里关注这个example。这是我正在使用的虚拟数据: json snippet。
这是我的 App.js:
state = {
data: null,};
componentDidMount() {
console.log("componentDidMount");
d3.json("dummy_data.json").then(data => {
this.setState({data: data});
console.log("Data is updated!");
})
this.createVisualization();
}
componentDidUpdate() {
console.log("componentDidUpdate");
this.updateVisualization();
}
createVisualization = () => {
console.log("createVisualization");
this.visualization = new Dashboard({
parentElement: d3.select(this.node)
});
}
updateVisualization = () => {
this.visualization.updateVis(this.state.data);
console.log("updateVisualization finished");
}
render() {
return (
<div style={{width: '100vw'}} id="app"
ref={node => this.node = node}>
<h1>Hello World!!!</h1>
</div>
)
}
这是我用来生成/渲染图表的 JS 文件 (dashboard.js):
export default class Dashboard {
constructor(_config) {
// setting up based on input config
this.parentElement = _config.parentElement;
this.initVis();
}
initVis() {
let vis = this;
vis.chartContainer = vis
.parentElement
.append("div")
.attr("id","chart-container")
.style("width","100%");
vis.chart = new dc.ScatterPlot("#chart-container");
vis
.chart
.width(768)
.height(480)
.margins({top: 0,right: 10,bottom: 20,left: 50})
.x(d3.scaleLinear())
.elasticX(true)
.elasticY(true)
.brushOn(false) // turn off brush-based range filter
.symbolSize(8) // set dot radius
.clipPadding(10);
const f = vis.chart.x();
console.log(f.domain());
console.log("Finish initVis")
}
updateVis(newData) {
let vis = this;
vis.cf = crossfilter(newData);
console.log(newData);
vis.chart
.on('pretransition',() => {
// console.log(vis)
// const xext = d3.extent(vis.chart.group().all(),d => d.key);
// console.log(newData.map(d => [+d.age,+d.readmission_risk]));
const r = regression.linear(newData.map(d => [d.age,d.readmission_risk]));
const m = r.equation[0],b = r.equation[1];
const [x1,x2] = vis.chart.x().domain();
const points = [
[
x1,m * x1 + b
],[
x2,m * x2 + b
]
];
const xScale = vis.chart.x();
const yScale = vis.chart.y();
const margins = vis.chart.margins();
console.log(xScale(20));
var line = vis.chart.g().selectAll('line.regression').data([points]);
// console.log(vis.chart.x().domain());
function do_points(line) {
line
.attr('x1',d => xScale(d[0][0]) + margins.left)
.attr('y1',d => yScale(d[0][1]) + margins.top)
.attr('x2',d => xScale(d[1][0]) + margins.left)
.attr('y2',d => yScale(d[1][1]) + margins.top);
}
line = line.enter().append('line')
.attr('class','regression')
.call(do_points)
.merge(line);
line.transition().duration(vis.chart.transitionDuration()).call(do_points);
})
vis.renderVis();
}
renderVis() {
let vis = this;
const ageDimension = vis.cf.dimension(d => d.age);
const ageGroup = ageDimension.group();
vis.chart.dimension(ageDimension).group(ageGroup);
vis.chart.render();
console.log("rendering");
}
我已经确定问题是 xScale
方法中回调函数中的 updateVis
。它正在返回 NaN
。但是我尝试在 xScale
中调用 initVis
缩放函数似乎工作正常并返回 [0,1]
。为此,我已经挣扎了很长时间。任何帮助将不胜感激!
更新: 这是我收到的错误消息的快照:
解决方法
感谢您提供可重现的示例。 D3 和 dc.js 代码只是盯着它而不运行它真的很难调试。
这里的问题是散点图期望组键是一个由两个元素组成的数字数组,而不仅仅是一个数字。您可以看到,在您开始的回归示例中,std::optional::emplace
返回一个返回此类键的函数。
相应地更改您的维度:
key_function()
导致图表出现。
我还必须添加示例中的 CSS 才能显示回归线;我创建了 const ageDimension = vis.cf.dimension(d => [d.age,d.readmission_risk] );
:
dashboard.css
并将其添加到 line.regression {
stroke: red;
stroke-width: 5;
opacity: 0.5;
}
:
dashboard.js
结果:
顺便说一句,您计算回归线的方式,在过滤数据时不会更新。如果您希望这样做,这应该可以工作:
import './dashboard.css';
这使用图表组中的键,但仅使用“输入”(值 > 0)过滤的键。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。