I have a dataset that includes the following frequency data:
FrequencyData = [
{label:"QWERTY", value:0},
{label:"AZERTY", value:14},
{label:"AAAAAA", value:20},
{label:"BBBBBB", value:30},
{label:"CCCCCC", value:40},
{label:"DDDDDDD", value:45},
{label:"EEEEEE", value:21},
];
Here is the code I am using to create a horizontal bar chart based on this dataset:
function createBarChart(dataset) {
$elem[0].svg = null;
var margin = {top: 20, right: 10, bottom: 120, left: 10},
width = $elem[0].parentNode.clientWidth - margin.left - margin.right,
height = $elem[0].parentNode.clientHeight - margin.top - margin.bottom;
var mappedDataset = dataset.map(function(d) { return d.value; });
var div = d3.select($elem[0]).append("div").attr("class", "toolTip");
var formatPercent = d3.format("");
var y = d3.scale.ordinal()
//.domain(mappedDataset.sort(function(a, b) { return mappedDataset[a] - mappedDataset[b]; }))
.domain(dataset.map(function(d) { return d.label; }))
.rangeRoundBands([0, height], 0.1, 0.3);
var x = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d.value; })])
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.tickSize(-height)
.orient("bottom");
d3.select($elem[0]).selectAll("svg").remove()
var svg = d3.select($elem[0]).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 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.select(".y.axis").remove();
svg.select(".x.axis").remove();
svg.append("g")
.append("text")
.attr("transform", "rotate(0)")
.attr("x", 170)
.attr("dx", ".1em")
.style("text-anchor", "end")
.text("Frequency of Visit/Time Spent (mins)");
//console.log(dataset);
var bar = svg.selectAll(".bar")
.data(dataset, function(d) { return d.label; })
// new data:
bar.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return 0; })
.attr("y", function(d) { return y(d.label); })
.attr("width", function(d) { return x(d.value); }) // return 0 if want to animate
.attr("height", y.rangeBand())
.text(function(d) { return d.label; });
svg.selectAll(".bartext")
.data(dataset, function(d) { return d.label; })
.enter()
.append("text")
.attr("class", "bartext")
.attr("text-anchor", "middle")
.attr("fill", "white")
.attr("x", function(d,i) {
if (d.value==0) {return x(d.value)+50;}
return x(d.value)/2;
})
.attr("y", function(d,i) {
//if (d.value==0){return};
return y(d.label)+15;
})
.text(function(d){
//if (d.value==0){return};
return d.label;
});
bar.on("mousemove", function(d){
if ( in_transition ) { return; }
div.style("left", d3.event.pageX+"px");
div.style("top", d3.event.pageY-130+"px");
div.style("display", "inline-block");
div.html((d.value)+"%");
});
bar.on("mouseout", function(d){
if ( in_transition ) { return; }
div.style("display", "none");
});
// removed data:
bar.exit().remove();
$elem[0].svg = svg;
}, delay);
}
Currently, the bars are not sorted in descending order as I intend. I have tried sorting the Y-axis using the labels, but this does not produce the desired result. I have also attempted to use D3 sorting functions without success:
mappedDataset.sort(function(a, b) { return mappedDataset[a] - mappedDataset[b]; }))
If you have any ideas on how to correctly sort the bars in descending order, I would greatly appreciate the assistance. Thank you.