NVD3.js tags with multiple xChart characters are aligned, but not in bars

I am using NVD3.js multiChart to show multiple rows and columns in a chart. Everything works fine, but the labels on the x axis are aligned only with line points, not with stripes. I want to correctly align the labels directly below the columns, as follows. But I get the following:

enter image description here

With red lines, I will mark where the labels should be.

I did jsFiddle : http://jsfiddle.net/n2hfN/

Thanks!

+6
source share
2 answers

As @Miichi mentioned, this is a bug in nvd3 ...

I am surprised that they have TODO to “understand why the value seems biased” because it is pretty obvious ... Bars use ordinal scale with .rangeBands() and the line uses a linear scale and the two scales have never been connected with each other, except that they have the same endpoints.

One solution would be to take the ordinal scale from the bars and simply adjust it to half the bandwidth to make the x-scale line. This would put the line points in the center of the bars. I suppose something similar was done in nv.models.linePlusBarChart , which was mentioned by @LarsKotthoff.

Basically, your x-scale line will look something like this:

 var xScaleLine = function(d) { var offset = xScaleBars.rangeBand() / 2; return xScaleBars(d) + offset; }; 

... where xScaleBars is the x scale used for the column part of the chart.

Having flashed the source code for nvd3, it seems that this scale is available as chart.bars1.scale() .

Perhaps someday nvd3 authors will decide that their kludge libraries deserve some documentation. So far, I can show you what can solve the problem by creating my own diagram and showing how the two scales will be connected.

First, I will use your data, but we will divide the data of the string and the string into two arrays:

 var barData = [ {"x":0,"y":6500}, {"x":1,"y":8600}, {"x":2,"y":17200}, {"x":3,"y":15597}, {"x":4,"y":8600}, {"x":5,"y":814} ]; var lineData = [ {"x":0,"y":2}, {"x":1,"y":2}, {"x":2,"y":4}, {"x":3,"y":6}, {"x":4,"y":2}, {"x":5,"y":5} ]; 

Then adjust the scales for the bars. For x-scale, I use ordinal scale and rangeRoundBands with the default interval between groups for nvd3 multiBar , which is 0.1. For y-scale, I will use a regular linear scale using .nice() so that the scale does not end with an inconvenient value, like the default in nvd3. Having some space above the largest value gives you some context that is “nice” when trying to interpret a chart.

 var xScaleBars = d3.scale.ordinal() .domain(d3.range(barData.length)) .rangeRoundBands([0, w], 0.1); var yScaleBars = d3.scale.linear() .domain([0, d3.max(barData, function(d) {return dy;})]) .range([h, 0]) .nice(10); 

Now here is the important part . For the x-scale line, do not make a separate scale, but simply make it a function of the x-scale:

 var xScaleLine = function(d) { var offset = xScaleBars.rangeBand() / 2; return xScaleBars(d) + offset; }; 

Here is a complete example of how JSBin . I tried to document the main sections with comments, so it’s easy to follow the general logic of this. If you can find out from the nvd3 source code what exactly is called by each of the multiChart elements and how to set separate scales for the constituent parts, then you can simply connect a new scale.

My feeling is that you need to have a nice pen on how d3 works to do something useful with nvd3, and if you want to set it up, you are probably best off turning your own schedule. Thus, you have full knowledge and control over what the element classes and variable names of the parts of your diagram are, and you can do whatever you want with them. If nvd3 gets the right documentation, it might be a simple fix. Good luck, and I hope this at least helps you get started.

+9
source

It somehow works fine lines1.padData (true)

0
source

Source: https://habr.com/ru/post/971903/


All Articles