sweatshoptech/idb

View on GitHub
templates/visualization.html

Summary

Maintainability
Test Coverage
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <title>SWEatshop.tech</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400" rel="stylesheet">
    <link rel="stylesheet" href="/static/css/styles.processed.css"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
    <script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.js"></script>
    <link rel="shortcut icon" href="/static/img/favicon.ico">
    <script src="http://phuonghuynh.github.io/js/bower_components/d3/d3.min.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/d3-transform/src/d3-transform.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/cafej/src/extarray.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/cafej/src/misc.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/cafej/src/micro-observer.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/microplugin/src/microplugin.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/bubble-chart/src/bubble-chart.js"></script>
    <script src="/static/js/central-click.js"></script>
    <script src="http://phuonghuynh.github.io/js/bower_components/bubble-chart/src/plugins/lines/lines.js"></script>
    <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
    <script>
      $(document).ready(function () {
        var bubbleChart = new d3.svg.BubbleChart({
          supportResponsive: true,
          //container: => use @default
          size: 600,
          //viewBoxSize: => use @default
          innerRadius: 600 / 3.5,
          //outerRadius: => use @default
          radiusMin: 50,
          //radiusMax: use @default
          //intersectDelta: use @default
          //intersectInc: use @default
          //circleColor: use @default
          data: {
            items: {{type_count|tojson}},
            eval: function (item) {return item.count;},
            classed: function (item) {return item.text.split(" ").join("");}
          },
          plugins: [
            {
              name: "central-click",
              options: {
                style: {
                  "font-size": "12px",
                  "font-style": "italic",
                  "font-family": "Source Sans Pro, sans-serif",
                  "text-anchor": "middle",
                  "fill": "white"
                },
                attr: {dy: "65px"}
              }
            },
            {
              name: "lines",
              options: {
                format: [
                  {// Line #0
                    textField: "count",
                    classed: {count: true},
                    style: {
                      "font-size": "28px",
                      "font-family": "Source Sans Pro, sans-serif",
                      "text-anchor": "middle",
                      fill: "white"
                    },
                    attr: {
                      dy: "0px",
                      x: function (d) {return d.cx;},
                      y: function (d) {return d.cy;}
                    }
                  },
                  {// Line #1
                    textField: "text",
                    classed: {text: true},
                    style: {
                      "font-size": "14px",
                      "font-family": "Source Sans Pro, sans-serif",
                      "text-anchor": "middle",
                      fill: "white"
                    },
                    attr: {
                      dy: "20px",
                      x: function (d) {return d.cx;},
                      y: function (d) {return d.cy;}
                    }
                  }
                ],
                centralFormat: [
                  {// Line #0
                    style: {"font-size": "50px"},
                    attr: {}
                  },
                  {// Line #1
                    style: {"font-size": "30px"},
                    attr: {dy: "40px"}
                  }
                ]
              }
            }]
        });
      });
      
    </script> 
  </head>
  <body class="gradient-bg">
    <nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse-opacity">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <a class="navbar-brand" href="/index.html"><img alt="Brand" src="/static/img/sweatshop-logo.png" style="width: 200px;"></a>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item">
            <a class="nav-link" href="/index.html">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/about.html">About</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/companies.html">Companies</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">People</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/investors.html">Investors</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/schools.html">Schools</a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" href="/visualization.html">Visualization<span class="sr-only">(current)</span></a>
          </li>
          <li><a href="#search"><img src="http://www.freeiconspng.com/uploads/search-icon-png-4.png" style="height: 35px;"></a></li>
        </ul>
      </div>
    </nav>
    <div style="min-height:89vh"> 
      <h1 class="cover-heading">Visualization</h1>
      <div class="container" style="color: white;">  
       <h3>Average Restaurant Rating by Zipcode</h3>
       <h4>data provided by <a href="http://foodcloseto.me" target="_blank">foodcloseto.me</a></h4>
        <label><input type="checkbox"> Sort by Rating/Zipcode</label>
        <div id="d32"></div>
        <script>
          var margin = {top: 20, right: 20, bottom: 30, left: 40},
              width = 960 - margin.left - margin.right,
              height = 500 - margin.top - margin.bottom;
          
          var x = d3.scale.ordinal()
              .rangeRoundBands([0, width], .1, 1);
          
          var y = d3.scale.linear()
              .range([height, 0]);
          
          var xAxis = d3.svg.axis()
              .scale(x)
              .orient("bottom");
          
          var yAxis = d3.svg.axis()
              .scale(y)
              .orient("left")
           
          var tip = d3.tip()
            .attr('class', 'd3-tip')
            .offset([-10, 0])
            .html(function(d) {
              return "<strong>Zipcode:</strong> <span style='color:dodgerblue'>" +d.letter + "</span></br><strong>Average Rating:</strong> <span style='color:dodgerblue'>" + d.frequency + "</span>" ;
            })

          var svg = d3.select("#d32").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 + ")");
          
          svg.call(tip);         
 
          d3.tsv("{{ url_for('static', filename='data.tsv') }}", function(error, data) {
          
            data.forEach(function(d) {
              d.frequency = +d.frequency;
            });
          
            x.domain(data.map(function(d) { return d.letter; }));
            y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
          
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis)
               .append("text")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Zipcode");
          
            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("Average Rating");
          
            svg.selectAll(".bar")
                .data(data)
              .enter().append("rect")
                .attr("class", "bar")
                .attr("x", function(d) { return x(d.letter); })
                .attr("width", x.rangeBand())
                .attr("y", function(d) { return y(d.frequency); })
                .attr("height", function(d) { return height - y(d.frequency); })
                .on('mouseover', tip.show)
                .on('mouseout', tip.hide);

            d3.select("input").on("change", change);
          
            var sortTimeout = setTimeout(function() {
              d3.select("input").property("checked", true).each(change);
            }, 2000);
          
            function change() {
              clearTimeout(sortTimeout);
          
              // Copy-on-write since tweens are evaluated after a delay.
              var x0 = x.domain(data.sort(this.checked
                  ? function(a, b) { return b.frequency - a.frequency; }
                  : function(a, b) { return d3.ascending(a.letter, b.letter); })
                  .map(function(d) { return d.letter; }))
                  .copy();
          
              svg.selectAll(".bar")
                  .sort(function(a, b) { return x0(a.letter) - x0(b.letter); });
          
              var transition = svg.transition().duration(750),
                  delay = function(d, i) { return i * 50; };
          
              transition.selectAll(".bar")
                  .delay(delay)
                  .attr("x", function(d) { return x0(d.letter); });
          
              transition.select(".x.axis")
                  .call(xAxis)
                .selectAll("g")
                  .delay(delay);
            }
          });
        
        </script>
        <br/><br/>
        <h3>Top 10 Food Types</h3>
        <h4>data provided by <a href="http://foodcloseto.me" target="_blank">foodcloseto.me</a></h4>
        <div class="bubbleChart"></div>
        <br/><br/>
      </div>
    </div>
    <div class="outro">
      © SWEatshop 2017
    </div>
 </body>
  <div id="search">
      <button type="button" class="close">×</button>
      <form action="/search" method="get">
          <input type="search" name="query" value="" placeholder="type keyword(s) here" />
          <button type="submit" class="btn btn-primary">Search</button>
      </form>
  </div>
  <script>
    $(function () {
        $('a[href="#search"]').on('click', function(event) {
            event.preventDefault();
            $('#search').addClass('open');
            $('#search > form > input[type="search"]').focus();
        });
        
        $('#search, #search button.close').on('click keyup', function(event) {
            if (event.target == this || event.target.className == 'close' || event.keyCode == 27) {
                $(this).removeClass('open');
            }
        });
    });
  </script>
</html>