Javascript D3多系列转换重叠数据

Javascript D3多系列转换重叠数据,javascript,d3.js,Javascript,D3.js,我有一个基于传感器序列号正确绘制几条线的图表。问题是,我需要它转换到一个新的数据集,数据将重叠。这是我到目前为止所拥有的 var thresholdTemp = 72; var minutes = 5; var transInterval; //Main function to create a graph plot function plot(date1, date2, interval) { var data; //If we define a date searc

我有一个基于传感器序列号正确绘制几条线的图表。问题是,我需要它转换到一个新的数据集,数据将重叠。这是我到目前为止所拥有的

var thresholdTemp = 72;
var minutes = 5;
var transInterval;

//Main function to create a graph plot
function plot(date1, date2, interval) { 
    var data;   
    //If we define a date search parameter then we don't want to have it load interactive
    if (date1 == undefined && date2==undefined) {   
        data = loadMinutesJSON(minutes);
    } else {
        data = searchJSON(date1, date2, interval);

    }
    var margin = {top: 20, right: 80, bottom: 60, left: 50},
    width = 960 - margin.left - margin.right ,
    height = 500 - margin.top - margin.bottom;

    //Re-order the data to be more usable  by the rest of the script
    var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;

    //Set the X domain to exist within the date and times given
    var x = d3.time.scale().domain([getMinDate(data), getMaxDate(data)]).range([0, (width)]);


    //Y Axis scale set to start at 45 degrees and go up to 30 degrees over highest temp
    var y = d3.scale.linear()
        .domain([
        45,
        getMaxTemp(data) + 10
         ])
        .range([height, 0]);


    //Set up the line colors based on serial number, this generates a color based on an ordinal value
    var color = d3.scale.category20().domain(d3.keys(data).filter(function(key) { return key;}));
            //.domain(d3.keys(data[0]).filter(function(key)  { return key === 'serial';}));

    //Define where the X axis is    
    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .tickFormat(d3.time.format("%b %d %H:%M:%S"));

    //Define where the Y axis is
    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left");

    //When called creates a line with the given datapoints
    var line = d3.svg.line()
        .interpolate("basis")
        .x(function(d) { return x(d.date);})
        .y(function(d) { return y(d.reading); });

    //An extra line to define a maximum temperature threshold
    var threshold = d3.svg.line()
        .x(function(d) { return x(d.date);})
        .y(function(d) { return y(thresholdTemp); });

    //Append the SVG to the HTML element
    var svg = d3.select("#plot").append("svg")
        .attr("width", (width + margin.left + margin.right))
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    //Define the clipping boundaries
    svg.append("defs").append("clipPath")
        .attr("id", "clip")
        .append("rect")
        .attr("width", (width + margin.left +  margin.right))
        .attr("height", height +  margin.top + margin.bottom);

    //Add the X axis    
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
        .selectAll("text")
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform" , function (d) {return "rotate(-35)"});

    //Add the Y axis and a label denoting it as temperature in F    
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis)
        .append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("Temperature (F)");

    //Create the lines based on serial number
    var serial = svg.selectAll(".serial")
        .data(data);
    var serials = serial.enter().append("g")
        .attr("class", "serial");

    //Add the extra line for a threshold and align it with the current time
    var threshElement = svg.selectAll(".thresh")
        .data(data)
        .enter().append("g")
        .attr("class", ".thresh");


    //Add the path to draw lines and clipping so they stay within bounds    
    var path = serial.append("path")
        .attr("clip-path", "url(#clip)")
        .attr("class", "line")
        .attr("d", function (d) {return line(d.values);})
        .style("stroke", function(d,i) {return color(i);});

    //Custom path to add a line showing the temperature threshold
    var threshpath = threshElement.append("path")
        .attr("clip-path", "url(#clip)")
        .attr("class", "line")
        .attr("d", function(d) { return threshold(d.values);})
        .style("stroke", "red");

    //Add a label to the end of the threshold line denoting it as the threshold
        threshElement.append("text")
        .attr("transform", "translate(" + x(getMaxDate(data)) + "," + y(thresholdTemp) + ")")
        .attr("x", 3)
        .attr("dy", ".35em")
        .text("Threshold");

    serial.exit().remove();
    //Add the legend
    //plotLegend(data);

    //Load in the new data and add it to the SVG
    function transition() {
        data = loadMinutesJSON(minutes);

        x.domain([getMinDate(data), getMaxDate(data)]);
        y.domain([45, getMaxTemp(data) + 10]);
                d3.select(".x.axis")
            .transition()
            .duration(500).call(xAxis)
            .selectAll("text")
                    .style("text-anchor", "end")
                    .attr("dx", "-.8em")
                    .attr("dy", ".15em")
                    .attr("transform" , function (d) {return "rotate(-35)"});

        d3.select(".y.axis").transition().duration(500).call(yAxis);

        serial.data(data).enter().append("g").attr("class", "serial");
        d3.selectAll("path")
            .attr("class", "line")
            .attr("d", function(d) { return line(d.values);})
            .style("stroke", function(d,i) { return color(i);});


    }
    if(date1 == undefined && date2 == undefined) {
        //Set the transition loop to run every 30 seconds
            transInterval = setInterval(transition,30000);

    }
}

//Set the new time in minutes and re-draw the graph
function setMinutes(newminutes) {
    if (transInterval) {
        clearInterval(transInterval);
    }
    d3.selectAll("svg").remove();
    console.log("Setting new minutes " + newminutes);
    minutes=newminutes;
    plot();
}
//Search the database for data between 2 dates and create a new plot of it
function searchDB(date1, date2, intervalInMinutes) {
    if (transInterval) {
        clearInterval(transInterval);
    }
    d3.selectAll("svg").remove();
    plot(date1, date2, intervalInMinutes);
    console.log("Processing Search ");
}


 //Quick function to determine the maximum date in a dataset
function getMaxDate(data) {
    var arr = [];
    for (x in data) {
        arr.push(d3.max(data[x].values, function(d) { return d.date;}));
    }
    return d3.max(arr);
        //return d3.max(data[0].values, function(d) { return d.date;});
}

        //Calculate the minimum data 
function getMinDate(data) {
    var arr = [];
    for (x in data) {
        arr.push(d3.min(data[x].values, function(d) { return d.date;}));
    }
    return d3.min(arr);
    //return d3.min(data[0].values, function(d) { return d.date;});
}

        //Calculate the upper maximum temperature
function getMaxTemp(data) {
    var arr = [];
    for (x in data) {
        arr.push(d3.max(data[x].values, function(d) { return d.reading;}));
    }
    return d3.max(arr);
    //return d3.max(data, function(d) { return d3.max(data.values, function(d) {return d.reading})});

}
以下是数据示例:

首先

然后过渡到:

[{"serial":"2D0008017075F210","values":[{"date":"2013-08-23T20:44:46.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:16.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:49:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null}]},{"serial":"1D00080170496D10","values":[{"date":"2013-08-23T20:44:46.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:16.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:49:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null}]},{"serial":"380008017037ED10","values":[{"date":"2013-08-23T20:44:46.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:16.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:47.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:47.000Z","reading":75.2,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:47.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:47.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:49:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null}]}] 
更新: 我已经对代码做了很多修改,但是JSFIDLE在这里
我不知道为什么小提琴不工作,我在我的网络服务器上测试了它,它工作得很好。但是我要做的是构造一个包含data1变量的图,然后将其转换为data2变量。

问题是什么?你能创建一个JSFIDLE吗?我在加载你的JSFIDLE时遇到语法错误。
[{"serial":"2D0008017075F210","values":[{"date":"2013-08-23T20:44:46.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:16.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:47.000Z","reading":76.1,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:49:17.000Z","reading":76.1,"elevation":null,"room":null,"system":null}]},{"serial":"1D00080170496D10","values":[{"date":"2013-08-23T20:44:46.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:16.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:47.000Z","reading":73.4,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:49:17.000Z","reading":73.4,"elevation":null,"room":null,"system":null}]},{"serial":"380008017037ED10","values":[{"date":"2013-08-23T20:44:46.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:16.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:45:47.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:46:47.000Z","reading":75.2,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:47:47.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:48:47.000Z","reading":74.3,"elevation":null,"room":null,"system":null},{"date":"2013-08-23T20:49:17.000Z","reading":74.3,"elevation":null,"room":null,"system":null}]}]