-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Thumbnail fv_34 with JSDOM #79
Changes from 14 commits
1692bee
c2d12c7
ffd2fed
2f6438d
9375729
6df16df
bef9932
5ea65ec
8a05655
1064c9f
a40807a
4ab507d
b1bee7a
8c20cbb
bf9ea85
bcaa845
26d0ff9
9daea30
b2dc43f
62e7091
a14baeb
51456c7
0ae52f9
1d76943
d1574db
7e7b94e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about calling the directory thumbnail There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed |
||
'use strict'; | ||
/** | ||
* @param {Object} options - holds options for the configuration of the hydrograph | ||
* Non-optional Keys include: | ||
* @prop 'height' v(int) - height of the graph | ||
* @prop 'width' v(int) - width of the graph | ||
* @prop 'data' v(list) - A list of objects representing data points | ||
* @prop 'div_id' v(string) - id for the container for this graph | ||
* | ||
* hydromodule is a module for creating hydrographs using d3. Pass it a javascript object | ||
* specifying config options for the graph. Call init() to create the graph. Linked | ||
* interaction functions for other figures should be passed to init in and object. | ||
* | ||
*/ | ||
var hydromodule = function (options) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we change hydrograph.js not to be wrapped in a function? I'm not sure why we are doing that anyways. Then I think you could use it directly here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you saying change the original hydrograph.js to not be wrapped in a function, and then we wont have to replicate this file? I will definitely try this, but I am still thinking we will have to battle the FV.hydromodule issue with the original file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe. The alternate is to not use global namepsace of FV in the original module. I would rather do that the duplicate code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wondering if we could make another ticket for this and attack it once the reference.json changes are merged? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it looks like they are already merged. But a separate ticket for this would still be helpful IMO. There may be a decent amount of refactoring. Something to talk about at sprint planning I guess. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's talk about at sprint planning. I'm okay with putting in a separate ticket though. |
||
|
||
var self = {}; | ||
|
||
var margin = {top: 30, right: 20, bottom: 30, left: 50}; | ||
var height = options.height - margin.top - margin.bottom; | ||
var width = options.width - margin.left - margin.right; | ||
|
||
// Adds the svg canvas | ||
var svg = null; | ||
// Focus for hydrograph hover tooltip | ||
var focus = null; | ||
// Voronoi layer | ||
var voronoi_group = null; | ||
// Define the voronoi | ||
var voronoi = d3.voronoi() | ||
.x(function (d) { | ||
return x(d.time_mili); | ||
}) | ||
.y(function (d) { | ||
return y(d.value); | ||
}) | ||
.extent([[-margin.left, -margin.top], [width + margin.right, height + margin.bottom]]); | ||
// Define the line | ||
var line = d3.line() | ||
.x(function (d) { | ||
return x(d.time_mili); | ||
}) | ||
.y(function (d) { | ||
return y(d.value); | ||
}); | ||
// Set the ranges | ||
var x = d3.scaleTime().range([0, width]); | ||
var y = d3.scaleLog().range([height, 0]); | ||
|
||
/** | ||
* Filters a set of data based on the ids listed in display_ids | ||
* @returns {Array} The entries of the original `data` whose `key` values are elements of display_ids. | ||
*/ | ||
var subset_data = function (full_data) { | ||
var toKeep = []; | ||
full_data.forEach(function (d) { | ||
if (options.display_ids.indexOf(d.key) !== -1) { | ||
toKeep.push(d); | ||
} | ||
}); | ||
return toKeep; | ||
}; | ||
/** | ||
* | ||
* Draws the svg, scales the range of the data, and draws the line for each site | ||
* all based on the data set as it was passed in. Called as needed | ||
* when data changes (as in removal of a line). | ||
* | ||
*/ | ||
var update = function () { | ||
|
||
// Cut the data down to sites we want to display | ||
var sub_data = subset_data(options.data); | ||
// Remove the current version of the graph if one exists | ||
var current_svg = d3.select(options.div_id + ' svg'); | ||
if (current_svg) { | ||
current_svg.remove(); | ||
} | ||
// recreate svg | ||
svg = d3.select(options.div_id) | ||
.append('svg') | ||
.attr('width', width + margin.left + margin.right) | ||
.attr('height', height + margin.top + margin.bottom) | ||
.append('g') | ||
.attr('transform', | ||
'translate(' + margin.left + ',' + margin.top + ')'); | ||
|
||
var graph_data = sub_data.map(function (d) { | ||
return { | ||
'date': d.date, | ||
'key': d.key, | ||
'name': d.name, | ||
'time': d.time, | ||
'time_mili': d.time_mili, | ||
'timezone': d.timezone, | ||
'value': Number(d.value) | ||
}; | ||
}); | ||
|
||
// Scale the range of the data | ||
x.domain(d3.extent(graph_data, function (d) { | ||
return d.time_mili; | ||
})); | ||
y.domain([d3.min(graph_data, function (d) { | ||
return d.value; | ||
}), d3.max(graph_data, function (d) { | ||
return d.value; | ||
})]); | ||
// Nest the entries by site number | ||
var dataNest = d3.nest() | ||
.key(function (d) { | ||
return d.key; | ||
}) | ||
.entries(graph_data); | ||
// Loop through each symbol / key | ||
dataNest.forEach(function (d) { | ||
svg.append('g') | ||
.attr('class', 'hydro-inactive') | ||
.append('path') | ||
.attr('id', 'hydro' + d.key) | ||
.attr('d', line(d.values)); | ||
console.log('Here IN DATANEST'); | ||
}); | ||
// Add the X Axis | ||
svg.append('g') | ||
.attr('class', 'axis') | ||
.attr('transform', 'translate(0,' + height + ')') | ||
.call(d3.axisBottom(x).tickFormat(d3.timeFormat('%B %e'))); | ||
|
||
// Add the Y Axis | ||
svg.append('g') | ||
.attr('class', 'axis') | ||
.call(d3.axisLeft(y).ticks(10, '.0f')); | ||
|
||
// Tooltip | ||
focus = svg.append('g') | ||
.attr('transform', 'translate(-100,-100)') | ||
.attr('class', 'focus'); | ||
focus.append('circle') | ||
.attr('r', 3.5); | ||
|
||
focus.append('text') | ||
.attr('y', -10); | ||
|
||
// Voronoi Layer | ||
voronoi_group = svg.append('g') | ||
.attr('class', 'voronoi'); | ||
voronoi_group.selectAll('path') | ||
.data(voronoi.polygons(d3.merge(dataNest.map(function (d) { | ||
return d.values | ||
})))) | ||
.enter().append('path') | ||
.attr('d', function (d) { | ||
return d ? 'M' + d.join('L') + 'Z' : null; | ||
}) | ||
.on('mouseover', function (d) { | ||
self.linked_interactions.hover_in(d.data.name, d.data.key); | ||
self.activate_line(d.data.key); | ||
self.series_tooltip_show(d); | ||
}) | ||
.on('mouseout', function (d) { | ||
self.linked_interactions.hover_out(); | ||
self.deactivate_line(d.data.key); | ||
self.series_tooltip_remove(d.data.key); | ||
}) | ||
.on('click', function (d) { | ||
self.linked_interactions.click(d.data.key); | ||
self.remove_series(d.data.key); | ||
}); | ||
|
||
}; | ||
|
||
/** | ||
* Initialize the Hydrograph. | ||
* | ||
*@param {Object} linked_interactions - Object holding functions that link to another figure's interactions. | ||
* Pass null if there are no such interactions to link. | ||
* @prop 'hover_in' - linked interaction function for hover_in events on this figure. | ||
* @prop 'hover_out' - linked interaction function for hover_out events on this figure. | ||
* @prop 'click' - linked interaction function for click events on this figure. | ||
* | ||
* | ||
*/ | ||
self.init = function (linked_interactions) { | ||
self.linked_interactions = linked_interactions; | ||
update(); | ||
return self; | ||
}; | ||
|
||
/** | ||
* Returns the svg element node. Primarily used for thumb-nailing. | ||
*/ | ||
self.get_svg_elem = function () { | ||
return d3.select(options.div_id); | ||
}; | ||
/** | ||
* Displays tooltip for hydrograph at a data point in addition to | ||
* corresponding map site tooltip. | ||
*/ | ||
self.series_tooltip_show = function (d) { | ||
focus.attr('transform', 'translate(' + x(d.data.time_mili) + ',' + y(d.data.value) + ')'); | ||
focus.select('text').html(d.data.key + ': ' + d.data.value + ' cfs ' + ' ' + d.data.time + ' ' + d.data.timezone); | ||
}; | ||
|
||
/** | ||
* Removes tooltip view from the hydrograph series | ||
* as well as the correspond mapsite tooltip. | ||
*/ | ||
self.series_tooltip_remove = function (sitekey) { | ||
focus.attr('transform', 'translate(-100,-100)'); | ||
}; | ||
|
||
/** | ||
* Removes a line from the hydrograph. This resizes data | ||
* appropriately and removes accents from the corresponding | ||
* site on the map. | ||
*/ | ||
self.remove_series = function (sitekey) { | ||
var keep_ids = FV.hydrograph_display_ids; | ||
keep_ids.splice(FV.hydrograph_display_ids.indexOf(sitekey), 1); | ||
self.change_lines(keep_ids); | ||
}; | ||
/** | ||
* Update the value of display_ids and call update to redraw the graph to match. | ||
* @param new_display_ids The new set of gages to be displayed. | ||
*/ | ||
self.change_lines = function (new_display_ids) { | ||
FV.hydrograph_display_ids = new_display_ids; | ||
update(); | ||
}; | ||
/** | ||
* Highlight a line. | ||
* @param sitekey the site number of the line to be highlighted | ||
*/ | ||
self.activate_line = function (sitekey) { | ||
d3.select('#hydro' + sitekey).attr('class', 'hydro-active'); | ||
}; | ||
/** | ||
* Un-highlight a line | ||
* @param sitekey the site number of the line to be un-highlighted | ||
*/ | ||
self.deactivate_line = function (sitekey) { | ||
d3.select('#hydro' + sitekey).attr('class', 'hydro-inactive'); | ||
}; | ||
|
||
return self | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use comments indicating this is same as hydrograph code and what differences are.