Multiple linecharts with different Y scales with shareable X Axis using d3js - javascript

Im working on this project where I have a big amount of data. It's segmented by categories Soybean, MA20, MA50, MA100, BBW_2 and date.
What I've done so far was to use a code where you can filter and zoom in the data. The result is
Selecting Soybean:
Selecting MA50:
Selecting BBW_2 !HERE IS THE PROBLEM! :
The problem is when BBW_2 is selected. You can see an orange line touching the X axis. This is BBW_2. It has it's Y' axis max value of 2, which is infinitely smaller than 1200, so the scale doesn't work as expected. This doesn't occur with the other categories because they have similar Y' axis values.
What Do I Want to Achieve?
I want to plot all the categories that the user selects appending the selected categories`generated linechart to the same X axis but with different Y scales. One example of what it would look like is this one: .
What I've tried:
Change the Y scale by changing it when the user selects BBW_2.
Plot in different SVG`s. This doesnt work great because it loses the zooming effect.
The code:
https://jsfiddle.net/ldepaula/3q1k9hyj/1/

Related

Tooltip indicator on axis displaying different data than the data plotted on chart

I have multiple y axis and x axis of chart which I change using setInterval based on different criteria
After those changes the cursor displaying values on y axis and x axis displays different value than the value plotted.
How can the cursor display correct value corresponding to the axis?
Please find screenshot attached highlighting the issue.
Thanks

How can I scale Y axis when changing dataset in this NVD3 multi bar chart?

I'm using NVD3 to generate a multi-bar / stacked chart. Here is a live fiddle.
I am taking an original array of data, transforming it into an nvd3 compatible structure, and maintaining arrays for both the 'current year' (2018) and 'all years'. The button at top allows you to toggle between all years and current year.
I'm pleased with the resulting chart with one exception. The scaling of the Y axis doesn't work if you perform the following steps:
1.) load the chart / fiddle
2.) click 'team 3' (orange) label at the top legend area a couple of times
3.) note the way the left side (Y axis) changes to scale to the resulting min / max
4.) now click 'Current Year' button at top (to only show a single year of data)
5.) again click 'team 3' (orange) label at the top legend area a couple of times... the Y axis does NOT scale at all now to decrease the max amount when 'team 3' is disabled.
When the current year / all years button is clicked, I'm running the following that I thought would force the chart to adapt fully to the new data set and automatically have its Y axis bounds set based on the data and legend items toggled:
data = convertedArray; // THE ALTERNATE ARRAY OF DATA
chart.forceY([uniqueDollarAmounts[0], // THE DISTINCT VALUES THAT GOVERN THE Y AXIS AMOUNTS (AND BOUNDS?)
uniqueDollarAmounts2[uniqueDollarAmounts.length-1]]);
d3.select('#NVD3Chart svg').datum(data).call(chart);
What do I need to do to have disabling 'team 3' decrease the Y axis max value to the 392,710.1 value that the next highest team has (team 7)? I also have observed that when you return back to 'All Years' it doesn't work as it does initially (speaking of the scaling of the Y axis)... so I'm breaking something when I pivot to the 2nd data set apparently.
The purpose of chart.forceY(..) is actually the opposite of what you want, it ensures that the Y Axis will not scale when the displayed data is filtered. The call to .datum(data) handles changes in the axis and data based on data. In fact simply remove both of these instances and it will Y-Axis scaling will work.
$('#sort').click(function() {
if ($(this).val() == "All Years") {
$(this).val("Current Year");
data = convertedArray;
//chart.forceY([uniqueDollarAmounts[0], uniqueDollarAmounts2[uniqueDollarAmounts.length-1]]);
d3.select('#NVD3Chart svg').datum(data).call(chart);
nv.utils.windowResize(chart.update);
getLowerTeamData()
}
else {
$(this).val("All Years");
data = convertedArray2;
//chart.forceY([uniqueDollarAmounts2[0], uniqueDollarAmounts2[uniqueDollarAmounts2.length-1]]);
d3.select('#NVD3Chart svg').datum(data).call(chart);
nv.utils.windowResize(chart.update);
getLowerTeamData()
}
});
A note on a functionality you are mentioning:
I also have observed that when you return back to 'All Years' it doesn't work as it does initially
This is because when the chart is first loaded chart.forceY was not used, as such the Y Axis will scale correctly. When you go back to 'All Years' it applies (or rather tried to apply)chart.forceY which wasn't happening initially causing this issue to appear.
This problem is actually due to chart.forceY(..) not working for your initial dataset from what appears to be a typo on your end. Take a look carefully at line 119:
chart.forceY([uniqueDollarAmounts[0], uniqueDollarAmounts2[uniqueDollarAmounts.length-1]]);
The uniqueDollarAmounts2 should be uniqueDollarAmounts, so the value of uniqueDollarAmounts2[uniqueDollarAmounts.length-1] is undefined. This causes .forceY to not work as intended which is why it still appears to scale when you filter "Team3".
Here is a fiddle showing chart.forceY on the initial chart and the typo correction. Notice that the Y-Axis does not change when the data is filtered in any cases. The minim value on the 2018 data is different so you will notice the lower value does indeed change from 0 and 6,641.8 as you would expect.
Here is a fiddle where instances of chart.forceY are removed. Notice that the Y-Axis scale appropriately now.

NVD3: Have labels at certain tick values at the top of the graph

I am using NVD3 to draw a graph that uses an ordinal scale on the x axis for dates. I also have a "focus graph" under it to highlight a specific region to display. To automatically update the ticks that are displayed, I use the tickValues() property.
I want to have label on specific dates at the top of the graph. My solution for this was to create another x axis, but above the the graph, plot the same data, but with a 0 height, and then use tickValues() to set the position of the labels. However, the labels don't show up on the top axis. Is there a solution or alternative?
I guess using a secondary x axis is fine. I forgot to remove the line setting the domain property for my secondary axis. When I removed that, it scaled just like my primary axis :)

Add grid lines compatible with zoom and drag in d3.js

I am trying to add grid lines to my existing code, and have seen many tutorials but none with zoomable and dragable grid lines.
A stripped version of my existing code is here :
http://jsfiddle.net/p4cmx1kj/
I understand that I must have a scale :
this.x = d3.scale.linear()
.domain([this.options.xmin, this.options.xmax])
.range([0, this.size.width]);
And draw it later. But I don't know how.
I would like to have vertical grid lines that "change" as I zoom (eg : go from 10-20-30-40 to 10-15-20-25) and move as I drag my graph around.
How can I do that ?
I guess you could do something like this example :
http://blog.scottlogic.com/2014/09/26/an-interactive-stock-comparison-chart-with-d3.html
And then add some limit, where if above a certain threshold it adds more / less tick labels on the axis. (At-least that is what I plan to attempt to do on a force layout now).
Or better still make your labels a function of the range, eg something along the lines of min + n*(min-max)/4 , where n is your tick label {1,4}.

Highcharts - Series tooltip doesn't work when plotting lines that zigzag on the x axis

I have a highcharts chart that I need to plot but which has lines which can go back on themselves on the X Axis.
e.g. jsfiddle example
My problem isn't that I can't plot it but rather the series tooltips don't display correctly.
If you zoom right in to individual points they seem ok, but not at normal zoom level.
E.g. if you scan your mouse across the series from right to left it doesn't want to show you the tooltip on x Value 1, intead it jumps to the second set of values on x value 2.
I've changed the tooltips to being not shared:
tooltip: {
shared: false,
},
but this has made little difference, apart from now it seems to work when zoomed in, but I suspect this is only because there are only one set of x Axis values visible.
Does anybody know how it is possible to configure Highcharts to allow for series where the x values aren't sorted either ascending or descending as I can't find anything in the documentation.
From the API documentation:
Note that line series and derived types like spline and area, require
data to be sorted by X because it interpolates mouse coordinates for
the tooltip. Column and scatter series, where each point has its own
mouse event, does not require sorting.
So change your series to type: 'scatter' with a lineWidth > 0. Here's an updated fiddle.

Categories