block by jermspeaks 9902b56ec6dc1a3c5b25

fun block

Full Screen

Built with blockbuilder.org

index.html

<!DOCTYPE html>
  <head>
    <meta charset="utf-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <style>
      body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
      svg { width: 100%; height: 100%; }
    </style>
  </head>

  <body>
    <div class="container"></div>
    <script>
        /* =======================================
      Attributes
     ======================================= */
  var w = $(window).width() - 200;
  var h = 200;

  // Padding
  var textPadding = 10;
  var rightEdgePadding = 40;
  var leftViewButtonPadding = 5;
  var rightViewButtonPadding = 10;

  // Text Line Height
  var lineHeight = 8;

  // Label Value Formatter
  var valueFormatter = d3.format('.2s');

  // Element Widths
  var yAxisLabelWidth = 100;
  var viewButtonWidth = 75;

  // Start Position for Bars
  var startBars = viewButtonWidth + yAxisLabelWidth;

  // End Position for Y Axis Labels
  var endYAxisLabels = viewButtonWidth + yAxisLabelWidth - textPadding;

  // Color of Selected Group
  var selectedColor = '150,222,136';

  // Find Start Position for Bar Label
  function startBarLabelPosition(d) {
    return viewButtonWidth + yAxisLabelWidth + xScale(d) + textPadding;
  }

  /* =======================================
      Data
     ======================================= */
  var dataset = {
    data: [{
      value: 934,
      category: '10+ Page Views',
      color: '186, 38, 43'
    }, {
      value: 6000,
      category: '5-9 Page Views',
      color: '212, 80, 51'
    }, {
      value: 12000,
      category: '2-4 Page Views',
      color: '246, 142, 53'
    }, {
      value: 48000,
      category: '1 Page View',
      color: '255,190,55'
    }, {
      value: 64000,
      category: 'All',
      color: '35,80,116'
    }],
    // data: [934, 6000, 12000, 48000, 64000],
    // categories: ['10+ Page Views', '5-9 Page Views', '2-4 Page Views', '1 Page View', 'All'],
    // colors: ['186, 38, 43', '212,80,51', '246,142,53', '255,190,55', '35,80,116', '150,222,136'],
    selected: 0
  };

  /* =======================================
      Scales
     ======================================= */

  // Max Range for width of bars
  var maxRange = w - viewButtonWidth - yAxisLabelWidth - rightEdgePadding;
  var xScale = d3.scale.linear()
    .domain([0, d3.max(dataset.data, function(d) {
      return d.value;
    })])
    .range([10, maxRange]);

  var yScale = d3.scale.ordinal()
    .domain(d3.range(dataset.data.length))
    .rangeRoundBands([0, h], 0.2);

  /* =======================================
      SVG Element
     ======================================= */
  var svg = d3.select('.container')
    .append('svg')
    .attr('width', w)
    .attr('height', h);
    // .style('border', '1px solid black');

  // Create Chart
  createChart();

  /* =======================================
      Event Handlers
     ======================================= */

  // Mouse Events
  function createBarEvents() {
    svg.selectAll('.bar')
      .on('mouseover', function(d, i) {
        d3.select(this)
          .attr('fill', function(d) {
            var index = dataset.data.indexOf(d);
            return 'rgba(' + dataset.data[index].color + ', 0.4)';
          });
      })
      .on('mouseout', function(d, i) {
        d3.select(this)
          .attr('fill', function(d, i) {
            var index = dataset.data.indexOf(d);
            return 'rgb(' + dataset.data[index].color + ')';
          });
      });
  }

  function createViewButtonEvents() {
    svg.selectAll('.view-button-group')
      .on('mouseover', function(d, i) {
        d3.select(this).select('rect')
          .attr('fill', function(d) {
            return 'rgba(' + dataset.data[2].color + ', 0.4)';
          });
        d3.select(this).select('text')
          .attr('fill', 'black');
      })
      .on('mouseout', function(d, i) {
        d3.select(this).select('rect')
          .attr('fill', function(d) {
            return 'rgb(' + dataset.data[2].color + ')';
          });
        d3.select(this).select('text')
          .attr('fill', 'white');
      })
      .on('click', function(d, i) {
        event.preventDefault();
        console.log(d);
        // remove view button
        // insert new selected bar group
        // insert view button in previously selected bar group
      });
  }

  // On Window Resize
  window.onresize = function(event) {
    // Update Width
    w = $(window).width() - 200;

    // Update Max Range
    maxRange = w - viewButtonWidth - yAxisLabelWidth - rightEdgePadding;

    // Update xScale
    xScale = d3.scale.linear()
      .domain([0, d3.max(dataset.data, function(d) {
        return d.value;
      })])
      .range([10, maxRange]);

    // Resize SVG
    svg.attr('width', w);

    // Resize Bar Labels
    svg.selectAll(".bar-label")
      .data(dataset.data)
      .transition()
      .delay(function(d, i) {
        return i / dataset.data.length * 1000;
      })
      .duration(150)
      .attr("x", function(d, i) {
        return startBarLabelPosition(d.value);
      });

    // Resize Bars
    svg.selectAll('.bar')
      .data(dataset.data)
      .transition()
      .delay(function(d, i) {
        return i / dataset.data.length * 1000;
      })
      .duration(200)
      .ease('linear')
      .attr('width', function(d) {
        return xScale(d.value);
      });
  };

  /* =======================================
      Chart Generation Functions
     ======================================= */

  function createChart() {
    selectedBarGroup();
    createBarGroups();
    createBarEvents();
    createViewButtonEvents();
    selectedBarGroup();
  }

  function createBarGroups() {
    var barGroups = svg.selectAll('.bar-group')
      .data(dataset.data)
      .enter()
      .append("g")
      .classed("bar-group", true);

    createBar(barGroups);
    createYAxisLabel(barGroups);
    createBarLabel(barGroups);
    createViewButton(barGroups);
    removeViewButton(barGroups);
  }

  // Create Bar
  function createBar(groupSelector) {
    groupSelector.append('rect')
      .classed('bar', true)
      .attr('x', viewButtonWidth + yAxisLabelWidth)
      .attr('y', function(d, i) {
        return yScale(i);
      })
      .attr('width', function(d) {
        return xScale(d.value);
      })
      .attr('height', yScale.rangeBand())
      .attr('fill', function(d, i) {
        return 'rgb(' + d.color + ')';
      });
  }

  // Create yAxis Labels
  function createYAxisLabel(groupSelector) {
    groupSelector.append("text")
      .classed('xAxis-label', true)
      .text(function(d, i) {
        return d.category;
      })
      .attr("x", 90 + viewButtonWidth)
      .attr("y", function(d, i) {
        return yScale(i) + (lineHeight / 2) + (yScale.rangeBand() / 2);
      })
      .attr("font-family", "sans-serif")
      .attr("font-size", "12px")
      .attr("fill", "black")
      .style({
        "text-anchor": "end"
      });
  }

  // Create Bar Labels
  function createBarLabel(groupSelector) {
    groupSelector.append("text")
      .classed('bar-label', true)
      .text(function(d, i) {
        return valueFormatter(d.value);
      })
      .attr("x", function(d, i) {
        return startBarLabelPosition(d.value);
      })
      .attr("y", function(d, i) {
        return yScale(i) + (lineHeight / 2) + (yScale.rangeBand() / 2);
      })
      .attr("font-family", "sans-serif")
      .attr("font-size", "12px")
      .attr("font-weight", 600)
      .attr("fill", "black");
  }

  // View Buttons
  function createViewButton(groupSelector) {
    var viewButtonGroup = groupSelector.append("g")
      .classed("view-button-group", true)
      .style({
        'cursor': 'pointer'
      });

    // View Button Rectangle
    viewButtonGroup.append("rect")
      .classed('view-button', true)
      .attr("x", leftViewButtonPadding)
      .attr("y", function(d, i) {
        return yScale(i);
      })
      .attr("width", viewButtonWidth - rightViewButtonPadding)
      .attr("height", yScale.rangeBand())
      .attr("rx", 5)
      .attr("ry", 5)
      .attr("fill", function(d) {
        return 'rgb(' + dataset.data[2].color + ')';
      });

    // View Button Text
    viewButtonGroup.append("text")
      .classed('view-text', true)
      .text('View')
      .attr("x", (leftViewButtonPadding + (viewButtonWidth - rightViewButtonPadding)) / 2)
      .attr("y", function(d, i) {
        return yScale(i) + (lineHeight / 2) + (yScale.rangeBand() / 2);
      })
      .attr("font-family", "sans-serif")
      .attr("font-size", "12px")
      .attr("fill", "white")
      .attr("text-anchor", "middle");
  }

  // Remove Selected View Button
  function removeViewButton(groupSelector) {
    groupSelector.each(function(d, i) {
      if (i === dataset.selected) {
        d3.select(this).select('.view-button-group').remove();
      }
    })
  }

  // Selected Bar Group Rectangle
  function selectedBarGroup() {
    var selectedBarGroup = svg.selectAll('.selected-bar-group')
      .data([dataset.selected])
      .enter()
      .append("g")
      .classed("selected-bar-group", true)

    selectedBarGroup.append("rect")
      .classed('selected-bar-overlay', true)
      .attr("x", leftViewButtonPadding)
      .attr("y", function(d, i) {
        return yScale(d);
      })
      .attr("width", viewButtonWidth + yAxisLabelWidth - rightViewButtonPadding)
      .attr("height", yScale.rangeBand())
      .attr("rx", 5)
      .attr("ry", 5)
      .attr("fill", function(d) {
        return 'rgb(' + selectedColor + ')';
      });
  }
    </script>
  </body>