how to draw multiple lines in d3.js , there are 3

2019-08-30 18:12发布

i have a line graph, and perform a calculation for values of the line and based on some criteria the mean, upper limit and lower limit changes. so in the graph i'll b have 3 limit lines(mean , upper and lower) and the normal value line. right now i am able to achieve the limit lines perfectly through the said code.

here im looping and at each iteration im drawing the 3 limit lines. but now im now storing the values of the limits in a db , the calculation is done in a diff file and stores the limit values along with the main values in a db. how do i draw these lines from a db such that these lines are able to be used in a "brush"( very imp). the column values in the db are date, close(value), mean, upper, lower. eg( 21-feb-2013, 250, 63.50, 320, 33.89) ( 22-feb-2013, 255, 63.50, 320, 33.89) ( 23-feb-2013, 192, 63.50, 320, 33.89) ( 24-feb-2013, 90, 45.50, 120, 23.9) ( 25-feb-2013, 67, 45.50, 120, 23.9)

first ill be drawing the limit lines and later ill draw the valueline. im converting the limit values to db to reduce computation on client side and majorly to help in the "brush" slider functionality. i want the limit lines to break when their values change, for eg mean value from 63.50 to 45.50, there must be no line between these two values.

the normal valueline line code is the same as add scrollbar and navigator, range selector functionality in d3.js

for(var v=0;v<m;v++)
{

var mean_value=meanArr[v];
var st=line[v];
var end=line[v+1];


     focus.append("line")

       .attr("class", "mean-line")

      .attr({ x1: x(data[st].date), y1: y(mean_value), x2:x(data[end].date), y2: y(mean_value) })
      .on("mouseover", function(d,i) {

        coordinates = d3.mouse(this);
    var x = coordinates[0];
    var y = coordinates[1];





            div.transition()        
                .duration(200)      
                .style("opacity", .9);      
                div.html(function(){for(var k=0;k<m;k++)
                {if(x<x_val[k])
                { return "mean "+meanArr[k]}}
        ;})
                .style("left", (d3.event.pageX) + "px")     
                .style("top", (d3.event.pageY - 28) + "px");    
            }).on("mouseout", function() {      
            div.transition()        
                .duration(500)      
                .style("opacity", 0);
       });





var upper_limit = uslArr[v];

  focus.append("line")

        .attr("class", "limit-line")
    .attr({ x1: x(data[st].date) , y1: y(upper_limit), x2:x(data[end].date), y2: y(upper_limit) })
    .on("mouseover", function(d,i) {

        coordinates = d3.mouse(this);
    var x = coordinates[0];
    var y = coordinates[1];





            div.transition()        
                .duration(200)      
                .style("opacity", .9);      
                div.html(function(){for(var k=0;k<m;k++)
                {if(x<x_val[k])
                { return "upper Limit "+uslArr[k]}}
        ;})
                .style("left", (d3.event.pageX) + "px")     
                .style("top", (d3.event.pageY - 28) + "px");    
            }).on("mouseout", function(d) {     
            div.transition()        
                .duration(500)      
                .style("opacity", 0);
       });                  



    //document.write(down_limit[30]);
  // lower limit line

  var lower_limit = lslArr[v];

    var z;


  focus.data(lslArr)
    .append("line")

    .attr("class", "limit-line")

    .attr({ x1: x(data[st].date), y1: y(lower_limit), x2:function(){ z=x(data[end].date); x_val[v]=z; return z;}, y2: y(lower_limit) })
    .on("mouseover", function(d,i) {

        coordinates = d3.mouse(this);
    var x = coordinates[0];
    var y = coordinates[1];


    //z=Math.ceil(z);


            div.transition()        
                .duration(200)      
                .style("opacity", .9);      
                div.html(function(){for(var k=0;k<m;k++)
                {if(x<x_val[k])
                { return "lower limit "+lslArr[k]}}
        ;})
                .style("left", (d3.event.pageX) + "px")     
                .style("top", (d3.event.pageY - 28) + "px");    
            })                  
        .on("mouseout", function() {        
            div.transition()        
                .duration(500)      
                .style("opacity", 0);
       });




}

i have put the 3 lines in a group such as http://bl.ocks.org/mbostock/3884955 but im not able to update it in the brush as the other value line. the code for the graph is given below. and the city variable is a group of 3 values mean, lower and upper limit. how do i change the color of each line. because i have used d3.scale.category10() , i have predefined colors. and i want a break of line from one value to another value in the limits, the defined() wont work, what other way can i do that.

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<style>
body { font: 14px Arial;}
svg {
  font: 10px sans-serif;
}
circle {
   -moz-transition: all 0.3s;
   -o-transition: all 0.3s;
   -webkit-transition: all 0.3s;
   transition: all 0.3s;
}           
circle:hover {
        stroke: orange; 
        stroke-width:2;
            }
path { 
    stroke: steelblue;
    stroke-width: 1;
    fill: none;
}



.axis path,
.axis line {
    fill: none;
    stroke: green;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
div.tooltip {   
    position: absolute;         
    text-align: center;         
    width: auto;                    
    height: auto;                   
    padding: 2px;               
    font: 14px sans-serif;      
    background: lightsteelblue; 
    border: 0px;        
    border-radius: 8px;         
    pointer-events: none;
}
.icon {
    float: right;
    display: block;
    margin-bottom: 100;
    margin-left: 0;
    margin-right: 0;
    margin-top: 0;
    padding-bottom: 0;
    padding-left: 0;
    padding-right: 0;
    padding-top: 0;
}       

.download { 
  background: lightblue; 
  color: blue; 
  font-weight: 900; 
  border: 2px; 
  padding: 4px; 
  margin:4px;
}   
.brush .extent {
  stroke: #fff;
  fill-opacity: .125;
  shape-rendering: crispEdges;
}   

</style>


</script>
</head>
<body>
<div id="svg"></div>
<button class="download" onClick="javascript:(function () { var e = document.createElement('script'); if (window.location.protocol === 'https:') { e.setAttribute('src', 'https://raw.github.com/NYTimes/svg-crowbar/gh-pages/svg-crowbar.js'); } else { e.setAttribute('src', 'http://nytimes.github.com/svg-crowbar/svg-crowbar.js'); } e.setAttribute('class', 'svg-crowbar'); document.body.appendChild(e); })();"> Download</button>

<script type="text/javascript" src="d3/d3.v3.js"></script>
<script>


var margin = {top: 10, right: 10, bottom: 100, left: 40},
    margin2 = {top: 430, right: 10, bottom: 30, left: 40},
        width = 2000 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom,
        height2 = 500 - margin2.top - margin2.bottom;


var parseDate = d3.time.format("%Y-%m-%d").parse;
var formatTime = d3.time.format("%e %B");

var x = d3.time.scale().range([0, width]);
var x2= d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var y2 = d3.scale.linear().range([height2, 0]);


var color = d3.scale.category10();


var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(25);
var xAxis2 = d3.svg.axis().scale(x2).orient("bottom");

var yAxis = d3.svg.axis().scale(y).orient("left");

var brush = d3.svg.brush()
    .x(x2)
    .on("brush", brushed);

var line = d3.svg.line()
    .interpolate("step")
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.limit); });

var valueline = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x(d.date); }).y(function(d) { return y(d.close); });

var valueline2 = d3.svg.line().defined(function(d) { return d.close != 0; }).x(function(d) { return x2(d.date); }).y(function(d) { return y2(d.close); });

var brush = d3.svg.brush()
    .x(x2)
    .on("brush", brushed);

var div = d3.select("body").append("div")   
    .attr("class", "tooltip")               
    .style("opacity", 0).style("float","left");    

var svg = d3.select("body").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom);



svg.append("defs").append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);

var focus = svg.append("g")
    .attr("class", "focus")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


var context = svg.append("g")
    .attr("class", "context")
    .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");







var arr=new Array();
// Get the data
d3.json("data/data3.php", function(error, data) { 

color.domain(d3.keys(data[0]).filter(function(key) {  if(key !== "date"&&key !== "close") return key; }));


    data.forEach(function(d,i) {




    d.date = parseDate(d.date);

        d.close = +d.close;
    d.mean=+d.mean;
    d.ucl=+d.ucl;
    d.lcl=+d.lcl;   

    arr[i]=d.close;


    len=i+1;


    });


var cities = color.domain().map(function(name) {
    return {
      name: name,
      values: data.map(function(d) {
        return {date: d.date, limit: +d[name]};
      })
    };
  });






 var min=0;
var max=200;
// Scale the range of the data

    x.domain(d3.extent(data, function(d) { return d.date; }));

  //  y.domain([min-10, max+10]);
    //y.domain([0, d3.max(data, function(d) { return d.ucl; })]);

y.domain([
    d3.min(cities, function(c) { return d3.min(c.values, function(v) { return v.limit; }); }),
    d3.max(cities, function(c) { return d3.max(c.values, function(v) { return v.limit; }); })
  ]);

    x2.domain(x.domain());
     y2.domain(y.domain());


    //y.domain([lsl-5, d3.max(data, function(d) { return d.close; })]);


  var city= focus.selectAll(".city")
      .data(cities)
      .enter().append("g")
      .attr("class", "city");

    city.append("path")
      .attr("class", "line")
      .attr("d", function(d) { return line(d.values); })
      .style("stroke", function(d) { return color(d.name); });







   focus.append("path")     // Add the valueline path.
    .datum(data)
        .attr("class","valueline")
    .attr("d", valueline);

    focus.selectAll(".dot").data(data).enter().append("a").attr("class", "dot")
        .attr("xlink:href",function(d,i){if(d.close>=d.ucl||d.close<=d.lcl)return "http://en.wikipedia.org";})
    .append("circle")
        .attr("r", 2)
    .style("fill", function(d,i) {            // <== Add these
        if(d.close==0) {return "none"}              
        if(d.close>=d.ucl||d.close<=d.lcl) {return "red"}

            else    { return "steelblue" }          // <== Add these
        ;})  
        .attr("cx", function(d) { return x(d.date); })
        .attr("cy", function(d) { return y(d.close); })
    .on("mouseover", function(d,i) {

            div.transition()        
                .duration(200)      
                .style("opacity", .9);      
                div.html(function(){
    if(d.close==0)
    {return}
    if(d.close>=d.ucl)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " > UPPER LIMIT"}
    else if(d.close<=lcl)
    {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b><br/>"  + " < LOWER LIMIT"}

    else {return formatTime(d.date) + "<br/><b>"  + d.close+ "</b>"}
;})
                .style("left", (d3.event.pageX) + "px")     
                .style("top", (d3.event.pageY - 28) + "px");    
            })                  
        .on("mouseout", function(d) {       
            div.transition()        
                .duration(500)      
                .style("opacity", 0);
       }).style("pointer-events","visible");




    /*
city.append("text")
      .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
      .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.limit) + ")"; })
      .attr("x", 3)
      .attr("dy", ".35em")
      .text(function(d) { return d.name; });

*/
            // Add the X Axis

    focus.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(-65)" 
                });


    focus.append("text")             // text label for the x axis
        .attr("x", width/2 )
        .attr("y",  height+margin.bottom)
        .style("text-anchor", "middle")
        .text("Date");  

// Add the Y Axis

    focus.append("g").attr("class", "y axis").call(yAxis);

    focus.append("text").attr("transform","rotate(-90)").attr("y", 0-margin.left+10 )
        .attr("x",0-( height/2) )
        .style("text-anchor", "middle")
    .style("text-decoration", "underline")  
        .text("issue"); 

    //title to graph
focus.append("text")
        .attr("x", (width / 2))             
        .attr("y", 0 - (margin.top / 2))
        .attr("text-anchor", "middle")  
        .style("font-size", "16px") 
        .style("text-decoration", "underline")  
        .text("Issue vs Date Graph");


context.append("path")      // Add the valueline path.
        .attr("d", valueline2(data));

context.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height2 + ")")
      .call(xAxis2);


context.append("g")
      .attr("class", "x brush")
      .call(brush)
    .selectAll("rect")
      .attr("y", -6)
      .attr("height", height2 + 7);



});


function brushed() {

  x.domain(brush.empty() ? x2.domain() : brush.extent());


  focus.selectAll(".valueline").attr("d",valueline);
  focus.selectAll(".dot").select("circle").attr("cx", function(d) { return x(d.date); });
  focus.selectAll(".city").attr("d",line);
  focus.select(".x.axis").call(xAxis);
}

function type(d) {
  d.date = parseDate(d.date);
  d.close = +d.close;
  d.ucl=+d.ucl;
  d.lcl=+d.lcl;
  d.mean=+d.mean;
  return d;
}




</script>

</body>
<html>

how should i call the group line in brushed()

0条回答
登录 后发表回答