Using an ordinal scale ('d3.scale.ordinal') for the x-axis in a bar chart
Asked Answered
M

2

18

I have a data array like this:

var data = [{"Alphabet_Type":"a"}, {"Alphabet_Type":"b"}, {"Alphabet_Type":"a"}];

I am using:

  • dc.js
  • crossfilter.js
  • d3.js

I want to create a bar chart with:

  • the x-axis having an alphabet name, and
  • the y-axis having number of occurrences of the alphabet.

Question: How can I plot a bar chart with an ordinal scale on the x-axis?

My code:

var data = [{"Alphabet_Type":"a"}, {"Alphabet_Type":"b"}, {"Alphabet_Type":"a"}];

var Filter = crossfilter(data);
var Dimension = Filter.dimension(function (d) { return d.Alphabet_Type; });
var Group = Dimension.group();

dc.barChart("#bar-chart")
    .width(800) 
    .height(275) 
    .transitionDuration(0) 
    .margins({ top: 10, right: 50, bottom: 30, left: 40 })
    .dimension(Dimension) 
    .group(Group) 
    .elasticY(false)
    .elasticX(false)
    .x(d3.scale.linear().domain([-1, 10]))
    .y(d3.scale.linear().domain([0, 5]))
    .centerBar(true)
    .renderHorizontalGridLines(true)
    .renderVerticalGridLines(true)
    .brushOn(false);

Finally, I have another problem which is that Alphabet_Type is not going to have predictable values. So I need to fetch the values for Alphabet_Type via crossfilter.js and incorporate those values into the domain. How can I do this?

Mahler answered 11/9, 2013 at 13:22 Comment(0)
E
34

Two things:

  1. Pass dc.units.ordinal as the parameter to .xUnits().
  2. Pass an ordinal scale function to .x().

Here's what I mean:

.x(d3.scale.ordinal().domain(["", "a", "b", "c"])) // Need empty val to offset first value
.xUnits(dc.units.ordinal) // Tell dc.js that we're using an ordinal x-axis

See this JSFiddle: http://jsfiddle.net/reblace/tbamW/156/

For some reason, I couldn't get renderHorizontalGridLines() or renderVerticalGridLines() to work, but the rest is good.

Extractor answered 11/9, 2013 at 14:54 Comment(7)
Thanks @Extractor for your answer. it works well. I have edited my question. Please help me in this. since am new to dc i dont know to implement this.Mahler
I got the answer for the question i added. Now how to add a "" (blank string) like u have added in thje domain by using the function.Mahler
the .xUnits() part was what was missing and cost me a tone of time. Thank you, it finally bloody works.Harvey
the .xUnits() part was what was missing and cost me a tone of time. Thank you, it finally bloody works. Exactly!!!!!!!!!!!!!!!! .xUnits(dc.units.ordinal) // Tell Dc.js that we're using an ordinal x axisGranitite
The domain is computed automatically for ordinal x scales in dc.js 2.0 and later.Handlebar
Not sure if it happens to every one.. when tried to offset with blank string, I got the whole x axis lines offset. Not sure if this is trivial, let me know I will post a fiddle.Handcart
Wow, .xUnits was hard to find! It doesn't show up in many examples, but it was exactly what I needed. I'm using it with .x(d3.time.scale()) and it works like a charm there too.Shirleyshirlie
M
7

Adding

.x(d3.scale.ordinal().domain(data.map(function (d) {return d.Alphabet_Type; })))

solved the problem.

Mahler answered 12/9, 2013 at 5:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.