gpt4 book ai didi

javascript - 如何使用 React 正确实现 d3 svg click?

转载 作者:行者123 更新时间:2023-12-03 05:00:32 26 4
gpt4 key购买 nike

我正在通过将 d3 map 与 React 集成来创建它。基本上,我有一个 mapchart 组件,可以按照以下方法创建 map : http://bl.ocks.org/herrstucki/9238916

我想通过单击特定的州/州/地区等来使我的 map 可缩放,如下所示 https://bl.ocks.org/mbostock/2206590

所以,基本上我必须在 svg 上添加一个用于 click 的事件处理程序,如调用 clicked() 函数的第二张 map 所示。

我尝试在 React 组件中实现 clicked 函数,如下所示:

 return React.DOM.svg({width: this.props.width, height: this.props.height},
React.DOM.g({
width: this.props.width,
height: this.props.height,
},
React.DOM.path({
className: 'states',
d: path(states),
onClick: this.clicked, // ** added click event here **
}),
React.DOM.path({
className: 'state-borders',
d: path(stateBorders),
})
),
);

但是,在实现单击功能时,我遇到了问题。

  clicked() {
var states = select(ReactDOM.findDOMNode(this)).select('path.states');
var d = states.attr('d'); // ** not what i thought it would be **

var group = select(ReactDOM.findDOMNode(this)).select('g');

var path = geoPath();
var x, y, k;
var centered;

if (d && centered !== d) {
var centroid = path.centroid(d);
console.log(centroid)
x = centroid[0];
y = centroid[1];
k = 4;
centered = d;
} else {
x = this.props.width / 2;
y = this.props.height / 2;
k = 1;
centered = null;
}

group.selectAll("path")
.classed("active", centered && function(d) { return d === centered; });

group.transition()
.duration(750)
.attr("transform", "translate(" + this.props.width / 2 + "," + this.props.height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
.style("stroke-width", 1.5 / k + "px");
}

path.centroid(d) 不起作用,因为 d 的值似乎不是正确的格式,我不确定如何点击状态将突出显示。在正常的 d3 版本中,正确状态和数据格式的 d 似乎隐式传递给函数。如何让我的 React 组件函数执行相同的操作?

最佳答案

首先,正如您发现的那样,states.attr('d')返回路径的 d 属性,即 ...<path d="..." />d map 示例中的 应该是被单击状态的数据,即绑定(bind)到单击的 DOM 元素的数据,而该数据又是您加载的 TopoJSON 文件中的条目。

由于您使用 React 而不是 d3 创建 DOM 节点,因此没有数据绑定(bind)到 DOM 元素。这意味着您必须管理单击的 DOM 节点和相关数据之间的关联。你可以这样做:

React.DOM.path({
className: 'states',
d: path(states),
onClick: this.clicked.bind(this, states), // ** added click event here **
})

这样,states将被传递到clicked()作为它的第一个参数:

function clicked(d) {
// now you have d!
}

但是,仅此方法并不能让您知道单击了哪个实际状态,因为您将所有状态绘制到一个 <path> 中。 。 d3 示例为每个状态创建一条路径,因此当单击路径时,其数据就是该状态的数据对象。要在 React 中等效地执行此操作,您必须循环并创建多个路径。我很难提供正确的代码,因为我不知道 states 的内容。但假设states是 TopoJSON 功能的数组,或多或少应该可以使用以下内容(此处切换到 JSX):

<svg width={this.props.width} height={this.props.height}>  
<g>{
states.map(function (state, i) {
return (<path
className='states'
key={'state_' + i}
d={path(state)}
onClick={this.clicked.bind(this, state)}
</path>)
})
}</g>
</svg>

关于javascript - 如何使用 React 正确实现 d3 svg click?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42245210/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com