Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3移动时电刷滞后_Javascript_Reactjs_D3.js - Fatal编程技术网

Javascript D3移动时电刷滞后

Javascript D3移动时电刷滞后,javascript,reactjs,d3.js,Javascript,Reactjs,D3.js,使用react绘制D3图表。我已经在d3中实现了一个笔刷 当我滚动画笔时,它可以很好地工作,但它是滞后的。有趣的是,如果我删除下面(在NavChart.js中)标记为problemble的行,笔刷就会开始正常工作(没有延迟)。但是,这一行很重要,因为我使用react hook更新ChartWrapper.js(称为“selection”)中的变量,我需要将图表与nav连接起来。 代码如下: ChartWrapper.js-> import React, {useRef, useEffect, u

使用react绘制D3图表。我已经在d3中实现了一个笔刷

当我滚动画笔时,它可以很好地工作,但它是滞后的。有趣的是,如果我删除下面(在NavChart.js中)标记为problemble的行,笔刷就会开始正常工作(没有延迟)。但是,这一行很重要,因为我使用react hook更新ChartWrapper.js(称为“selection”)中的变量,我需要将图表与nav连接起来。 代码如下:

ChartWrapper.js->

import React, {useRef, useEffect, useState, useImperativeHandle} from 'react';
import  {select, selectAll, extent, axisBottom, axisLeft, scaleLinear, scaleTime, curve, line, curveCardinal, set} from 'd3';
import Chart from './Chart';
import NavChart from './NavChart';
import UsePrevious from './UsePrevious';

const MARGIN = {TOP: 50, BOTTOM: 50, LEFT: 50, RIGHT: 50};
const maxData = 10;
export default function ChartWrapper(props) {

    let [selection, setSelection] = useState([props.data[0].time, props.data[1].time]);
    const previousSelection = UsePrevious(selection);
    let [first, setFirst] = useState(true);
    const svgRef = useRef();
    let chart = null;
    let nav = null;
    const navRef = useRef();    

    useEffect(
        () => {
                console.log(`selection is : ${selection}`);
                //Chart component
                chart = new Chart(MARGIN, svgRef, props.data, props.xAxisText, props.yAxisText);
                // navigation component (Both aren't connected right now)
                nav = new NavChart(MARGIN, navRef, props.data, previousSelection.current, selection, setSelection, first);
                setFirst(false);


        }, [props.data, previousSelection, selection, first]        
    );

    return (
        <div>
            <svg ref = {svgRef} width = {700} height = {400}></svg>
            <br /><br/>
            <svg ref = {navRef} width = {700} height = {75}></svg>
        </div>
    );
}
import-React,{useRef,useffect,useState,useImperialiveHandle}来自'React';
从'd3'导入{select,selectAll,extent,axisBottom,axisLeft,scaleLinear,scaleTime,curve,line,curveCardinal,set};
从“./Chart”导入图表;
从“/NavChart”导入NavChart;
从“/UsePrevious”导入UsePrevious;
常量边距={TOP:50,BOTTOM:50,LEFT:50,RIGHT:50};
常数maxData=10;
导出默认函数ChartWrapper(道具){
让[selection,setSelection]=useState([props.data[0]。时间,props.data[1]。时间];
const previousSelection=使用先前(选择);
let[first,setFirst]=useState(true);
const svgRef=useRef();
设chart=null;
设nav=null;
const navRef=useRef();
使用效果(
() => {
log(`selection is:${selection}`);
//图表组件
图表=新图表(边距、svgRef、props.data、props.xAxisText、props.yAxisText);
//导航组件(两个组件目前未连接)
导航=新导航图表(边距、导航参考、道具数据、上一个选择、当前选择、设置选择、第一);
setFirst(假);
},[props.data,上一个选择,选择,第一个]
);
返回(


); }
NavChart.js->

import {select,
    selectAll,
    extent,
    axisBottom,
    axisLeft,
    scaleLinear,
    scaleTime,
    line,
    brushX,
    event
} from 'd3';

const PADDING = {TOP: 10, BOTTOM: 30};

export default class NavChart {
    constructor(MARGIN, svgRef, data, previousSelection, selection, setSelection, firstTime) {

        this.svg = select(svgRef.current);
        this.MARGIN = MARGIN;
        this.data = data;

        this.chartWidth = this.svg.attr('width') - MARGIN.LEFT - MARGIN.RIGHT;
        this.chartHeight = this.svg.attr('height') - PADDING.TOP - PADDING.BOTTOM;

        this.xScale = scaleTime()
                        .domain(extent(
                            this.data.map((d) => d.time)
                        ))
                        .range([0, this.chartWidth]);

        this.yScale = scaleLinear()
                        .domain(extent(
                            this.data.map((d) => d.value)
                        ))
                        .range([this.chartHeight, 0]);

        this.myLine = line()
                        .x((d) => this.xScale(d.time))
                        .y((d) => this.yScale(d.value));

        this.chartArea = this.svg.append('g')
                        .attr('transform', `translate(${MARGIN.LEFT}, ${PADDING.TOP})`);

        this.chartArea.append('rect')
                        .attr('x', 0)
                        .attr('y', 0)
                        .attr('width', this.chartWidth)
                        .attr('height', this.chartHeight)
                        .attr('fill', '#f2f2f2');

        this.pathsG = this.chartArea.append('g')
                        .attr('class', 'pathsG')
                        .attr('transform', `translate(0,0)`);

        this.xAxis = axisBottom(this.xScale);

        this.xAxisG = this.chartArea.append('g')
                                       .attr('transform', `translate(0, ${this.chartHeight})`);

        this.xAxisG.call(this.xAxis);

        this.pathsG.selectAll('path')
            .data([this.data])
            .join('path')
            .attr('d', (value) => this.myLine(value))
            .attr('fill', 'none')
            .attr('stroke', '#D073BA')
            .attr('stroke-width', '1.5');

        this.circlesVar = this.pathsG.selectAll('.circle')
            .data(data);

        this.circlesVar.enter().append('circle')
            .attr('class', 'circle')
            .attr('r', '3')/*(value) => 
                    value.time > selection[0] && value.time <= selection[1] ? 4 : 2)*/
            .style('fill', '#D073BA')
            .attr('cx', (d) => this.xScale(d.time))
            .attr('cy', (d) => this.yScale(d.value));

        this.brushG = this.chartArea.append('g')
                        .attr('class', 'brush');

        this.brush = brushX().extent([
            [0, 0],
            [this.chartWidth, this.chartHeight]
        ]).on('start brush end', () => {
            if (event.selection  && (event.sourceEvent != null)) {
                const timeSelection = event.selection.map(this.xScale.invert);
                setSelection(timeSelection);    // This line is problematic
            }
        });
         this.brushG.call(this.brush)
                        .call(this.brush.move, selection.map(this.xScale));
    }
}
import{select,
选择全部,
范围,
在底部,
左,,
标线,
缩放时间,
行,,
灌木丛,
事件
}从'd3'开始;
常量填充={TOP:10,BOTTOM:30};
导出默认类导航图{
构造函数(边距、svgRef、数据、以前的选择、选择、设置选择、第一次){
this.svg=select(svgRef.current);
这个。保证金=保证金;
这个数据=数据;
this.chartWidth=this.svg.attr('width')-MARGIN.LEFT-MARGIN.RIGHT;
this.chartHeight=this.svg.attr('height')-PADDING.TOP-PADDING.BOTTOM;
this.xScale=scaleTime()
.域(范围)(
this.data.map((d)=>d.time)
))
.范围([0,此.chartWidth]);
this.yScale=scaleLinear()
.域(范围)(
this.data.map((d)=>d.value)
))
.范围([this.chart height,0]);
this.myLine=line()
.x((d)=>此.xScale(d.time))
.y((d)=>该.yScale(d.value));
this.charterea=this.svg.append('g'))
.attr('transform','translate(${MARGIN.LEFT},${PADDING.TOP})`);
this.chartArea.append('rect')
.attr('x',0)
.attr('y',0)
.attr('width',this.chartWidth)
.attr('height',this.chartHeight)
.attr('fill','#f2f2');
this.pathsG=this.chartArea.append('g'))
.attr('class','pathsG')
.attr('transform','translate(0,0)`);
this.xAxis=axisBottom(this.xScale);
this.xAxisG=this.chartArea.append('g'))
.attr('transform','translate(0,${this.chartHeight})`);
this.xAxis.call(this.xAxis);
this.pathsG.selectAll('path'))
.data([this.data])
.join('路径')
.attr('d',(值)=>此.myLine(值))
.attr('填充','无')
.attr('stroke','#D073BA')
.attr('stroke-width','1.5');
this.circlesVar=this.pathsG.selectAll(“.circle”)
.数据(数据);
this.circlesVar.enter().append('circle'))
.attr('class','circle')
.attr('r','3')/*(值)=>
value.time>选择[0]&&value.time此.xScale(d.time))
.attr('cy',(d)=>此.yScale(d.value));
this.brushG=this.chartArea.append('g'))
.attr('class','brush');
this.brush=brushX().extent([
[0, 0],
[this.chartWidth,this.chartHeight]
]).on('开始画笔结束',()=>{
if(event.selection&(event.sourceEvent!=null)){
const timeSelection=event.selection.map(this.xScale.invert);
setSelection(timeSelection);//此行有问题
}
});
this.brush.call(this.brush)
.call(this.brush.move,selection.map(this.xScale));
}
}
我知道对选择变量的更改(通过NavChart.js中的setSelection方法)将触发ChartWrapper.js中的useEffect()钩子,但我不知道为什么会导致延迟。我需要向笔刷添加过渡吗


编辑:链接到代码在线->'

当前代码侦听重叠事件,因此并行响应多次

end
事件就足够了,而不是一起听
start
brush
end

    this.brush = brushX().extent([
        [0, 0],
        [this.chartWidth, this.chartHeight]
    ]).on('end', () => {
        if (event.selection  && (event.sourceEvent != null)) {
            const timeSelection = event.selection.map(this.xScale.invert);
            setSelection(timeSelection);
        }
    });

当前代码侦听重叠的事件,因此并行响应多次

end
事件就足够了,而不是一起听
start
brush
end

    this.brush = brushX().extent([
        [0, 0],
        [this.chartWidth, this.chartHeight]
    ]).on('end', () => {
        if (event.selection  && (event.sourceEvent != null)) {
            const timeSelection = event.selection.map(this.xScale.invert);
            setSelection(timeSelection);
        }
    });

谢谢你的解决方案!!谢谢你的解决方案!!