block by enjalot 7162280

html5devconf project

Full Screen

project

index.html

<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8">
    <style>
      svg {
        width: 500px;
        height: 500px;
        border: 1px solid gray;
        float: left;
      }
      .background {
        fill: #4B9E9E;
        fill-opacity: 0.1;
      }
      .extent {
        fill: #78C5C5;
        fill-opacity: 0.4;
      }
      .resize rect {
        fill: #276C86;
      }
      #table {
        width: 400px;
        float:left;
      }
    </style>
  </head>
  <body>
    <svg>
     
    </svg>

    <div id="table">
      <table>
      </table>
    </div>

    <script src="//d3js.org/d3.v3.js"></script>
    <script src="table.js"></script>
    <script src="scatter.js"></script>
    <script>
      d3.json("data.json", function(err, data){
        var posts = data.data.children;
        //console.log(posts);

        var topPadding = 40;
        var leftPadding = 60;
        var svg = d3.select("svg")
        var g = svg.append("g")
        .attr("transform", "translate(" + [leftPadding, topPadding ]+")")

        var scatter = Scatter();
        scatter.data(posts)
        scatter(g);

        var div = d3.select("#table table");
        var table = Table()
          .data(posts)
        table(div);

        scatter.on("filter", function(filtered) {
          console.log("filter event", filtered)
          table.data(filtered);
          table(div);
        })

        table.on("hover", function(data) {
          console.log("hovered", data);
          scatter.highlight(data)
        })
      })
    </script>
  

</body></html>

scatter.js

function Scatter() {
  var data;
  var dispatch = d3.dispatch(chart, "filter");
  var container;

  function chart(g) {
    container = g;
    var chartHeight = 400;
    var chartWidth = 400;

    var xfield = function(d) { 
      return d.data.downs; 
    }
    var yfield = function(d) { 
      return d.data.ups;
    }

    var yScale = d3.scale.linear()
    .domain([0, d3.max(data, yfield)])
    .range([0, chartHeight])

    var xScale = d3.scale.linear()
    .domain([0, d3.max(data, xfield)])
    .range([0, chartWidth])


    var colorScale = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.data.downs })])
    .range(["#17D84D", "#FF1D1D"])
    .interpolate(d3.interpolateHsl)
             

    var circles = g
    .selectAll("circle")
    .data(data)

    circles.enter().append("circle")
    circles.attr({
      cx: function(d,i) { return xScale(xfield(d)); },
      cy: function(d) { return chartHeight - yScale(yfield(d))},
      fill: function(d) { return colorScale(d.data.downs) },
      r: 8,
      stroke: "#000",
      "fill-opacity": 0.5
    })
    .on("click", function(d) {
      console.log(d.data);
    })

    yScale.range([chartHeight, 0])

    var yaxis = d3.svg.axis()
    .scale(yScale)
    .orient("left") //left, right, top
    .ticks(4) //best guess
    var yg = g.append("g")
    yaxis(yg)
    //yg.attr("transform", "translate(" + [leftPadding, topPadding] + ")")
    yg.selectAll("path")
      .style({ fill: "none", stroke: "#810808"})
    yg.selectAll("line")
      .style({ stroke: "#000"})
    yg.selectAll(".tick text").attr("transform", "rotate(-26)")


    var xaxis = d3.svg.axis()
    .scale(xScale)
    .orient("bottom") //left, right, top
    .ticks(4) //best guess
    var xg = g.append("g")
    xaxis(xg)
    xg.attr("transform", "translate(" + [0, chartHeight] + ")")
    xg.selectAll("path")
      .style({ fill: "none", stroke: "#810808"})
    xg.selectAll("line")
      .style({ stroke: "#000"})
    xg.selectAll(".tick text").attr("transform", "rotate(-26)")


    var brush = d3.svg.brush()
    brush.x(xScale)
    .y(yScale)
    brush.on("brushend", brushHandler);
    function brushHandler() {
      //console.log(brush.extent())
      var minext = brush.extent()[0];
      var xmin = minext[0];
      var ymin = minext[1];

      var maxext = brush.extent()[1];
      var xmax = maxext[0];
      var ymax = maxext[1];
      
      var filtered = data.filter(function(d) {
        var x = xfield(d);
        var y = yfield(d);
        return x >= xmin 
          && x <= xmax 
          && y >= ymin 
          && y <= ymax;
      })
      console.log("filtered", filtered, filtered.length)
      
      g.selectAll("circle")
      .style("stroke", "#000");
      
      g.selectAll("circle")
      .data(filtered, function(d) { 
        return d.data.id 
      })
      .style("stroke", "#FFFFFF")

      dispatch.filter(filtered)
    }

    brush.extent([
      [
        10000,
        10000
      ],
      [
        20000,
        20000
      ]
    ])
    brushHandler();


    var bg = g.append("g").classed("brush", true)
    brush(bg)

    //g.selectAll("rect").attr("height", 88)
    bg.selectAll(".background")
      .style({visibility: "visible"})
    bg.selectAll(".extent")
      .style({visibility: "visible"})
    bg.selectAll(".resize rect")
      .style({visibility: "visible"})

  }
  chart.data = function(_) {
    if(!arguments.length) return data;
    data = _;
    return chart;
  }
  chart.highlight = function(data) {
    container.selectAll("circle")
    .style("stroke-width", 1)
    .attr("r", 10)
    .data(data, function(d) { return d.data.id })
    .style("stroke-width", 10)
    .attr("r", 20)
  }

  return d3.rebind(chart, dispatch, "on");
}

table.js

function Table() {
  var data;
  var dispatch = d3.dispatch(chart, "hover");
  //var container;
  function chart(div) {
    //container = div;
    
    var rows = div.selectAll("tr")
    .data(data, function(d) { return d.data.id });

    var rowsEnter = rows.enter()
      .append("tr");

    rowsEnter.append("td").text(function(d) {
      return d.data.score
    })
    rowsEnter.append("td")
    .append("a").attr("href", function(d) { 
      return d.data.url 
    })
    .text(function(d) {
      return d.data.title
    })
    rows.exit().remove();

    rows.on("mouseover", function(d,i) {
      dispatch.hover([d])
    })
    rows.on("mouseout", function(d,i) {
      dispatch.hover([])
    })
  }

  chart.data = function(_) {
    if(!arguments.length) return data;
    data = _;
    //if(container) chart(container);
    return chart;
  }
  return d3.rebind(chart, dispatch, "on");
}