问题
I'm newbie in D3 and want to draw chart with 6 horizontal bars. My xAxis is scaleLinear with their values. So I want yAxis to be just a list with each bar name. So for yScale I have 6 names - ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps']
So when I use this yScale:
var params = ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps'];
var yScale = d3.scaleBand()
.domain(params)
.range([0, 300])
I see only one 'Games' and one 'Apps' on yAxis How to list all of the params on yAxis and not to skip repeatable?
回答1:
What you're seeing here is the default (and expected) behaviour of any ordinal scale: the values must be unique.
If you have a look at the API, you'll see (emphasis mine):
Domain values are stored internally in a map from stringified value to index; the resulting index is then used to determine the band. Thus, a band scale’s values must be coercible to a string, and the stringified version of the domain value uniquely identifies the corresponding band.
Therefore, any solution here will be a hacky one. That being said, an easy solution is adding a meaningless unique value to each element of your array. For instance, using the indices of the elements in the array:
const params = ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps'].map(function(d, i) {
return d + "-" + i;
});
Then we just remove those indices for creating the axis, using tickFormat:
const yAxis = d3.axisLeft(yScale)
.tickFormat(function(d) {
return d.split("-")[0];
});
Here is a demo:
const svg = d3.select("svg");
const params = ['Games', 'Apps', 'Games', 'Apps', 'Games', 'Apps'].map(function(d,i) {
return d + "-" + i;
});
const yScale = d3.scaleBand()
.domain(params)
.range([2, 148]);
const yAxis = d3.axisLeft(yScale)
.tickFormat(function(d) {
return d.split("-")[0];
});
yAxis(svg.append("g").attr("transform", "translate(100,0)"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
来源:https://stackoverflow.com/questions/55413680/same-repeatable-string-values-using-a-band-scale