block by curran acde35df0c7939ff97740b4f9800258e

Counter

Full Screen

A counter app that demonstrates usage of d3-component. Inspired by Redux Counter Example.

The following components are defined and used to construct the app:

Built with blockbuilder.org

forked from curran‘s block: Stopwatch


index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://unpkg.com/d3@4"></script>
  <script src="https://unpkg.com/d3-component@3"></script>
  <script src="https://unpkg.com/redux@3/dist/redux.min.js"></script>
  <style>
    body {
      text-align: center;
      margin-top: 75px;
    }
    .count-display {
      color: #3d3d3d;
      font-size: 10em;
      font-family: sans;
      cursor: default;
    }
    button {
      background-color: #7c7c7c;
      border: solid 3px #7c7c7c;
      border-radius: 11px;
      color: white;
      padding: 20px 60px;
      margin: 20px;
      font-size: 58px;
      cursor: pointer;
    }
    button:hover {
      border: solid 3px black;
    }
    button:focus {
      outline: none;
    }
  </style>
</head>
<body>
  <script>
    
    // A component that renders the count.
    var countDisplay = d3.component("div", "count-display")
      .render(function (selection, d){
        selection.text(d.count); 
      });
    
    // A generic Button component.
    var button = d3.component("button")
      .render(function (selection, d){
        selection
            .text(d.text)
            .on("click", d.onClick);
      });
    
    // The panel that contains the two buttons.
    var buttonPanel = d3.component("div", "button-panel")
      .render(function (selection, d){
        selection.call(button, [
          {
            text: "+",
            onClick: d.actions.increment
          },{
            text: "-",
            onClick: d.actions.decrement
          },
        ]);
      });
    
    // The top-level app component.
    var app = d3.component("div")
      .render(function (selection, d){
        selection
            .call(countDisplay, d)
            .call(buttonPanel, d);
      });
    
    
    function main(){
      var store = Redux.createStore(reducer),
          actions = actionsFromDispatch(store.dispatch);
      
      render();
      store.subscribe(render);
      
      function reducer (state, action){
        var count = state || 0;
        switch (action.type) {
          case "INCREMENT": return count + 1;
          case "DECREMENT": return count - 1;
          default: return count;
        }
      }

      function actionsFromDispatch(dispatch){
        return {
          increment: function (){
            dispatch({ type: "INCREMENT" });
          },
          decrement: function (){
            dispatch({ type: "DECREMENT" });
          }
        }
      }

      function render(){
        d3.select("body").call(app, {
          count: store.getState(),
          actions: actions
        });
      }
    }
    main();

  </script>
</body>