canimus
4/16/2012 - 9:13 PM

D3 Usage of Filters

D3 Usage of Filters

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>D3 SLA Graph</title>
  <style type="text/css">
  body {
    font: 10px 'Menlo';
    margin-left: 0;
  }

  h1 {
    margin-left: 80px;
    margin-bottom: 0px;
    font-size: 22px;
    font-weight: bold;
    color: #333;
  }
  
  h2 {
    margin-top: 20px;
    margin-left: 80px;
    margin-bottom: 0px;
    color: #444;
    padding-bottom: 4px;
    border-bottom: 2px dotted #333;
    width: 800px;
  }

  path.line {
    fill: none;
    stroke: #9d9d9d;
    stroke-width: 1px;
  }

  .axis {
    shape-rendering: crispEdges;
  }

  .x.axis .minor {
    stroke-opacity: .5;
  }

  .x.axis line {
    stroke: #fff;
    stroke-width: 1px;
    stroke-dasharray: 5 2;
  }

  .x.axis path {
    display: none;
  }

  .y.axis line, .y.axis path {
    fill: none;
    stroke: #000;
  }

  circle.red {
    fill: #917c6f;
    stroke: #666;
    stroke-width: .5px;
    opacity: 1;
  }
  
  circle.yellow {
    fill: #decd87;
    stroke: #666;
    stroke-width: .5px;
    opacity: 1;
  }

  circle.green {
     fill: #37abc8;
     stroke: #666;
     stroke-width: .5px;
     opacity: 1;
   }

  text.label {
    font-family: 'Flux';
    fill: white;
    stroke: none;
    font-size: 18px;
    opacity: 1;
  }

  </style>
  <script src="/assets/d3.min.js" type="text/javascript" charset="utf-8"></script>
  <script src="/assets/d3.csv.min.js" type="text/javascript" charset="utf-8"></script>
  <script src="/assets/d3.time.min.js" type="text/javascript" charset="utf-8"></script>
  <script type="text/javascript">

  // Variables definition
  var  m = [80, 80, 80, 80],
  w = 960 - m[1] - m[3],
  h = 500 - m[0] - m[2],
  parse = d3.time.format("%B %Y").parse;

  // Scales and axes     
  var  x = d3.time.scale().range([0,w]),
  y = d3.scale.linear().range([h,0]),
  xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(false),
  yAxis = d3.svg.axis().scale(y).ticks(6).orient("right");



  // Area generator
  var area = d3.svg.area()
  //.interpolate("basis")
  //.interpolate("monotone")
  //.interpolate("basis-open")
  .x(function(d) { return x(d.date); })
  .y0(function(d) {return h})
  .y1(function(d) { return y(d.total); });

  var line = d3.svg.line()
  //.interpolate("basis")
  //.interpolate("monotone")
  //.interpolate("basis-open")
  .x(function(d) { return x(d.date); })
  .y(function(d) { return y(d.total); });

  // Read the CSV file
  d3.csv("data.csv", function(data) {

    // Filter to one symbol: Elche
    var values = data.filter(function(d) {
      return d.city == "Elche";
    });

    // Parse the dates and total visitors
    values.forEach(function(d) {
      d.date = parse(d.date);
      d.total = +d.total;
    });


    // Compute the min and max to define the domain of values
    x.domain([values[0].date, values[values.length-1].date]);
    y.domain([0, d3.max(values, function(d) { return d.total; })+10]).nice();
    //y.domain([0, 500]);

    // Add an SVG element
    var svg = d3.select("body").append("svg")
    .attr("width", w + m[1] + m[3])
    .attr("height", h + m[0] + m[2]);

    var defs = svg.append("defs");
    
    // Add the area
    defs.append("path")
    .attr("class", "area")
    .attr("id", "my_area")
    //.attr("clip-path", "url(#clip)")
    .attr("d", area(values));

    var gradient = defs.append("linearGradient")
    .attr("id", "gradient")
    .attr("gradientUnits", "userSpaceOnUse")
    .attr("x1", 0)
    .attr("y1", 0)
    .attr("x2", 0)
    .attr("y2",560);
    gradient.append("stop")
    .attr("offset", 0)
    .attr("stop-color","white")
    .attr("stop-opacity", .3);
    gradient.append("stop")
    .attr("offset",1)
    .attr("stop-color","white")
    .attr("stop-opacity",1);
  
    var gradient2 = defs.append("linearGradient")
    .attr("id", "gradient2")
    .attr("gradientUnits", "userSpaceOnUse")
    .attr("x1", 0)
    .attr("y1", 0)
    .attr("x2", 0)
    .attr("y2",350);
    gradient2.append("stop")
    .attr("offset", 0)
    .attr("stop-color","white")
    .attr("stop-opacity", .3);
    gradient2.append("stop")
    .attr("offset",1)
    .attr("stop-color","white")
    .attr("stop-opacity",1);

    var mask1 = defs.append("mask")
    .attr("id", "mask1")
    .attr("maskUnits","userSpaceOnUse")
    .attr("x",0)
    .attr("y",0)
    .attr("width", 800)
    .attr("height",y(120));      
    mask1.append("rect")
    .attr("x",0)
    .attr("y",0)
    .attr("width", 800)
    .attr("height", y(120))
    .attr("fill", "url(#gradient2)");

    var mask2 = defs.append("mask")
    .attr("id", "mask2")
    .attr("maskUnits","userSpaceOnUse")
    .attr("x",0)
    .attr("y",y(120))
    .attr("width", 800)
    .attr("height",50);      
    mask2.append("rect")
    .attr("x",0)
    .attr("y",y(120))
    .attr("width", 800)
    .attr("height", 50)
    .attr("fill", "url(#gradient2)");

    var mask3 = defs.append("mask")
    .attr("id", "mask3")
    .attr("maskUnits","userSpaceOnUse")
    .attr("x",0)
    .attr("y",y(95))
    .attr("width", 800)
    .attr("height",200);      
    mask3.append("rect")
    .attr("x",0)
    .attr("y",y(95))
    .attr("width", 800)
    .attr("height", 200)
    .attr("fill", "url(#gradient)");


    svg = svg.append("g")
    .attr("transform", "translate("+m[3]+","+m[0]+")");
  
    svg.append("use")
    .attr("xlink:href","#my_area")
    .attr("fill","#917c6f")
    .attr("mask","url(#mask1)");

    svg.append("use")
    .attr("xlink:href","#my_area")
    .attr("fill","#decd87")
    .attr("mask","url(#mask2)");

    svg.append("use")
    .attr("xlink:href","#my_area")
    .attr("fill","#37abc8")
    .attr("mask","url(#mask3)");

    svg.append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", w)
    .attr("height", h)
    .attr("clip-rule", "nonzero");

    svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0,"+h+")")
    .call(xAxis);

    // Add the y-axis
    svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate("+w+",0)")
    .call(yAxis);

    svg.append("path")
    .attr("class", "line")
    .attr("clip-path", "url(#clip)")
    .attr("d", line(values));
    
    var circle_points = svg.append("g")
      .attr("id", "edge_holder")
      .attr("clip-path", "url(#clip)");
      
    circle_points.selectAll("circle").data(values).enter().append("circle")
      .attr("r", 5)
      .attr("cx", function(d) { return x(d.date)})
      .attr("cy", function(d) { return y(d.total)})
      .attr("class", function(d,i) {
        if ( d.total >= 120 ) {
          return "red";
        } else if ( (d.total >= 90) && (d.total < 120) ) {
          return "yellow";
        } else {
          return "green";
        }
      })
      .on("mouseover", function() {
        d3.select(this)
          .transition().duration(100)
          .attr("r", 8);
      })
      .on("mouseout", function() {
        d3.select(this)
          .transition().duration(100)
          .attr("r", 5);
      });    

    svg.append("text")
    .attr("class", "label")
    .attr("x", w-6)
    .attr("y", h-6)
    .attr("text-anchor", "end")
    .text(values[0].city);
    
    svg.on("click", function() {
      var n = values.length-1,
          i = Math.floor(Math.random() * n / 2),
          j = i + Math.floor(Math.random() * n / 2) + 1;
      
      
      x.domain([values[i].date, values[j].date]);
      //svg.selectAll("use").remove();
      
      //d3.selectAll("circle").transition().duration(400).attr("cy", 10);
      //d3.selectAll("circle").data(values).exit().remove();
      d3.select("#my_area").transition().duration(750).attr("d", area(values));
      // Graph transition
      var t1 = svg.transition().duration(750);      
      t1.select(".x.axis").call(xAxis);      
      t1.select(".line").attr("d", line(values));      
      
      //var t2 = svg.transition().duration(750).delay(750);
      d3.selectAll("circle").each(function(d) {
        d3.select(this).transition().duration(750).attr("cx", x(d.date)).attr("cy", y(d.total));
      });
      //t2.select("circle").data(function(values,i) { return [x(d.date),y(d.total)]});
        
      
      
    });

  });

  </script>
</head>
<body>
  <h1>Orchestration ScoreCard</h1>
  <h2>Aggregated Response Times</h2>
</body>
</html>