I make a scatterplot using d3.js where the points are arranged by their name and an accompanying number. The data that is plotted would look like this:
name, group, number
"AB", "A", 0.5
"ABC", "A", 10.0
"BC", "B", 3.0
"BCD", "B", 5.0
"BCDE", "B", 0.3
"CD", "C", 1.6
"DE", "D", 1.5
What I want to achieve is a plot where the points are scattered on the x axis according to their name, but the x axis should display the group once per group and a tick between different groups.
The result should look like this:
I do have a y and an x axis, the ticks and labels are not shown. In principle, the axes are created using the code below (example for the x axis):
var x = d3.scale.ordinal()
.rangeBands([0, 400]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickValues(0) // hide ticks
.tickFormat(""); // hide labels
The domain is derived from the name column:
x.domain(data.map(function(d) { return d.name; }));
And appended to to actual svg:
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + 400 + ")")
.call(xAxis)
This code results in the following plot:
I tried with adding a second x axis by simply repeating the steps that were used to create the first x axis described above. I just renamed x
to x2
, made ticks and labels visible, and derived the domain not from d.name
but from d.group
. The complete code is here. Naturally, this distributes the labels and ticks along the whole x axis and does not incorporate the group information.
How can I scatter the labels and ticks of the x axis according to the group column from the data?
One simplistic, but perhaps not desired way of handling this would be by using tickFormat
to simply repeat the group value for each ordinal value on the scale:
var lkUp = {};
chartData.forEach(function(d) { lkUp[d.name] = {group: d.group}; });
xAxis.tickFormat(function(d) { return lkUp[d].group; });
Working example: http://bl.ocks.org/jsl6906/64de7c45e4484114334b
If you move outside of trying to use D3's axis
component, you can draw these groups separately, i.e.:
//'chartGroups' is an array of calculated groups, with start and end coordinates
var chartGroups = svg.selectAll("g.chartGroup").data(chartGroups)
.enter().append("g").attr(..);
chartGroups.append("text").attr(..);
chartGroups.append("path").attr(..);
Working example: http://bl.ocks.org/jsl6906/a8a4dd54f3d8de6a7aae