-->

Add (second) x axis to scatterplot to display grou

2019-06-28 01:11发布

问题:

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.

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:


What I have so far.

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:


What I tried.

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.


Question.

How can I scatter the labels and ticks of the x axis according to the group column from the data?

回答1:

Naive approach

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

Drawing from scratch

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