Zoomable timeline with one element per tick (D3V6) - javascript

I'm working on a timeline-based chart that should always have one rect per x-axis tick. The idea is to use the color of each rectangle to convey the amount of data that's in that date (somewhat like a heatmap).
The chart also has grouped y values. That is, there are two y axes: one for each group, and inside each of those, three lines (subgroups). Semantically the intention is to say: "For this coupon, on this date, there are this many readings for each data type". To help clear up my intention further, this library has a very similar solution to what I'm aiming at.
OK, and your question...?
My question is about aligning the rectangles with the ticks, and keeping them that way. How can I make them always be aligned with the ticks? Is there a way to "tie" a rect to a tick?
To make matters worst, the chart has to be zoomable, so when you scroll and the dimensions of the ticks change, the rectangles should stick to their corresponding ticks: move with them, change their width accordingly and so on. Basically, I'd like to "marry" the rects to their corresponding ticks.
What have you tried?
My approach right now is to make the segments' width depend on the current tick count, and essentially treat the current ticks as if they were my data.
That is:
segmentWidth = state.width() / ticks.length;
And when updating/rendering the rects:
state.mainG.selectAll('g.couponData')
.selectAll('g.column')
.data(ticks)
...
One problem I see with this is that if you click and drag, the ticks expand, so having a single, global segmentWidth doesn't seem like the right approach. Seems like I'd need a way to grab each tick and get the distance to the next one, and use that as the width of each corresponding segment, but I haven't quite got there yet.
Here's a fiddle with an example of what I have:
https://jsfiddle.net/bnekvp0o/11/
TBH, I presume I'm making some dumb calculation mistakes, but I also feel like I'm bruteforcing the solution, so I'm hesitant to keep trying to make it work with my current approach, since I'm quite new to the framework.
Thanks in advance!

Related

Tooltip using d3.bisector in small multiples of stacked area charts is throwing reference errors

I have a stacked area chart — or rather, small multiples of stacked area charts — to which I'm trying to add a tooltip that displays values multiple values, as in this block: https://bl.ocks.org/fabiomainardi/3976176cb36e718a608f
as well as this one: http://bl.ocks.org/wdickerson/64535aff478e8a9fd9d9facccfef8929
As I understand it, the result I'd like to achieve (which most resembles that second block) requires the d3.bisect method, since 1) multiple paths/lines are involved, and 2) I'd like, eventually, alongside the y value for each area inside the tooltip, to display the x axis value (i.e., the date), like in this block: http://bl.ocks.org/d3noob/6eb506b129f585ce5c8a. Maybe getting the x axis value on mousover is another question for another day; but maybe you're feeling generous.
To me, they're related questions in the sense that I'm equally unable to call up either x or y values for the tooltip.
Here's my Plunker: http://plnkr.co/edit/ztDPXbLu3dZ6ju4poz84?p=preview
I've tried adapting about six or seven different examples that use d3.bisect to display tooltip x/y values for multiple paths/lines, without success. All of the other examples that I've been working from have a much simpler data structure.
In my various adaptations of other people's tooltips, I've tried summoning dates and y values in the following ways, among others:
d.x
d.date
d.dates
arr
data.x
dataset.x
dataset.date
data.x
dataset.x
data.y
d.y
dataset.y
dataset[0].values[1].y
dataset[i].values[j].y
dates.x
date.y
dataset.values.x
data.values.y
d3.max(data.values.y)
Predictably, I get a lot of reference errors.
I've managed to get one pseudo-tooltip working. Here's another Plunker:
https://plnkr.co/edit/XpXQc6ryvpyPeprAPxH4?p=info
But this only displays totals for the full date range, and only one path at a time. My goal is to display, in the tooltip, both the date and all of the respective y axis values, for each of the paths in the stacked area chart, just like in the second block I referenced earlier.
How do I do this, and can someone demonstrate for me in a forked Plunker, how to make the necessary references to my dataset for such a tooltip?

Alter first vertical grid line in nvd3

I want to remove (or make effectively hidden) the first vertical line in the grid for an nvd3 chart. I thought it was a problem with my chart, but after testing it, I realized it seems to be a more general problem.
I tested it by running the line:
d3.selectAll('.tick, .nv-axislabel, .nv-axis text').attr('fill','#999999')
in the console, at the simplest line chart I could find: http://nvd3.org/examples/line.html and it still didn't work! It changes all the lines except the very first vertical line. I'm baffled, I've tried every combination of classes with stroke, fill, opacity, etc - I can either affect the entire svg (with opacity), or nothing. Anyone have any ideas?
EDIT:
I should have specified this originally, I apologize - I do not want to remove the Y axis entirely. I still need the label and the tick marks - I just want to remove that one vertical line (or at least lighten it - it is much darker than the rest of my chart).
Going by your comments:
You don't want to see the " the first vertical line in the grid for an nvd3 chart"
Which is the y axis:
Two ways to achieve that:
Option1
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(false) //hide the y-axis
.showXAxis(true); //Show the x-axis
Option2:
Since in your example you are going for a CSS option
d3.selectAll('.nv-y').attr('display','none')
I will prefer Option1
EDIT post your clarification, you wish to make the y axis line light you can use:
d3.selectAll('.nv-y path').attr('opacity','0.1')
or if you want to hide it completely
d3.selectAll('.nv-y path').attr('display','none')
One solution is to specify an array of tick values that you want to use for each axis. Use axis.tickValues([values]) to explicitly declare which XAxis ticks you want for your graph. So you could pop .tickValues([1, 2, 3, 5, 8, 13, 21]); into either the chart.xAxis or the chart.yAxis, and ticks would only appear from the corresponding values in the array. In your case, you would want to put it in the chart.xAxis variable. However if you want to have a dynamic chart, explicitly declaring the tick values would pose a problem once the data is updated in the graph. If on the other hand you are using static data, this is a pretty easy fix. I've tested this solution in their live code editor and it seems to do the trick.
Refer to https://github.com/mbostock/d3/wiki/SVG-Axes#ticks to see some other directives that could be of use.

How to make a box heatmap chart (similar to a tag cloud) with ReactJS and D3JS?

Given time series data with category hierarchy (i.e. parent children), how to make a box heatmap chart like this:
http://finviz.com/map.ashx
This is very intuitive to view the performance of one stock, as well as one whole category.
Is there any existing JS that can make similar animation effect?
The visualization is somehow similar to tag cloud, but inside of a box, and with a color indicating a value change (of positive or negative).
Here is my idea.
We can keep the position (x, y), width, and height of each root category fixed, e.g. "Technology" and "Service" on the finviz page.
The second difficult part is to calculate the (x, y, width, height) for each sub-box inside of one category, to make sure that the layout of these boxes are well placed. Any insight on this part?
We need to make an animation effect for the delta value, and make a color for each box.

highstocks hozontal line won't draw

So I'm trying to get my highcharts plot to draw the recent minima and maxima.
I already figured the correct JSON sub-object is "plotLines", however my script just refuses to draw them without any error. Maybe someone of you can spot my error. The corresponding (and probably wrong, but that doesn't really matter for this example) values are listed to the left
thanks!
With you current values, the lines will never plot.
Your axis min is sitting at 500, and you are plotting lines at 498.
The axis will not expand to show plotLines or plotBands - it will only expand to show data (or based on minPadding/maxPAdding, etc).
You will need to check that your lines are within your axis min/max in order to display them.
You can do that by using the getExtremes() method, and if needed, the setExtremes() method:
http://api.highcharts.com/highcharts#Axis.getExtremes
http://api.highcharts.com/highcharts#Axis.setExtremes
Edit to incorporate comments:
If the line is the same value as a grid line, you will need to set a zIndex on either the plotLine or the gridLines - by default the gridLines are above the plotLines

How to prevent tiny bars on charts in Highcharts

http://d.pr/i/U5bb/4n26fLZr
Here's an example of a chart of ours. Pretty unreadable, yea? Is there an easy, dynamic way avoid this? I've tried implementing a dynamic height, but the problem is I can never seem to find the sweet spot that accommodates a smaller number of bars, and a larger number of bars. I feel like this has to be a problem that others have encountered before. Any help would be appreciated!
I accomplish this by doing the following:
1) determine height of non-data elements on the chart (ie, explicitly set the top and bottom margins, and add them together to get a base_height for the chart
2) determine how much space I want each bar to take, including bar width, and padding between bars, and set as my height_multiplier (I usually end up going for 20-25 pixels, personally)
3) on pulling my data, determine how many bars will be needed, and set as my bar_count
4) calculate: chart_height = base_height + (bar_count * height_multiplier)
5) Pass that value to the html to set the height of the chart's containing element.
If your data will vary so much that the chart height in your example works some times, but then you have as many data points as you've posted there, there simply will not be a 'sweet spot' that will handle both extremes well.

Categories