samedi 11 juin 2016

D3.js Bar Chart

HTML

<div id="searchVolume"></div>  

CSS

#tooltip {
    position: absolute;
    width: 50px;
    height: auto;
    padding: 10px;
    background-color: white;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
    pointer-events: none;
}
#tooltip.hidden {
    display: none;
}
#tooltip p {
    margin: 0;
    font-family: sans-serif;
    font-size: 12px;
    line-height: 16px;
}
.indent{
    padding-left: 5px;
}

rect {
    -moz-transition: all 0.3s;
    -webkit-transition: all 0.3s;
    -o-transition: all 0.3s;
    transition: all 0.3s;
}
rect:hover{
    fill: orange;
}
.axis path,
.axis line {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}
.axis text {
    font-family: sans-serif;
    font-size: 11px;
}  

Script

var margin = {top: 25, right: 40, bottom: 35, left: 85},
                w = 500 - margin.left - margin.right,
                h = 350 - margin.top - margin.bottom;
var padding = 10;

var colors =    [ ["Morning", "#F64BEE"],
                  ["Midday", "#25B244"],
          ["Afternoon", "#2BA3F4"],
          ["Evening","#FD7680"]];

var dataset = [
                { "Morning": 1400000, "Midday": 673000, "Afternoon": 43000, "Evening":50000},
                { "Morning": 165000, "Midday": 160000, "Afternoon": 21000, "Evening":23000 },
                {"Morning": 550000, "Midday": 301000, "Afternoon": 34000, "Evening":43000},
        {"Morning": 550320, "Midday": 351000, "Afternoon": 24000, "Evening":38000},
        {"Morning": 55000, "Midday": 3010, "Afternoon": 24000, "Evening":43054},
        {"Morning": 750000, "Midday": 401000, "Afternoon": 84000, "Evening":42100},
        {"Morning": 578000, "Midday": 306000, "Afternoon": 54000, "Evening":43400},
                            ];

var xScale = d3.scale.ordinal()
                .domain(d3.range(dataset.length))
                .rangeRoundBands([0, w], 0.05); 
// ternary operator to determine if global or local has a larger scale
var yScale = d3.scale.linear()
                .domain([0, d3.max(dataset, function(d) { return Math.max(d.Morning,d.Midday,d.Afternoon,d.Evening);})]) 
                .range([h, 0]);
var xAxis = d3.svg.axis()
                .scale(xScale)
                .orient("bottom");
var yAxis = d3.svg.axis()
                .scale(yScale)
                .orient("left")
                .ticks(5);




var commaFormat = d3.format(',');

//SVG element
var svg = d3.select("#searchVolume")
            .append("svg")
            .attr("width", w + margin.left + margin.right)
            .attr("height", h + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Graph Bars
var sets = svg.selectAll(".set") 
    .data(dataset) 
    .enter()
    .append("g")
    .attr("class","set")
    .attr("transform",function(d,i){
         return "translate(" + xScale(i) + ",0)";
     })
    ;

sets.append("rect")
    .attr("class","Morning")
    .attr("width", xScale.rangeBand()/4)
    .attr("y", function(d) {
        return yScale(d.Morning);
    })
    .attr("x", xScale.rangeBand()/4)
    .attr("height", function(d){
        return h - yScale(d.Morning);
    })
    .attr("fill", colors[0][1])
    .append("text")
   .text(function(d) {
        return commaFormat(d.Morning);
   })
   .attr("text-anchor", "middle")
   .attr("x", function(d, i) {
        return xScale(i) + xScale.rangeBand() / 4;
   })
   .attr("y", function(d) {
        return h - yScale(d.Morning) + 14;
   })
   .attr("font-family", "sans-serif") 
   .attr("font-size", "11px")
   .attr("fill", "black")
    ;

sets.append("rect")
    .attr("class","Midday")
    .attr("width", xScale.rangeBand()/4)
    .attr("y", function(d) {
        return yScale(d.Midday);
    })
    .attr("height", function(d){
        return h - yScale(d.Midday);
    })
    .attr("fill", colors[1][1])
    .append("text")
    .text(function(d) {
        return commaFormat(d.Midday);
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
        return xScale(i) + xScale.rangeBand() / 4;
    })
    .attr("y", function(d) {
        return h - yScale(d.Midday) + 14;
    })
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px")
    .attr("fill", "red")
    ;

  sets.append("rect")
    .attr("class","Afternoon")
    .attr("width", xScale.rangeBand()/4)
    .attr("y", function(d) {
        return yScale(d.Afternoon);
    })
    .attr("height", function(d){
        return h - yScale(d.Afternoon);
    })
    .attr("fill", colors[2][1])
    .append("text")
    .text(function(d) {
        return commaFormat(d.Afternoon);
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
        return xScale(i) + xScale.rangeBand() / 4;
    })
    .attr("y", function(d) {
        return h - yScale(d.Afternoon) + 14;
    })
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px")
    .attr("fill", "red")
    ; 

  sets.append("rect")
    .attr("class","Evening")
    .attr("width", xScale.rangeBand()/4)
    .attr("y", function(d) {
        return yScale(d.Evening);
    })
    .attr("height", function(d){
        return h - yScale(d.Evening);
    })
    .attr("fill", colors[3][1])
    .append("text")
    .text(function(d) {
        return commaFormat(d.Evening);
    })
    .attr("text-anchor", "middle")
    .attr("x", function(d, i) {
        return xScale(i) + xScale.rangeBand() / 4;
    })
    .attr("y", function(d) {
        return h - yScale(d.Evening) + 14;
    })
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px")
    .attr("fill", "red")
    ;
// xAxis
svg.append("g") // Add the X Axis
    .attr("class", "x axis")
    .attr("transform", "translate(0," + (h) + ")")
    .call(xAxis)
        ;
// yAxis
svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(0 ,0)")
    .call(yAxis)
    ;
// xAxis label
svg.append("text") 
    .attr("transform", "translate(" + (w / 4) + " ," + (h + margin.bottom - 5) +")")
    .style("text-anchor", "middle")
    .text("Keyword");
//yAxis label
svg.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - margin.left)
        .attr("x", 0 - (h / 4))
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("Searches");

// Title
svg.append("text")
        .attr("x", (w / 2))
        .attr("y", 0 - (margin.top / 2))
        .attr("text-anchor", "middle")
        .style("font-size", "16px")
        .style("text-decoration", "underline")
        .text("Weekly Consumption");


// add legend   
var legend = svg.append("g")
        .attr("class", "legend")
        //.attr("x", w - 65)
        //.attr("y", 50)
        .attr("height", 100)
        .attr("width", 100)
        .attr('transform', 'translate(-20,50)');

var legendRect = legend.selectAll('rect').data(colors);

legendRect.enter()
    .append("rect")
    .attr("x", w - 65)
    .attr("width", 10)
    .attr("height", 10);

legendRect
    .attr("y", function(d, i) {
        return i * 20;
    })
    .style("fill", function(d) {
        return d[1];
    });

var legendText = legend.selectAll('text').data(colors);

legendText.enter()
    .append("text")
    .attr("x", w - 52);

legendText
    .attr("y", function(d, i) {
        return i * 20 + 9;
    })
    .text(function(d) {
        return d[0];
    });  

D3 Fiddle

In the above fiddle, I have attempted to make a bar chart using d3.js library. I am stuck on following basic things which shouldn't even take much time. I am not able to grasp the functions of d3. You can play around with the fiddle and any help would be hugely beneficial:
1. I want four different bars grouped on a single x value. Like for '0' there would be four of them unlike the current one where it is merging everything into two.
2. Change the content of x-axis from numbers to days like from Monday to Friday.
3. For y-axis, I am trying to display the values like, instead of 20000, it should show 20k and the bar should recognise that while dynamically creating it. Is this possible?

Any help would be greatly beneficial. I couldn't figure it out.

Aucun commentaire:

Enregistrer un commentaire