D3: gráfico de barras Volver


Gráfico en d3 usando divs

Ver template Ver solución

Ver template jsFiddle Ver solución jsFiddle

Actividad D3: Dada la información de los goleadores de los mundiales crear un gráfico de barras horizontales, usando divs de HTML, d3.js y CSS.

//Crear Divs
  d3.select("#chart")
      .selectAll("div")
      .data(data)
      .enter().append("div")
      .style("width", function(d) { return 10*d.goles + "px"; })
      .text(function(d) { return d.goles; });

Escalas

Calcular el máximo y agregar escala para el ancho de los divs.

//Gol Máximo
var golesMax = d3.max(data,function(d){
      return d.goles;
    });

//Escala X
var x = d3.scale.linear()
    .domain([0, golesMax ])
    .range([0, 400]);

//Crear Divs
d3.select("#chart")
    .selectAll("div")
    .data(data)
    .enter().append("div")
    .style("width", function(d) { return x(d.goles) + "px"; })
    .text(function(d) { return d.nombre + ' - ' + d.goles; });

Gráfico en d3 usando svg

Ver template Ver solución

Ver template jsFiddle Ver solución jsFiddle

Actividad D3: Dada la información de los goleadores de los mundiales crear un gráfico de barras verticales, usando rect de SVG, d3.js y CSS.

// Tamaños
var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

//Escalas
var jugadores = data.map(function(d) { return d.nombre; });

var golesMax = d3.max(data,function(d){
      return d.goles;
    });

var x = d3.scale.ordinal()
  .domain(jugadores)
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
  .domain([0,golesMax])
    .range([height, 0]);

// Crear SVG
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

//Crear barras
svg.selectAll(".bar")
    .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.nombre); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.goles); })
      .attr("height", function(d) { return height - y(d.goles); });

Luego agregamos los ejes

//Ejes
var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

Le damos estilo a los elementos SVG de los ejes:

.axis {
  font-size: 10px;
  font-family: sans-serif;
}
.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

Rotamos los labels para que puedan leerse (agrandamos el margen inferior si se cortan los nombres):

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis)
    .selectAll("text")
    .attr("y", 0)
    .attr("x", 10)
    .attr("dy", ".20em")
    .attr("transform", "rotate(90)")
    .style("text-anchor", "start");

Interacción, traemos los datos y los mostramos en consola:

//Interaccion del mouse sobre las barras
.on("mouseenter", function(d){
  console.log('entro',d);
})
.on("mouseout", function(d){
  console.log('salgo',d);
});

Creamos un div de detalle para mostrar los datos:

<div id="detalles"></div>

Llenamos el div que preparamos con información cuando pasamos por arriba y cuando salimos lo limpiamos:

.on("mouseenter", function(d){
  d3.select('#detalles').html(d.nombre+' metió '+d.goles+' goles.');
})
.on("mouseout", function(d){
  d3.select('#detalles').html('...');
});

Interacción, desde CSS:

rect{
  fill:blue;
}

rect:hover{
  fill:red;
}

¿Quedó similar a esto la solución?

Goleadores en mundiales JSON

[
{"nombre":"Miroslav Klose","equipo":"Alemania","goles":16,"partidos":24,"promedio":0.67},
{"nombre":"Ronaldo","equipo":"Brasil","goles":15,"partidos":19,"promedio":0.79},
{"nombre":"Gerd Müller","equipo":"Alemania","goles":14,"partidos":13,"promedio":1.08},
{"nombre":"Just Fontaine","equipo":"Francia","goles":13,"partidos":6,"promedio":2.17},
{"nombre":"Pelé","equipo":"Brasil","goles":12,"partidos":14,"promedio":0.86},
{"nombre":"Sándor Kocsis","equipo":"Hungría","goles":11,"partidos":5,"promedio":2.2},
{"nombre":"Jürgen Klinsmann","equipo":"Alemania","goles":11,"partidos":17,"promedio":0.65},
{"nombre":"Helmut Rahn","equipo":"Alemania","goles":10,"partidos":10,"promedio":1},
{"nombre":"Gabriel Batistuta","equipo":"Argentina","goles":10,"partidos":12,"promedio":0.83},
{"nombre":"Gary Lineker","equipo":"Inglaterra","goles":10,"partidos":12,"promedio":0.83},
{"nombre":"Thomas Müller","equipo":"Alemania","goles":10,"partidos":13,"promedio":0.77},
{"nombre":"Teófilo Cubillas","equipo":"Perú","goles":10,"partidos":13,"promedio":0.77},
{"nombre":"Grzegorz Lato","equipo":"Polonia","goles":10,"partidos":20,"promedio":0.5},
{"nombre":"Eusébio","equipo":"Portugal","goles":9,"partidos":6,"promedio":1.5},
{"nombre":"Christian Vieri","equipo":"Italia","goles":9,"partidos":9,"promedio":1},
{"nombre":"Vavá","equipo":"Brasil","goles":9,"partidos":10,"promedio":0.9},
{"nombre":"David Villa","equipo":"España","goles":9,"partidos":12,"promedio":0.75},
{"nombre":"Paolo Rossi","equipo":"Italia","goles":9,"partidos":14,"promedio":0.64},
{"nombre":"Jairzinho","equipo":"Brasil","goles":9,"partidos":16,"promedio":0.56},
{"nombre":"Karl-Heinz Rummenigge","equipo":"Alemania","goles":9,"partidos":20,"promedio":0.45},
{"nombre":"Guillermo Stábile","equipo":"Argentina","goles":8,"partidos":4,"promedio":2},
{"nombre":"Leônidas da Silva","equipo":"Brasil","goles":8,"partidos":5,"promedio":1.6},
{"nombre":"Ademir","equipo":"Brasil","goles":8,"partidos":6,"promedio":1.33},
{"nombre":"Óscar Míguez","equipo":"Uruguay","goles":8,"partidos":7,"promedio":1.14},
{"nombre":"Diego Armando Maradona","equipo":"Argentina","goles":8,"partidos":21,"promedio":0.38}
]

Goleadores en mundiales CSV

nombre,equipo,goles,partidos,promedio
Miroslav Klose,Alemania,16,24,0.67
Ronaldo,Brasil,15,19,0.79
Gerd Müller,Alemania,14,13,1.08
Just Fontaine,Francia,13,6,2.17
Pelé,Brasil,12,14,0.86
Sándor Kocsis,Hungría,11,5,2.2
Jürgen Klinsmann,Alemania,11,17,0.65
Helmut Rahn,Alemania,10,10,1
Gabriel Batistuta,Argentina,10,12,0.83
Gary Lineker,Inglaterra,10,12,0.83
Thomas Müller,Alemania,10,13,0.77
Teófilo Cubillas,Perú,10,13,0.77
Grzegorz Lato,Polonia,10,20,0.5
Eusébio,Portugal,9,6,1.5
Christian Vieri,Italia,9,9,1
Vavá,Brasil,9,10,0.9
David Villa,España,9,12,0.75
Paolo Rossi,Italia,9,14,0.64
Jairzinho,Brasil,9,16,0.56
Karl-Heinz Rummenigge,Alemania,9,20,0.45
Guillermo Stábile,Argentina,8,4,2
Leônidas da Silva,Brasil,8,5,1.6
Ademir,Brasil,8,6,1.33
Óscar Míguez,Uruguay,8,7,1.14
Diego Armando Maradona,Argentina,8,21,0.38