block by jonsadka c507d3d89b057034898cc3dc6f0abcb5

Chile Earthquake

Full Screen

NOTE: Always take the strong axis motion using the .v2 extension. All units in ‘cm/sec2’ with a 0.2 second interval from the uncorrected data

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
  </style>
</head>

<body>
  <script>
		const width = 960;
    const height = 500;
    const margin = {top: 0, right: 0, bottom: 0, left: 0};
    const interval = 0.2; // second per point
    
    const svg = d3.select('body').append('svg')
      .attr('width', width)
      .attr('height', height);
    const gLine = svg.append('g')
      .attr('transform', `translate(${margin.left},${margin.top})`);
    const gBar = svg.append('g');

    const xScale = d3.scaleLinear()
        .rangeRound([0, width]);

    const yScale = d3.scaleLinear()
        .rangeRound([height, 0]);
    
    const colorScale = d3.scaleSequential(d3.interpolateReds)

    const line = d3.line()
        .x(function(d, i) { return xScale(i); })
        .y(function(d) { return yScale(d); });

    d3.json('data.json', function(err, data){
      const pixelsPerBar = 2;
      
      const rawDataPoints = data.acceleration.length;
      const totalResponseTime = rawDataPoints * interval;
      const barCount = width / pixelsPerBar;
      const pointsPerBin = rawDataPoints / barCount;
      
      // Hack: just take averages in the meantime
      const binnedAcceleration = data.acceleration
        .reduce(createBins, [[]])
        .map((bin) => d3.mean(bin));

      const max = d3.max(binnedAcceleration);
      const min = d3.min(binnedAcceleration);
      const greatest = Math.max(max, Math.abs(min));
      
      xScale.domain([0, barCount]);
      yScale.domain([min, max]);
      colorScale.domain([0, greatest]);

      gBar.selectAll('.bars')
        .data(binnedAcceleration).enter()
        .append('rect')
          .attr('class', 'bars')
          .attr('width', pixelsPerBar)
          .attr('height', height)
          .attr('x', (d, i) => i * pixelsPerBar)
          .attr('y', 0)
          .attr('fill', (d) => colorScale(Math.abs(d)))

      gLine.append('g')
          .attr('transform', `translate(0,${height})`)
          .attr('opacity', 0)
          .attr('class', 'line-graph')
          .call(d3.axisBottom(xScale))
        .select('.domain')
          .remove();

//       gLine.append('g')
//           .call(d3.axisLeft(yScale))
//         .append('text')
//           .attr('fill', '#000')
//           .attr('transform', 'rotate(-90)')
//           .attr('y', 6)
//           .attr('dy', '0.71em')
//           .attr('text-anchor', 'end')
//           .text('Acceleration');

      gLine.append('path')
          .datum(binnedAcceleration)
          .attr('fill', 'none')
          .attr('stroke', colorScale(max / 4))
          .attr('stroke-linejoin', 'round')
          .attr('stroke-linecap', 'round')
          .attr('stroke-width', 1)
          .attr('d', line);
      
      gLine.append('g')
        .append('text')
          .attr('fill', '#000')
          .attr('transform', `translate(${width}, 0)`)
          //.attr('y', 6)
          //.attr('dy', '0.71em')
          //.attr('text-anchor', 'end')
          .text(`${totalResponseTime}s`);
      
      
      let toggle = true; 
      setInterval(() => {
        d3.selectAll('.bars')
          .transition().duration(2000)
          .attr('fill', toggle ? colorScale(max / 4) : (d) => colorScale(Math.abs(d)))
          .attr('height', toggle ? 0 : height)
          .attr('y', toggle ? yScale : 0);

        d3.selectAll('.line-graph')
          .transition().delay(1000).duration(1000)
          .attr('opacity', toggle ? 1 : 0)

        d3.selectAll('.line-graph')
          .transition().delay(1000).duration(1000)
          .attr('opacity', toggle ? 1 : 0)

        toggle = !toggle;
      }, 2000)

      function createBins(bins, currentValue, currentIndex) {
        const lastBin = bins[bins.length - 1];
        const binFilledUp = lastBin.length >= pointsPerBin;
        binFilledUp ? bins.push([currentValue]) : lastBin.push(currentValue);
        return bins;
      }
    })

  </script>
</body>