block by curran 266399f3c1bd8b401413ba7dd149a451

Data Driven Changes

Full Screen

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Shopping App Prototype</title>
    <script src="https://d3js.org/d3.v4.min.js"></script>
  </head>
  <body>
    <svg width="960" height="500"></svg>
    <script>
      const xValue = d => d.price;
      const yValue = d => d.name;
      const textValue = d => `${d.name} $${d.price}`
      const verticalSpacing = 60;

      const svg = d3.select('svg');
      const width = +svg.attr('width');

      const margin = { left: 220, right: 220, top: 20, bottom: 20 };
      const innerWidth = width - margin.left - margin.right;

      const xScale = d3.scaleLinear().range([0, innerWidth]);
      const yScale = d3.scaleBand()
        .paddingInner(0.1)
        .paddingOuter(0.05);

      function render(selection, data){
        xScale.domain([0, d3.max(data, xValue)]);
        yScale
          .domain(data.map(yValue))
          .range([0, verticalSpacing * data.length]);

        let g = selection.selectAll('g').data([null]);
        g = g.enter().append('g')
          .merge(g)
            .attr('transform', `translate(${margin.left},${margin.top})`);

        const groups = g.selectAll('g').data(data);
        groups.exit().remove();
        const groupsEnter = groups.enter().append('g');
        groups
          .merge(groupsEnter)
            .attr('transform', d => `translate(0,${yScale(yValue(d))})`);

        const rects = groupsEnter
          .append('rect')
            .attr('fill', 'steelblue')
          .merge(groups.select('rect'))
            .attr('width', d => xScale(xValue(d)))
            .attr('height', yScale.bandwidth());

        const textBackground = groupsEnter
          .append('text')
            .attr('class', 'background')
            .style('font-size', '32pt')
            .style('font-family', 'Sans-Serif')
            .attr('x', 5)
            .attr('dy', '0.32em')
            .attr('fill', 'none')
            .attr('stroke', 'white')
            .attr('stroke-width', 5)
            .attr('stroke-linejoin', 'round')
          .merge(groups.select('.background'))
            .attr('y', yScale.bandwidth() / 2)
            .text(textValue);

        const textForeground = groupsEnter
          .append('text')
            .attr('class', 'foreground')
            .style('font-size', '32pt')
            .style('font-family', 'Sans-Serif')
            .attr('x', 5)
            .attr('dy', '0.32em')
          .merge(groups.select('.foreground'))
            .attr('y', yScale.bandwidth() / 2)
            .text(textValue);
      }

      d3.json('data.json', data => {
        data.forEach((list, i) => {
          setTimeout(() => {
            render(svg, list);
          }, i * 1000);
        });
      });

      //render(svg, [ { name: 'Milk', price: 3 } ]);

      //setTimeout(() => {
      //  render(svg, [ { name: 'Milk', price: 3 }, { name: 'Eggs', price: 20 } ]);
      //}, 1000);

      //setTimeout(() => {
      //  render(svg, [ { name: 'Milk', price: 3 }, { name: 'Eggs', price: 2 } ]);
      //}, 2000);

      //setTimeout(() => {
      //  render(svg, [
      //    { name: 'Milk', price: 3 },
      //    { name: 'Eggs', price: 2 },
      //    { name: 'Cupcakes', price: 5 }
      //  ]);
      //}, 3000);

      //setTimeout(() => {
      //  render(svg, [ { name: 'Milk', price: 3 }, { name: 'Eggs', price: 2 } ]);
      //}, 4000);
    </script>
  </body>
</html>

data.json

[
  [
    { "name": "Milk", "price": 3 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 20 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Cupcakes", "price": 5 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Cookies", "price": 6 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 },
    { "name": "Smoked Salmon", "price": 14.75 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 },
    { "name": "Smoked Salmon", "price": 14.75 },
    { "name": "Broccoli", "price": 3.65 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 },
    { "name": "Smoked Salmon", "price": 14.75 },
    { "name": "Broccoli", "price": 3.65 },
    { "name": "Coffee", "price": 5.99 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 },
    { "name": "Smoked Salmon", "price": 14.75 },
    { "name": "Broccoli", "price": 3.65 },
    { "name": "Coffee", "price": 5.99 },
    { "name": "Sugar", "price": 9.98 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 },
    { "name": "Smoked Salmon", "price": 14.75 },
    { "name": "Broccoli", "price": 3.65 },
    { "name": "Coffee", "price": 5.99 },
    { "name": "Sugar", "price": 9.98 },
    { "name": "Mozzarella Cheese", "price": 4 }
  ],
  [
    { "name": "Milk", "price": 3 },
    { "name": "Eggs", "price": 2 },
    { "name": "Apples", "price": 4 },
    { "name": "Bread", "price": 4 },
    { "name": "Bananas", "price": 1 },
    { "name": "Onions", "price": 2 },
    { "name": "Garlic", "price": 1 },
    { "name": "Smoked Salmon", "price": 14.75 },
    { "name": "Broccoli", "price": 3.65 },
    { "name": "Coffee", "price": 5.99 },
    { "name": "Sugar", "price": 9.98 },
    { "name": "Mozzarella Cheese", "price": 4 },
    { "name": "Tomatoes", "price": 3 }
  ]
]