更新一行';用d3.js替换数据以响应拖动事件

更新一行';用d3.js替换数据以响应拖动事件,d3.js,D3.js,我使用d3创建了两个折线图,当用户拖动其中一个图形的范围时,这两个折线图都可以放大。我已经能够通过在拖动事件结束时完全重画每个图形来实现它,但是我只想做一个更新,可能还想做一个动画转换。出于某种原因,图形开始更新,但它们不会绘制新数据,因此它们只是变成空图形,即使只是一个图形更新。在尝试更新之前和之后,我都做了console.log(newdata),数组中有大量数据,其格式与原始数据相同。我确实有很多观点(数千点),但我已经看到d3示例可以很好地处理如此大的数据集,至少可以作为折线图。使用Fi

我使用d3创建了两个折线图,当用户拖动其中一个图形的范围时,这两个折线图都可以放大。我已经能够通过在拖动事件结束时完全重画每个图形来实现它,但是我只想做一个更新,可能还想做一个动画转换。出于某种原因,图形开始更新,但它们不会绘制新数据,因此它们只是变成空图形,即使只是一个图形更新。在尝试更新之前和之后,我都做了console.log(newdata),数组中有大量数据,其格式与原始数据相同。我确实有很多观点(数千点),但我已经看到d3示例可以很好地处理如此大的数据集,至少可以作为折线图。使用Firebug,我没有得到任何错误,函数完成(删除rect)。我意识到我还需要更新量表,但我想至少首先更新数据。我是d3的新手,所以如果我只是做了些傻事,我不会感到惊讶。非常感谢您的帮助

下面是画线的代码,后面是处理拖动事件的代码

var line = d3.svg.line()
    .x(function(d){return x_scale(d.x)})
    .y(function(d){return y_scale(d.y)})
d3.select("#graph" + pointnum + " svg g")
        .append("path")
        .attr("d", line(data))
        .attr("class", "dist_line");

var dragrect;


var dragit = d3.behavior.drag()
    .on("dragstart", function(){
        omsi_globals.startx = Math.round(d3.mouse(this)[0]);
        dragrect = d3.select("#graph" + pointnum + " svg g")
            .append("rect")
                .attr("x", omsi_globals.startx)
                .attr("y", 0)
                .attr("width", 1)
                .attr("height", omsi_globals.chart_dimensions.height)
                .attr("fill", "gray")
                .attr("opacity", ".1");
    })
    .on("drag", function(){
        var currx = d3.mouse(this)[0];
        if(omsi_globals.startx > currx){
             dragrect.transition()
                .attr("x", currx)
                .attr("width", Math.abs(currx - omsi_globals.startx))
                .delay(0)
                .duration(10);
        }
        else dragrect.transition()
                .attr("width", Math.abs(currx - omsi_globals.startx))
                .delay(0)
                .duration(10);
    })
    .on("dragend", function(){
        var startx = omsi_globals.startx;
        var endx = Math.round(d3.mouse(this)[0]);
        //make sure the drag covered more than one pixel. If not, fade out the rect
        if(Math.abs(startx - endx)< 1){
            dragrect.transition().attr("width", 0); 
            return;
        }
        //people can drag both directions, so figure out which is lower and which is higher
        var lowerx = Math.min(startx, endx);
        var higherx = Math.max(startx, endx);
        //we'll scale as a proportion of the current x scale (not indices, which are more regular than the data)
        var currxmin = omsi_globals.d3data[pointnum-1][0].x;
        var currxmax = omsi_globals.d3data[pointnum-1][omsi_globals.d3data[pointnum-1].length-1].x;
        var chartwidth = omsi_globals.chart_dimensions.width;
        var newmin = ((lowerx/chartwidth) * (currxmax - currxmin)) + currxmin;
        var newmax = ((higherx/chartwidth) * (currxmax - currxmin)) + currxmin;
        //decide if it's time to switch to raw data or not
        var sourcedata = [];
        var newdata = [];
        //switch to raw data if down to less than threshold width
        if(newmax - newmin < omsi_globals.threshold) sourcedata = omsi_globals.plotpoints[pointnum-1].raw; 
        else sourcedata = omsi_globals.d3data[pointnum-1];
        for(i=0; i<sourcedata.length; i++){
            if(sourcedata[i].x < newmax && sourcedata[i].x > newmin){
                newdata.push(sourcedata[i]);
            }
        }
        //update the global variables to be read by d3
        omsi_globals.d3data[pointnum-1] = newdata;
        omsi_globals.d3xranges[pointnum-1] = [newdata[0].x, newdata[newdata.length-1].x];
        d3.selectAll("#graph" + pointnum + " path")
            .data(newdata)
            .transition()
            .duration(2500)
            .attr("d", line);
        dragrect.remove();

    });
var line=d3.svg.line()
.x(函数(d){返回x_标度(d.x)})
.y(函数(d){返回y_标度(d.y)})
d3.选择(“#图形”+pointnum+“svg g”)
.append(“路径”)
.attr(“d”,行(数据))
.attr(“类”、“距离线”);
变量牵引;
var dragit=d3.behavior.drag()
.on(“dragstart”,函数(){
omsi_globals.startx=Math.round(d3.mouse(this)[0]);
dragrect=d3。选择(“图形”+pointnum+“svg g”)
.append(“rect”)
.attr(“x”,omsi_globals.startx)
.attr(“y”,0)
.attr(“宽度”,1)
.attr(“高度”,omsi_全局图尺寸。高度)
.attr(“填充”、“灰色”)
.attr(“不透明度”和“.1”);
})
.on(“拖动”,函数(){
var currx=d3.mouse(this)[0];
如果(omsi_globals.startx>currx){
dragrect.transition()
.attr(“x”,currx)
.attr(“宽度”,Math.abs(currx-omsi_globals.startx))
.延迟(0)
.期限(10);
}
else dragrect.transition()
.attr(“宽度”,Math.abs(currx-omsi_globals.startx))
.延迟(0)
.期限(10);
})
.on(“dragend”,function(){
var startx=omsi_globals.startx;
var endx=Math.round(d3.mouse(this)[0]);
//确保拖动覆盖了多个像素。如果没有,请淡出矩形
如果(数学绝对值(startx-endx)<1){
dragrect.transition().attr(“宽度”,0);
返回;
}
//人们可以向两个方向拖动,所以找出哪个较低,哪个较高
var lowerx=数学最小值(开始、结束);
var higherx=数学最大值(开始、结束);
//我们将按当前x标度的比例进行缩放(不是指数,它比数据更规则)
var currxmin=omsi_globals.d3data[pointnum-1][0].x;
var currxmax=omsi_globals.d3data[pointnum-1][omsi_globals.d3data[pointnum-1].length-1].x;
var chartwidth=omsi_globals.chart_dimensions.width;
var newmin=((下限/图表宽度)*(currxmax-currxmin))+currxmin;
var newmax=((高x/图表宽度)*(currxmax-currxmin))+currxmin;
//决定是否该切换到原始数据
var sourcedata=[];
var newdata=[];
//如果下降到小于阈值宽度,则切换到原始数据
如果(newmax-newmin
您能构建一个JSFIDLE来表示您的问题吗?@ChrisJamesC,谢谢您的关注。这里有一个JSFIDLE:我自己找到了一个解决方案,尽管我仍然喜欢比我更优雅的解决方案。似乎我需要用新的比例定义一条新线,然后更新路径以使用它。我猜这与我有不同大小的数据集这一事实有关。