Pokemon

Create interactive visualizations for the Pokemon data. Complete the script so that when a user clicks on each menu button, there will be a different bar chart shown in the Viz block.

You will be reusing the code you wrote for generating SVG bar charts a couple weeks ago. The main challenge is to figure out how to connect your visualization code with the front-end code (event handlers ... etc).

Viz

Data is not loaded yet

// pokemonData is a global variable
pokemonData = 'not loaded yet'

$.get('/data/pokemon-small.json')
 .success(function(data){
     console.log('data loaded', data)
     // Show in the myviz that the data is loaded
     $('.myviz').html('number of records load:' + data.length)
     pokemonData = data          
 })


function vizAsHorizontalBars() {

    // define a template string
    var tplString = '<g transform="translate(0 ${d.y})"> \
                    <rect                                \
                         width="${d.width}"              \
                         height="20"                     \
                         style="fill:${d.color};         \
                                stroke-width:3;          \
                                stroke:rgb(0,0,0)" />    \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return 0
    }

    function computeWidth(d, i) {
        return d.Attack
    }

    function computeY(d, i) {
        return i * 20
    }

    function computeColor(d, i) {
        return 'red'
    }

    var viz = _.map(pokemonData, function(d, i) {
                return {
                    x: computeX(d, i),
                    y: computeY(d, i),
                    width: computeWidth(d, i),
                    color: computeColor(d, i)
                }
             })
    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-horizontal').click(vizAsHorizontalBars)

// for each of the TODOs below, you will write a "callback function" similar
// to vizAsHorizontalBars and a $('something').click to add this callback
// function to respond to the click event of a particular button

// Visualize the attack points as a series of vertical bars (without labels)

function vizAsVerticalBars() {

    // define a template string
    var tplString = '<g transform="translate(${d.x} 0)"> \
                    <rect                                \
                         width="20"                      \
                         height="${d.height}"            \
                         style="fill:${d.color};         \
                                stroke-width:3;          \
                                stroke:rgb(0,0,0)" />    \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return i * 30
    }

    function computeY(d, i) {
        return 0
    }

    function computeWidth(d, i) {
        return 20
    }

    function computeHeight(d, i) {
        return d.Attack
    }

    function computeColor(d, i) {
        return 'red'
    }

    var viz = _.map(pokemonData, function(d, i) {
                return {
                    x: computeX(d, i),
                    y: computeY(d, i),
                    width: computeWidth(d, i),
                    height: computeHeight(d, i),
                    color: computeColor(d, i)
                }
             })
    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-vertical').click(vizAsVerticalBars)

// Visualize the attack points vs. defense
// points as side-by-side horizontal bar charts (with labels)

function vizAsHorizontalLabelBars() {

    // define a template string
    var tplString = '<g transform="translate(120 ${d.y})">   \
                         <rect                               \
                              x="-${d.attackwidth}"          \
                              width="${d.attackwidth}"       \
                              height="20"                    \
                              style="fill:${d.attackcolor};  \
                                     stroke-width:1;         \
                                     stroke:rgb(0,0,0)" />   \
                         <rect                               \
                              x=0                            \
                              width="${d.defensewidth}"      \
                              height="20"                    \
                              style="fill:${d.defensecolor}; \
                                     stroke-width:1;         \
                                     stroke:rgb(0,0,0)" />   \
                         <text transform="translate(0 15)">  \
                             ${d.label}                      \
                         </text>                             \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return 120
    }

    function computeAttackWidth(d, i) {
        return d.Attack
    }

    function computeDefenseWidth(d, i) {
        return d.Defense
    }

    function computeY(d, i) {
        return i * 20
    }

    function computeAttackColor(d, i) {
        return 'red'
    }

    function computeDefenseColor(d, i) {
        return 'blue'
    }

    function computeLabel(d, i) {
        return d.Name
    }

    var viz = _.map(pokemonData, function(d, i){
                return {
                    x: computeX(d, i),
                    y: computeY(d, i),
                    attackwidth: computeAttackWidth(d, i),
                    defensewidth: computeDefenseWidth(d, i),
                    attackcolor: computeAttackColor(d, i),
                    defensecolor: computeDefenseColor(d, i),
                    label: computeLabel(d, i)
                }
             })
    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-attack-defense').click(vizAsHorizontalLabelBars)

// Visualize the speed points vs. defense
// points as side-by-side horizontal bar charts (with labels)

function vizSpeedDefense() {

    // define a template string
    var tplString = '<g transform="translate(120 ${d.y})">   \
                         <rect                               \
                              x="-${d.speedwidth}"          \
                              width="${d.speedwidth}"       \
                              height="20"                    \
                              style="fill:${d.speedcolor};  \
                                     stroke-width:1;         \
                                     stroke:rgb(0,0,0)" />   \
                         <rect                               \
                              x=0                            \
                              width="${d.defensewidth}"      \
                              height="20"                    \
                              style="fill:${d.defensecolor}; \
                                     stroke-width:1;         \
                                     stroke:rgb(0,0,0)" />   \
                         <text transform="translate(0 15)">  \
                             ${d.label}                      \
                         </text>                             \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return 120
    }

    function computeSpeedWidth(d, i) {
        return d.Speed
    }

    function computeDefenseWidth(d, i) {
        return d.Defense
    }

    function computeY(d, i) {
        return i * 20
    }

    function computeSpeedColor(d, i) {
        return 'red'
    }

    function computeDefenseColor(d, i) {
        return 'blue'
    }

    function computeLabel(d, i) {
        return d.Name
    }

    var viz = _.map(pokemonData, function(d, i){
                return {
                    x: computeX(d, i),
                    y: computeY(d, i),
                    speedwidth: computeSpeedWidth(d, i),
                    defensewidth: computeDefenseWidth(d, i),
                    speedcolor: computeSpeedColor(d, i),
                    defensecolor: computeDefenseColor(d, i),
                    label: computeLabel(d, i)
                }
             })
    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-speed-defense').click(vizSpeedDefense)

// TODO: add code to visualize the attack points in ascending order as a
// series of horizontal bar charts (with labels)

function vizAttackSortedAsc() {

    // define a template string
    var tplString = '<g transform="translate(0 ${d.y})">     \
                    <rect                                    \
                         width="${d.width}"                  \
                         height="20"                         \
                         style="fill:${d.color};             \
                                stroke-width:3;              \
                                stroke:rgb(0,0,0)" />        \
                         <text transform="translate(0 15)">  \
                             ${d.label}                      \
                         </text>                             \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return 0
    }

    function computeY(d, i) {
        return i * 20
    }

    function computeWidth(d, i) {
        return d.Attack
    }

    function computeColor(d, i) {
        return 'red'
    }

    function computeLabel(d, i) {
        return d.Name
    }

    var viz = _.chain(pokemonData).sortBy(function(obj) {
        return obj['Attack']
    }).map(function(d, i){
        return {
            x: computeX(d, i),
            y: computeY(d, i),
            label: computeLabel(d, i),
            width: computeWidth(d, i),
            color: computeColor(d, i)
        }
    }).value()

    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-horizontal-sorted').click(vizAttackSortedAsc)

// TODO: add code to visualize the attack points in descending order as a
// series of horizontal bar charts (with labels)

function vizAttackSortedDesc() {

    // define a template string
    var tplString = '<g transform="translate(0 ${d.y})">     \
                    <rect                                    \
                         width="${d.width}"                  \
                         height="20"                         \
                         style="fill:${d.color};             \
                                stroke-width:3;              \
                                stroke:rgb(0,0,0)" />        \
                         <text transform="translate(0 15)">  \
                             ${d.label}                      \
                         </text>                             \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return 0
    }

    function computeY(d, i) {
        return i * 20
    }

    function computeWidth(d, i) {
        return d.Attack
    }

    function computeColor(d, i) {
        return 'red'
    }

    function computeLabel(d, i) {
        return d.Name
    }

    var viz = _.chain(pokemonData).sortBy(function(obj) {
        return -obj['Attack']
    }).map(function(d, i){
        return {
            x: computeX(d, i),
            y: computeY(d, i),
            label: computeLabel(d, i),
            width: computeWidth(d, i),
            color: computeColor(d, i)
        }
    }).value()

    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-horizontal-sorted-desc').click(vizAttackSortedDesc)

// TODO: add code to visualize the attack points as a series of horizontal bar
// charts (with labels), and using the brightness of red to represent speed
// and width to represent attack points

function vizAttackSpeed() {

    // define a template string
    var tplString = '<g transform="translate(0 ${d.y})">     \
                    <rect                                    \
                         width="${d.width}"                  \
                         height="20"                         \
                         style="fill:${d.color};             \
                                stroke-width:3;              \
                                stroke:rgb(0,0,0)" />        \
                         <text transform="translate(0 15)">  \
                             ${d.label}                      \
                         </text>                             \
                    </g>'

    // compile the string to get a template function
    var template = _.template(tplString)

    function computeX(d, i) {
        return 0
    }

    function computeWidth(d, i) {
        return d.Attack
    }

    function computeY(d, i) {
        return i * 20
    }

    function computeLabel(d, i) {
        return d.Name
    }

    function computeColor(d, i) {
        // FIXME: Not sure why this is breaking the viz?
        // var value = _.round((255 * d.Speed)/(_.max(_.pluck(data, 'Speed'))))
        // var string = 'rgb(' + value + ',0,0)'
        // return string
        return 'rgb(' + d['Speed'] + ', 0, 0)'
    }

    var viz = _.map(pokemonData, function(d, i) {
                return {
                    x: computeX(d, i),
                    y: computeY(d, i),
                    width: computeWidth(d, i),
                    color: computeColor(d, i),
                    label: computeLabel(d, i)
                }
             })
    console.log('viz', viz)

    var result = _.map(viz, function(d){
             // invoke the compiled template function on each viz data
             return template({d: d})
         })
    console.log('result', result)

    $('.myviz').html('<svg>' + result + '</svg>')
}

$('button#viz-attack-speed').click(vizAttackSpeed)