block by jwilber 25fdb564bce999f676b16ca081234deb

basic reusable bar chart

Full Screen

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html> 
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.js"></script>
<style>
  svg {
    border: 1px dotted red;
  }
</style>
</head>
<body>
<div id="runningHistory"></div>
<div id="viz2"></div>
</body>
  <script>
    var milesRun = [2, 5, 4, 1, 2, 6, 5];
    var highTemperatures = [77, 71, 82, 87, 84, 78, 80, 84, 86, 72, 71, 68, 75, 73, 80, 85, 86, 80];
    
    
 		function drawChart(dom, data, options) {
      const width = options.width || 500;
      const height = options.height || 300;
      const barPadding = options.barPadding || 1;
    	const fillColor = options.fillColor || 'steelblue';
 
    	var barSpacing = height / data.length;
    	var barHeight = barSpacing - barPadding;
    	var maxValue = d3.max(data);
    	var widthScale = width / maxValue;
      
      d3.select(dom).append('svg')
      	.attr('width', width)
      	.attr('height', height)
      	.selectAll('rect')
      	.data(data)
      	.enter()
        .append('rect')
        .attr('y', (d,i) => i * barSpacing)
        .attr('height', barHeight)
        .attr('x', 0)
        .attr('width', d => d*widthScale)
        .attr('fill', fillColor);
    }
    
   var runningOptions = {barPadding: 2, fillColor: 'coral'};
    drawChart('#runningHistory', milesRun, runningOptions);
    
   const weaOps = {barPadding: 10, fillColor: 'pink',
                  width: 200}
   drawChart('#viz2', highTemperatures, weaOps)
    
    
  </script>
</html>

scatter.js

function randomData(numPoints) { 
  var data = [];
  random = function() {return Math.floor(Math.random() * 100);};
  for (i = 0; i < numPoints; i++) {
    data.push({
      x: random(),
      y: random(),
      z: random()
    });
  }
  return data;
}

function scatterPlot() {
  var margin = {top: 10, right: 25, bottom: 25, left: 40},
      width = 600,
      height = 400,
      xValue = function(d) { return d[0]; },
      yValue = function(d) { return d[1]; },
      sizeValue = function(d) { return d[2]; },
      xScale = d3.scaleLinear(),
      yScale = d3.scaleLinear(),
      sizeScale = d3.scaleSqrt(),
      xAxis = d3.axisBottom().tickSize(6,1);
      yAxis = d3.axisLeft().tickSize(6, 1);
 
  function chart(selection) {
    selection.each(function(data) {

      // Convert data to standard representation greedily;
      // this is needed for nondeterministic accessors.
      data = data.map(function(d, i) {
        return [xValue.call(data, d, i),
                yValue.call(data, d, i),
                sizeValue.call(data, d, i)];
      });

      // Update the x-scale.
      xScale
          .domain(d3.extent(data, function(d) { return d[0]; }))
          .range([0, width - margin.left - margin.right]);

      // Update the y-scale.
      yScale
          .domain([0, d3.max(data, function(d) { return d[1]; })])
          .range([height - margin.top - margin.bottom, 0]);

      // Update the size-scale.
      sizeScale
          .domain([d3.min(data, function(d) { return d[2]; }),
            d3.max(data, function(d) { return d[2]; })])
          .range([2,8]);

      // Select the svg element, if it exists.
      var svg = d3.select(this).selectAll("svg").data([data]);

      // Otherwise, create the skeletal chart.
      var gEnter = svg.enter().append("svg").append("g");
      gEnter.append("g").attr("class", "points");
      gEnter.append("g").attr("class", "x axis");
      gEnter.append("g").attr("class", "y axis");

      // Update the outer dimensions.
      svg .attr("width", width)
          .attr("height", height);

      // Update the inner dimensions.
      var g = svg.select("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

      // Update the points
      g.select("g.points")
       .selectAll("circles.point")
       .data(data)
       .enter()
       .append("circle")
       .attr("class", "point")
       .attr("r", function(d) { return sizeScale(d[2]); })
       .attr("transform", function(d) { 
              return "translate(" + xScale(d[0]) + "," + yScale(d[1]) + ")";
             });

      // Update the x-axis.
      g.select(".x.axis")
          .attr("transform", "translate(0," + yScale.range()[0] + ")")
          .call(xAxis);

      // Update the y-axis.
      g.select(".y.axis")
          .attr("transform", "translate(0," + xScale.range()[0] + ")")
          .call(yAxis);
    });
  }

  // The x-accessor for the path generator; xScale ∘ xValue.
  function X(d) {
    return xScale(d[0]);
  }

  // The x-accessor for the path generator; yScale ∘ yValue.
  function Y(d) {
    return yScale(d[1]);
  }

  function size(d) {
    return sizeScale(d[2]);
  }

  chart.margin = function(_) {
    if (!arguments.length) return margin;
    margin = _;
    return chart;
  };

  chart.width = function(_) {
    if (!arguments.length) return width;
    width = _;
    return chart;
  };

  chart.height = function(_) {
    if (!arguments.length) return height;
    height = _;
    return chart;
  };

  chart.x = function(_) {
    if (!arguments.length) return xValue;
    xValue = _;
    return chart;
  };

  chart.y = function(_) {
    if (!arguments.length) return yValue;
    yValue = _;
    return chart;
  };

  chart.size = function(_) {
    if (!arguments.length) return sizeValue;
    sizeValue = _;
    return chart;
  };

  return chart;
}

var chart = scatterPlot()
  .x( function(d) { return +d.x; } )
  .y( function(d) { return +d.y; } )
  .size( function(d) { return +d.z; } )
  .height(250);

// Bind the data to the chart to the #viz elements
chart1 = d3.select('#viz1').datum(randomData(50)).call(chart);
chart2 = d3.select('#viz2').datum(randomData(50)).call(chart);