我正在使用React使用D3v4构建力仿真。但是,只有在对象阵列已经处于我的状态(在本例中为节点)的情况下,并且如果尝试从csv文件读取它并使用setState时,它才能工作。同样在我的Force.js文件中,当我尝试为ForceX设置this.props.width / 2,为ForceY设置this.props.height / 2时,它不起作用,我不得不直接为ForceX输入400 250来让ForceY发挥作用。
如果有人可以向我指出正确的方向,那就太好了!
不使用d3.csv的有效版本:
App.js
import React, { Component } from "react";
import * as d3 from "d3";
import Force from "./Force";
class App extends Component {
state = {
width: 800,
height: 500,
nodes: [
{
"ID": 1,
"name": "Chlamydoselachus africana",
"url": "https://en.wikipedia.org/wiki/Chlamydoselachus_africana",
"common_name": "African frilled shark",
"size": 117,
"family": "Chlamydoselachidae",
"family_common": "Frilled Sharks",
"min_depth": 300,
"max_depth": 1400,
"IUCN": "NA",
"CITES": 0,
"baum": "",
"family_grouped": "Frilled Sharks"
},
{
"ID": 2,
"name": "Chlamydoselachus anguineus",
"url": "https://en.wikipedia.org/wiki/Chlamydoselachus_anguineus",
"common_name": "Frilled shark",
"size": 150,
"family": "Chlamydoselachidae",
"family_common": "Frilled Sharks",
"min_depth": 0,
"max_depth": 1570,
"IUCN": "LC",
"CITES": 0,
"baum": "",
"family_grouped": "Frilled Sharks"
},
{
"ID": 3,
"name": "Heptranchias perlo",
"url": "https://en.wikipedia.org/wiki/Heptranchias_perlo",
"common_name": "Sharp-nose sevengill shark",
"size": 140,
"family": "Hexanchidae",
"family_common": "Cow Sharks",
"min_depth": 0,
"max_depth": 1000,
"IUCN": "NT",
"CITES": 0,
"baum": "",
"family_grouped": "Cow Sharks"
},
{
"ID": 4,
"name": "Hexanchus griseus",
"url": "https://en.wikipedia.org/wiki/Hexanchus_griseus",
"common_name": "Blunt-nose sixgill shark",
"size": 790,
"family": "Hexanchidae",
"family_common": "Cow Sharks"
},
{
"ID": 5,
"name": "Hexanchus nakamurai",
"url": "https://en.wikipedia.org/wiki/Hexanchus_nakamurai",
"common_name": "Bigeyed sixgill shark",
"size": 180,
"family": "Hexanchidae",
"family_common": "Cow Sharks"
},
{
"ID": 6,
"name": "Hexanchus vitulus",
"url": "https://en.wikipedia.org/wiki/Hexanchus_vitulus",
"common_name": "Atlantic sixgill shark",
"size": 220,
"family": "Hexanchidae",
"family_common": "Cow Sharks"
},
{
"ID": 7,
"name": "Notorynchus cepedianus",
"url": "https://en.wikipedia.org/wiki/Notorynchus_cepedianus",
"common_name": "Broad-nose sevengill shark",
"size": 300,
"family": "Hexanchidae",
"family_common": "Cow Sharks"
},
{
"ID": 8,
"name": "Centrophorus atromarginatus",
"url": "https://en.wikipedia.org/wiki/Centrophorus_atromarginatus",
"common_name": "Dwarf gulper shark",
"size": 87,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 9,
"name": "Centrophorus granulosus",
"url": "https://en.wikipedia.org/wiki/Centrophorus_granulosus",
"common_name": "Gulper shark",
"size": 100,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 10,
"name": "Centrophorus harrissoni",
"url": "https://en.wikipedia.org/wiki/Centrophorus_harrissoni",
"common_name": "Dumb gulper shark",
"size": 110,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 11,
"name": "Centrophorus moluccensis",
"url": "https://en.wikipedia.org/wiki/Centrophorus_moluccensis",
"common_name": "Small-fin gulper shark",
"size": 98,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 12,
"name": "Centrophorus seychellorum",
"url": "https://en.wikipedia.org/wiki/Centrophorus_seychellorum",
"common_name": "Seychelles gulper shark",
"size": 80,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 13,
"name": "Centrophorus squamosus",
"url": "https://en.wikipedia.org/wiki/Centrophorus_squamosus",
"common_name": "Leaf-scale gulper shark",
"size": 158,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 14,
"name": "Centrophorus tessellatus",
"url": "https://en.wikipedia.org/wiki/Centrophorus_tessellatus",
"common_name": "Mosaic gulper shark",
"size": 89,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
},
{
"ID": 15,
"name": "Centrophorus uyato",
"url": "https://en.wikipedia.org/wiki/Centrophorus_uyato",
"common_name": "Little gulper shark",
"size": 110,
"family": "Centrophoridae",
"family_common": "Gulper Sharks"
}],
margin:{left:10,top:10,right:10,bottom:10}
};
render() {
return (
<Force width={this.state.width} height={this.state.height} data={this.state.nodes} />
);
}
}
export default App;
Force.js
import React from "react";
import * as d3 from "d3";
import _ from "lodash";
class Force extends React.Component {
constructor(props){
super(props);
var forceSim;
}
componentDidMount() {
var radiusScale = d3.scaleSqrt()
.range([0,0.7]);
this.forceSim = d3.forceSimulation(this.props.data)
.force('x', d3.forceX(function(d) {
return 400
}).strength(0.03))
.force('y', d3.forceY(function(d) {
return 250
}).strength((0.03)))
.force('collide', d3.forceCollide(function(d) {
return radiusScale(+d.size)
})).velocityDecay(0.1).alphaDecay(0.01);
this.forceSim.on('tick', () => this.setState({nodes: this.props.data}));
}
componentWillUnmount() {
this.forceSim.stop();
}
render() {
var colorScale = d3.scaleOrdinal()
.range(['#450303', '#6e0505', '#951f1f'
]);
var radiusScale = d3.scaleSqrt()
.range([0.5,0.9]);
return (
<svg width={this.props.width} height={this.props.height}>
{this.props.data.map((node, index) =>(
<circle r={radiusScale(node.size)} cx={node.x} cy={node.y} fill={colorScale(node.family)} key={index}/>
))}
</svg>
);
}
}
export default Force;
使用d3.csv的版本无效,但我想使其正常工作:
App.js
import React, { Component } from "react";
import * as d3 from "d3";
import Force from "./Force";
import data from './data.csv';
class App extends Component {
state = {
width: 800,
height: 500,
nodes: [],
margin:{left:10,top:10,right:10,bottom:10}
};
componentDidMount() {
d3.csv(data).then(function(data) {
console.log(data)
this.setState(prevState =>({
nodes: data
}))
}).catch(function(err) {
throw err;
})
}
render() {
return (
<Force width={this.state.width} height={this.state.height} data={this.state.nodes} />
);
}
}
export default App;
Force.js
this.forceSim = d3.forceSimulation(this.props.data)
.force('x', d3.forceX(function(d) {
return (this.props.width)/2 ////HERE
}).strength(0.03))
.force('y', d3.forceY(function(d) {
return (this.props.height)/2 ////HERE
}).strength((0.03)))
.force('collide', d3.forceCollide(function(d) {
return radiusScale(+d.size)
})).velocityDecay(0.1).alphaDecay(0.01);
这是csv文件数据:
ID,名称,URL,通用名称,大小,家庭,家庭通用 1,Chlamydoselachus africana,https://en.wikipedia.org/wiki/Chlamydoselachus_africana,African褶边鲨,117,Chlamydoselachidae,褶边鲨 2,Chlamydoselachus anguineus,https://en.wikipedia.org/wiki/Chlamydoselachus_anguineus,Frilled鲨鱼,150,Chlamydoselachachae,褶边鲨鱼 3,Heptranchias perlo,https://en.wikipedia.org/wiki/Heptranchias_perlo,Sharp-nose sevengill shark,140,Hexanchidae,Cow Sharks 4,Hexanchus griseus,https://en.wikipedia.org/wiki/Hexanchus_griseus,Blunt-nose sixgill shark,790,Hexanchidae,Cow Sharks 5,Hexanchus nakamurai,https://en.wikipedia.org/wiki/Hexanchus_nakamurai,Bigeyed Sixgill shark,180,Hexanchidae,Cow Sharks 6,Hexanchus vitulus,https://en.wikipedia.org/wiki/Hexanchus_vitulus,Atlantic Sixgill鲨鱼,220,Hexanchidae,Cow Sharks 7,Notorynchus cepedianus,https://en.wikipedia.org/wiki/Notorynchus_cepedianus,Broad-nose,七g鲨,300,六ch科,牛鲨 8,Centrophorus atromarginatus,https://en.wikipedia.org/wiki/Centrophorus_atromarginatus,Dwarf食尸鲨,87,Centrophoridae,Gulper Sharks 9,Centrophorus granulosus,https://en.wikipedia.org/wiki/Centrophorus_granulosus,Gulper鲨鱼,100,Centrophoridae,Gulper鲨鱼 10,Centrophorus harrissoni,https://en.wikipedia.org/wiki/Centrophorus_harrissoni,Dumb食尸鲨,110,Centrophoridae,Gulper Sharks 11,Centrophorus moluccensis,https://en.wikipedia.org/wiki/Centrophorus_moluccensis,Small-fin食尸鲨,98,Centrophoridae,Gulper Sharks 12,雪松草,https://en.wikipedia.org/wiki/Centrophorus_seychellorum,Seychelles ul鲨,80,C科,G鲨 13,Centrophorus squamosus,https://en.wikipedia.org/wiki/Centrophorus_squamosus,Leaf-scale食尸鲨,158,Centrophoridae,Gulper Sharks 14,中华en(Centrophorus tessellatus),https://en.wikipedia.org/wiki/Centrophorus_tessellatus,Mosaic食尸鲨,89,食蟹科,食尸鲨
答案 0 :(得分:1)
错误在于匿名函数和class
。
这对this
的工作方式有很好的解释:https://stackoverflow.com/a/3127440/5122581
在您的代码中:
this
您使用匿名函数将promise传递给了then回调。该函数没有您期望的d3.csv(data).then(function(data) {
console.log(data)
this.setState(prevState =>({
nodes: data
}))
}).catch(function(err) {
throw err;
})
绑定。有三种解决方案:
this
d3.cvs(data).then((data) => {
this.setState({ nodes: data });
});
创建变量:this
const self = this;
d3.cvs(data).then(function(data) {
self.setState({ nodes: data });
});
由于您已经在使用箭头功能,所以我认为它们是最简洁,优雅的解决方案