Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3.js -- Ordinal scale (version 3 to version 4)

I am taking an Udemy's course on D3.js.

Unfortunately because of the new version D3.js came out, there aren't any up-to-date tutorials on their new syntax so I am glancing at their API's wiki.

That being said, I've been stuck on how to translate this code (version 3). I am learning ordinal scale

var data = [
    {key: "Glazed",     value: 132},
    {key: "Jelly",      value: 71},
    {key: "Holes",      value: 337},
    {key: "Sprinkles",  value: 93},
    {key: "Crumb",      value: 78},
    {key: "Chocolate",  value: 43},
    {key: "Coconut",    value: 20},
    {key: "Cream",      value: 16},
    {key: "Cruller",    value: 30},
    {key: "Éclair",     value: 8},
    {key: "Fritter",    value: 17},
    {key: "Bearclaw",   value: 21}
];
var w = 800;
var h = 450;
var margin = {
    top: 20,
    bottom: 20,
    left: 20,
    right: 20
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var x = d3.scale.linear()
        .domain([0, d3.max(data, function(d){
            return d.value;
        })])
        .range([0, width]);
var y = d3.scale.ordinal()
        .domain(data.map(function(entry){
            return entry.key;
        }))
        .rangeBands([0, height]);
var svg = d3.select("body").append("svg")
            .attr("id", "chart")
            .attr("width", w)
            .attr("height", h);
var chart = svg.append("g")
            .classed("display", true)
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function plot(params){
    this.selectAll(".bar")
        .data(params.data)
        .enter()
            .append("rect")
            .classed("bar", true)
            .attr("x", 0)
            .attr("y", function(d,i){
                return y(d.key);
            })
            .attr("height", function(d,i){
                return y.rangeBand()-1;
            })
            .attr("width", function(d){
                return x(d.value);
            });
    this.selectAll(".bar-label")
        .data(params.data)
        .enter()
            .append("text")
            .classed("bar-label", true)
            .attr("x", function(d){
                return x(d.value);
            })
            .attr("dx", -4)
            .attr("y", function(d,i){
                return y(d.key);
            })
            .attr("dy", function(d,i){
                return y.rangeBand()/1.5+2;
            })
            .text(function(d){
                return d.value;
            })
}
plot.call(chart, {data: data});

to version 4.

Looking at their API Wiki, it seems that get rid rangeBand function CHANGES.MD

I've tried my best translating but I can't figure it out what it's wrong:

var data = [
    {key: "Glazed",     value: 132},
    {key: "Jelly",      value: 71},
    {key: "Holes",      value: 337},
    {key: "Sprinkles",  value: 93},
    {key: "Crumb",      value: 78},
    {key: "Chocolate",  value: 43},
    {key: "Coconut",    value: 20},
    {key: "Cream",      value: 16},
    {key: "Cruller",    value: 30},
    {key: "Éclair",     value: 8},
    {key: "Fritter",    value: 17},
    {key: "Bearclaw",   value: 21}
];
var w = 800;
var h = 450;
var margin = {
    top: 20,
    bottom: 20,
    left: 20,
    right: 20
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var x = d3.scaleLinear()
        .domain([0, d3.max(data, function(d){
            return d.value;
        })])
        .range([0, width]);
var y = d3.scaleOrdinal()
        .domain(data.map(function(entry){
            return entry.key;
        }))
        .range([0, height]);

var svg = d3.select("body").append("svg")
            .attr("id", "chart")
            .attr("width", w)
            .attr("height", h);
var chart = svg.append("g")
            .classed("display", true)
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function plot(params){
    this.selectAll(".bar")
        .data(params.data)
        .enter()
            .append("rect")
            .classed("bar", true)
            .attr("x", 0)
            .attr("y", function(d,i){
                return y(d.key);
            })
            .attr("height", function(d,i){
                return y.range(1)-1;
            })
            .attr("width", function(d){
                return x(d.value);
            });
    this.selectAll(".bar-label")
        .data(params.data)
        .enter()
            .append("text")
            .classed("bar-label", true)
            .attr("x", function(d){
                return x(d.value);
            })
            .attr("dx", -4)
            .attr("y", function(d,i){
                return y(d.key);
            })
            .attr("dy", function(d,i){
                return y.range(1)/1.5+2;
            })
            .text(function(d){
                return d.value;
            })
}
plot.call(chart, {data: data});

Working Version 3

Not Working Version 4

like image 400
Alejandro Avatar asked Sep 26 '16 06:09

Alejandro


People also ask

What is ordinal scale in d3 JS?

The d3. scaleOrdinal() function is used to create and return the ordinal scale which has the specified range and domain. If the domain and range are not given then both are set to empty array. These types of scales have a discrete domain and range.

Which is valid scale in d3 JS?

D3 creates a function myScale which accepts input between 0 and 10 (the domain) and maps it to output between 0 and 600 (the range). Scales are mainly used for transforming data values to visual variables such as position, length and colour.

What is scale linear in d3?

The d3. scaleLinear() method is used to create a visual scale point. This method is used to transform data values into visual variables.

What is domain and range in d3 JS?

The domain is the complete set of values, so in this case that is all of your temperatures, from 33 to 64. The range is the set of resulting values of a function, in this case the resulting values of scaling your temperatures from 0 to 600.


1 Answers

Below is the working code.

scale.oridnal is not supported in v4, hence scaleBand is used.

var data = [
    {key: "Glazed",     value: 132},
    {key: "Jelly",      value: 71},
    {key: "Holes",      value: 337},
    {key: "Sprinkles",  value: 93},
    {key: "Crumb",      value: 78},
    {key: "Chocolate",  value: 43},
    {key: "Coconut",    value: 20},
    {key: "Cream",      value: 16},
    {key: "Cruller",    value: 30},
    {key: "Éclair",     value: 8},
    {key: "Fritter",    value: 17},
    {key: "Bearclaw",   value: 21}
];
var w = 800;
var h = 450;
var margin = {
    top: 20,
    bottom: 20,
    left: 20,
    right: 20
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var x = d3.scaleLinear()
        .domain([0, d3.max(data, function(d){
            return d.value;
        })])
        .range([0, width]);
/*var y = d3.scale.ordinal()
        .domain(data.map(function(entry){
            return entry.key;
        }))
        .rangeBands([0, height]);*/
var y = d3.scaleBand()
        .domain(data.map(function(entry){
            return entry.key;
        }))
    .rangeRound([0, height])
    .padding(0.1);      

var svg = d3.select("body").append("svg")
            .attr("id", "chart")
            .attr("width", w)
            .attr("height", h);
var chart = svg.append("g")
            .classed("display", true)
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function plot(params){
    this.selectAll(".bar")
        .data(params.data)
        .enter()
            .append("rect")
            .classed("bar", true)
            .attr("x", 0)
            .attr("y", function(d,i){
                return y(d.key);
            })
            .attr("height", function(d,i){
                return y.bandwidth()-1;
            })
            .attr("width", function(d){
                return x(d.value);
            });
    this.selectAll(".bar-label")
        .data(params.data)
        .enter()
            .append("text")
            .classed("bar-label", true)
            .attr("x", function(d){
                return x(d.value);
            })
            .attr("dx", -4)
            .attr("y", function(d,i){
                return y(d.key);
            })
            .attr("dy", function(d,i){
                return y.bandwidth()/1.5+2;
            })
            .text(function(d){
                return d.value;
            })
}
plot.call(chart, {data: data});
like image 164
msapkal Avatar answered Sep 25 '22 17:09

msapkal