Skip to content

Instantly share code, notes, and snippets.

@ne8il
Last active December 15, 2015 01:59

Revisions

  1. ne8il revised this gist Mar 18, 2013. 1 changed file with 31 additions and 3 deletions.
    34 changes: 31 additions & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -11,7 +11,7 @@
    }

    ul {
    list-style: none;
    list-style: none;
    }

    .peopleDiv {
    @@ -98,6 +98,8 @@
    <div id="formArea">
    <ul>
    <li> <button id="shuffleButton">Shuffle</button></li>
    <li> <button id="ascButton">Ascending</button></li>
    <li> <button id="descButton">Descending</button></li>
    </ul>
    </div>
    </div>
    @@ -300,16 +302,38 @@
    */
    var shuffle = function(){

    people.sort(function(a, b){
    sortAndBuild(function(a, b){
    var chance = !!Math.round(Math.random() * 1);
    return chance ? 1 : -1;
    });
    }

    /**
    * sort in ascending order
    */
    var asc = function(){

    sortAndBuild(function(a, b){
    return a['weight'] > b['weight'];
    });
    }

    /**
    * Randomly shuffles our people and rebuilds chart
    */
    var desc = function(){
    sortAndBuild(function(a, b){
    return a['weight'] < b['weight'];
    });
    }

    var sortAndBuild = function(sortFunction){
    people.sort(sortFunction);

    populateRemoveSelect();
    buildChart();
    }


    //event listener to add a new person
    d3.select('#addButton')
    .on('click', addPerson);
    @@ -320,7 +344,11 @@
    d3.select('#shuffleButton')
    .on('click', shuffle);

    d3.select('#ascButton')
    .on('click', asc);

    d3.select('#descButton')
    .on('click', desc);

    populateRemoveSelect();

  2. ne8il created this gist Mar 17, 2013.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Going overboard on features
    330 changes: 330 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,330 @@
    <!DOCTYPE html>
    <meta charset="utf-8">
    <head>
    <style>

    body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    width: 960px;
    padding:20px;
    position: relative;
    }

    ul {
    list-style: none;
    }

    .peopleDiv {
    display:inline-block;
    position:relative;
    height:30px;
    line-height:30px;
    width:100px;
    text-align:center;
    }

    svg {
    padding:20px;
    }

    .axis path,
    .axis line {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
    }

    .axis text {
    font-family: sans-serif;
    font-size: 11px;
    }

    #formArea {
    border:1px solid #c3c3c3;
    background-color:#f1f1f1;
    border-radius:5px;
    width:200px;
    padding:10px;
    margin:10px;
    float:left;
    height:240px;
    }
    #formArea input{
    display:block;
    margin: 10px 0px;
    }

    button {
    border:1px solid #a3a3a3;
    background-color:#d3d3d3;
    padding:5px;
    width:100px;
    border-radius:10px;
    cursor: pointer;
    }
    button:hover {
    background-color:#c3c3c3;
    }
    button:active {
    background-color:#a3a3a3;
    }

    </style>
    </head>
    <body>

    <div id="svgArea"></div>

    <div class="forms">
    <div id="formArea">
    <ul>
    <li><label>Name<input type="text" id="nameInput"/></label></li>
    <li><label>Weight<input type="number" min="100" max="500" id="weightInput"/></label></li>
    <li><label>Color<input type="color" id="colorInput"/></label></li>
    <li> <button id="addButton">Add</button></li>
    </ul>


    </div>

    <div id="formArea">
    <ul>
    <li><label>Name<select id="removeSelect"/>
    </select></label></li>
    <li> <button id="removeButton">Remove</button></li>
    </ul>
    </div>

    <div id="formArea">
    <ul>
    <li> <button id="shuffleButton">Shuffle</button></li>
    </ul>
    </div>
    </div>

    </body>

    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>

    var people = [{'name' : 'Frank', 'color' : 'blue', 'weight' : 180},
    {'name' : 'Tom', 'color' : 'red', 'weight' : 230},
    {'name' : 'Peter', 'color' : 'green', 'weight' : 190},
    {'name' : 'Mary', 'color' : 'purple', 'weight' : 150}];


    var chartWidth = 800,
    chartHeight = 250,
    padding = 30,
    duration = 1000; //transition length (in ms)


    var svg = d3.select('#svgArea')
    .append('svg')
    .attr('width', chartWidth)
    .attr('height', chartHeight);


    /*
    * Append our axis groups before rendering chart
    */

    var yAxisGroup = svg.append("g")
    .classed('axis', true)
    .classed('y-axis', true)
    .attr("transform", "translate(" + padding + ",0)")

    var xAxisGroup = svg.append("g")
    .classed('axis', true)
    .attr('transform', 'translate(' + padding + ', ' + chartHeight + ')');

    var buildChart = function(){
    /** SCALES */

    var min = d3.min(people, function(d){return d['weight']});
    var max = d3.max(people, function(d){return d['weight']});

    var yScale = d3.scale.linear()
    .domain([0, max])
    .rangeRound([0, chartHeight]);




    //populate an array of names to use for our ordinal scale
    var nameCats = people.map(function(d){ return d['name']});

    var xScale = d3.scale.ordinal()
    .domain(nameCats)
    .rangeBands([0, chartWidth]);


    var rect = svg.selectAll("rect")
    .data(people, function(d) {
    return d['name']
    });

    var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient('bottom');

    xAxisGroup
    .transition()
    .duration(duration)
    .call(xAxis);


    rect.enter()
    .insert('rect')
    .classed('chartBlock', true)
    .style('fill', function(d){
    return d['color']
    })
    .attr('x', function(d, i){
    return xScale(d['name']) - .5 + 2.5 + padding;
    })
    .attr('y', function(d){
    return (chartHeight - yScale(d['weight']))
    })
    .attr('height', function(d){
    return yScale(d['weight']);
    })
    .attr('width', chartWidth / people.length - 5);


    //remove anything we've deleted
    rect.exit()
    .remove();

    //when transitioning, we don't have to worry about the color
    //but everything else could have changed
    rect.transition()
    .duration(duration)
    .attr("x", function(d, i) {
    return xScale(d['name']) - .5 + 2.5 + padding;
    })
    .attr('y', function(d){
    return (chartHeight - yScale(d['weight']))
    })
    .attr('height', function(d){
    return yScale(d['weight']);
    })
    .attr('width', chartWidth / people.length - 5);

    var yAxisScale = d3.scale.linear()
    .domain([0, max])
    .rangeRound([chartHeight, 0]);

    var yAxis = d3.svg.axis()
    .scale(yAxisScale)
    .orient('left')
    .ticks(10);


    yAxisGroup.transition()
    .duration(duration)
    .call(yAxis);
    }



    /** Event Handlers and Functions */


    /**
    * Add person to chart
    * Name is required
    */
    var addPerson = function(){

    var nameInput = d3.select('#nameInput').node();
    var weightInput = d3.select('#weightInput').node();
    var colorInput = d3.select('#colorInput').node();

    if(nameInput.value == '') return;

    var weight = Math.min(Math.max(weightInput.value, 100), 500);

    var newPerson = {
    'name' : nameInput.value,
    'color' : colorInput.value,
    'weight' : weight
    }

    people.push(newPerson);

    populateRemoveSelect();

    //clear out inputs
    nameInput.value = '';
    weightInput.value = '';
    colorInput.value = '';

    //refresh chart
    buildChart();
    }

    /**
    * remove selected person
    */
    var removePerson = function(){
    var removeInput = d3.select('#removeSelect').node();
    var name = removeInput.value;

    //easiest way to splice this person out
    people = people.filter(function(person){
    return person['name'] != name;
    });

    populateRemoveSelect();
    buildChart();
    }

    /**
    * Fills in remove select with our names
    */
    var populateRemoveSelect = function(){
    var removeInput = d3.select('#removeSelect').node();

    //clear existing options
    removeInput.options.length = 0;

    people.forEach(function(name){
    var display = name['name'];
    removeInput.add(new Option(display, display));
    });
    }

    /**
    * Randomly shuffles our people and rebuilds chart
    */
    var shuffle = function(){

    people.sort(function(a, b){
    var chance = !!Math.round(Math.random() * 1);
    return chance ? 1 : -1;
    });

    populateRemoveSelect();
    buildChart();
    }


    //event listener to add a new person
    d3.select('#addButton')
    .on('click', addPerson);

    d3.select('#removeButton')
    .on('click', removePerson);

    d3.select('#shuffleButton')
    .on('click', shuffle);



    populateRemoveSelect();

    //initial render of chart
    buildChart();

    </script>