繁体   English   中英

React + D3:如何访问对象的状态和道具? (在事件触发的函数内)a

[英]React + D3: How can I access to the state and props of the object? (Inside a function fired by an event)a

我是 D3 的新手,我想创建一个散点图,当我将鼠标放在一个点上时,我想在该点附近显示一个文本,如工具提示。

我可以更改点的颜色,但我无法访问 React Object 的状态,因为出现错误:

在此处输入图片说明

之前我设置状态的代码是这样的:

componentDidMount(){
    let canvas = this.setCanvas();
    let scales = this.setScales(this.props.data);
    this.setState({
        canvas: canvas,
        scales: scales
    }, () => {
        this.setAxesToCanvas(canvas, scales);
        this.setPointsToCanvas(canvas, this.props.data, scales);    
    });
}

setCanvas 方法返回一个 svg:

setCanvas(){
    // Add the visualization svg canvas to the container <div>
    let svg = d3.select("#" + this.props.idContainer)
    .append("svg")
    .style("background-color", "#354560")
    .style("color", "#FFFFFF")  //With this we've got the color of the axis too
    .attr("height", this.state.height)
    .attr("width", this.state.width);

    return svg;  
}

而 setScales 返回一个 json 对象:

setScales(data){ 
    let xRange = [this.state.margin.left, this.state.width - this.state.margin.right];
    let yRange = [this.state.margin.top, this.state.height - this.state.margin.top - this.state.margin.bottom]; // flip order because y-axis origin is upper LEFT  

    let xScale = d3.scaleLinear()
    .domain([ d3.min(data, d => parseFloat(d.value_x)) - 1, d3.max(data, d => parseFloat(d.value_x)) + 1])
    .range(xRange);

    let yScale = d3.scaleLinear()
    .domain([ d3.max(data, d => parseFloat(d.value_y)) + 1, d3.min(data, d => parseFloat(d.value_y)) - 1])
    .range(yRange);       

    return {"xScale" : xScale, "yScale" : yScale, "xRange" : xRange, "yRange" : yRange};
}

设置状态后,我调用函数 setAxesToCanvas 和 setPointsToCanvas。 这是我定义的最后一个函数,用于捕捉甚至“onMouseOver”如何看到:

setPointsToCanvas(canvas, data){
    let xRange = [this.state.margin.left, this.state.width - this.state.margin.right];
    let yRange = [this.state.margin.top, this.state.height - this.state.margin.top - this.state.margin.bottom]; // flip order because y-axis origin is upper LEFT  

    let xScale = d3.scaleLinear()
    .domain([ d3.min(data, d => parseFloat(d.value_x)) -1, d3.max(data, d => parseFloat(d.value_x)) + 1])
    .range(xRange);

    let yScale = d3.scaleLinear()
    .domain([ d3.max(data, d => parseFloat(d.value_y)) + 1, d3.min(data, d => parseFloat(d.value_y)) - 1])
    .range(yRange);

    canvas.selectAll("circle")
    .data(data)
    .enter().append("circle")
    .attr("class", "dot")
    .attr("r", 5.5)     //Radius size, could map to another dimension
    .attr("cx", function(d) { return xScale(parseFloat(d.value_x)); })  //x position
    .attr("cy", function(d) { return yScale(parseFloat(d.value_y)); })  //y position
    .style("fill", "#FFC107")
    .on("mouseover", this.tipMouseOver);

}

我在事件触发时调用的方法是 tipMouseOver ,它的代码是:

tipMouseOver(data, iter){
    // Use D3 to select element, change color and size
    d3.select(this)
    .style("fill", "green")
    .style("radius", "5 em");

    // Specify where to put label of text
    console.log("Before to set the text - data: " + data + " iter: " + iter);
    this.state.canvas.append("text").attr({
        id: "t" + data.value_x + "-" + data.value_y + "-" + iter,  // Create an id for text so we can select it later for removing on mouseout
            x: function() { return this.state.scales.xScale(data.value_x) - 30; },
            y: function() { return this.state.scales.yScale(data.value_y) - 15; }
        })
        .text(function() {
        return [data.value_x, data.value_y];  // Value of the text
        });        
} 

您如何在屏幕截图中看到所有内容都已执行,直到到达该行

this.state.canvas.append("text")

如果我尝试将画布和缩放比例传递给事件发生时触发的方法

.on("mouseover", this.tipMouseOver(canvas, scales));

我修改了函数...

tipMouseOver(data, iter, canvas, scales){
....
}

但是当我重新加载页面时,我收到了这个错误:

在此处输入图片说明

我已经检查过我也无法访问反应对象的道具。

因此,如何访问对象的状态和道具以获取画布和比例?

编辑我:

我在代码沙盒中添加代码:

编辑 React + D3:如何访问对象的状态和道具? (在事件触发的函数内)

我在这里解决了您想要实现的目标,但没有解决您提出的问题,即在事件中访问状态和道具。 但我想你会发现FreeCodeCamp组件函数很有用。

关于鼠标事件,我将它们移动到setPointsToCanvas函数中,以便它们可以访问画布和缩放。 之后,它应该是直截了当的。 希望这可以帮助 !

是的,您需要像 React 文档中那样使用 .bind 将函数绑定到“this”。 但是我遇到的问题是我的 D3 图表有一个构建函数,在这个构建函数中,我在构建函数中定义了 d3 定向事件侦听器和处理程序。

我注意到在这个函数内部,如果我曾经尝试访问 this.state(反应状态)或使用 this.setState 更新反应状态,它会告诉我它不存在。 我尝试使用箭头函数,但最终仍会导致问题。 我通过在事件侦听器函数的顶部设置 var self = this; 正确定义“this”解决了我的问题; 然后我可以说 self.state.something 并通过说 self.setState({something: newthing}) 来访问 react setState 函数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM