score:6
What you're looking for is to create a separation between your core application code and code that can be reused. This is a good idea because it keeps your application's code small, making it easier for you to change it and move it forward. In a reusable chart you want to send a very generic events, e.g. clicked
, while in your application you need the events to be very specific to your domain, e.g. addSugar
.
There are two ingredients you need: d3.dispatch and d3.rebind. The former helps you create a clear internal API, while the latter helps you expose the dispatched events to the outside world.
Go here to find an example of this. What you want to look for is three things:
- Inside the reusable chart you create a dispatcher with events you want to publish to the outside world:
var myDispatch = d3.dispatch('myclick', 'mydrag')
- Then in your reusable chart's event handlers you publish these events like so:
myDispatch.myclick(argumentsyouwanttopass)
- As a last step you make these events available to the outside:
return d3.rebind(_chart, myDispatch, "on");
- Then you can bind to these events on the outside:
myChart.on('myclick', function(){})
So your example, rewritten could look like this:
function chart() {
var dispatch = d3.dispatch('click');
function _chart(selection) {
selection.each(function(d, i) {
selection.selectAll('rect')
.data(d)
.enter()
.append('rect')
.attr('x', 0)
.attr('y', function(d, i) {return i * 11;})
.attr('width', function(d, i) {return d;})
.attr('height', 10);
.on('click', dispatch.click);
});
}
return d3.rebind(_chart, dispatch, 'on');
}
Additional note: to register multiple event handlers, you need to namespace them (like you have to for regular d3 events), e.g. chart.on('click.foo', handlerFoo)
, chart.on('click.bar', handlerBar)
etc.
score:2
One idea to make it more reusable and applicable to any possible event is to define a handler
array. This is similar to d3 itself. Here is an updated fiddle
function chart() {
var event_handlers = {}; //key value pairs
function _chart(selection) {
selection.each(function(d, i) {
var rects = selection.selectAll('rect')
.data(d)
.enter()
.append('rect')
.attr('x', 0)
.attr('y', function(d, i) {return i * 11;})
.attr('width', function(d, i) {return d;})
.attr('height', 10);
for(var event in event_handlers){
rects.on(event, event_handlers[event])
}
});
}
_chart.on = function(event, fun) {
if(arguments.length==1) return event_handlers[event];
event_handlers[event] = fun;
return _chart;
}
return _chart;
}
You can use your chart
the same way you use HTML elements.
chart.on("click", clickHandler);
Source: stackoverflow.com
Related Query
- Interactivity with the d3 reusable pattern
- How to create a reusable component in D3 with an API that manipulates each instance of the component?
- D3 semantic zooming with Reusable Pattern
- Using D3.js with the module pattern
- What is the updating chart pattern with queue()?
- Convert a directory structure in the filesystem to JSON with Node.js
- How can I bring a circle to the front with d3?
- D3: Create a continuous color scale with many strings/inputs for the range and dynamically changing values of the domain
- MultiBar chart with nvd3 / d3 only shows labels for every other tick on the x-axis. How can I get them all to show up?
- Fill rect with pattern
- Implementing the D3 "reusable chart" pattern in TypeScript
- Can D3 library be used with the Electron (Atom shell)?
- D3 linechart, can't edit the amount of ticks with an ordinal scale?
- nvd3.js : unable to bind onClick event with the data points in the svg
- Can I have a SVG Pattern with background color?
- How to update the fill color on existing svg elements with d3.js?
- Make simple bar chart using C3 with separate columns on the x axis
- What's the easy way to load d3-selection-multi along with d3 v4 in RequireJS?
- D3 fill shape with image using pattern
- How can I start with all the nodes collapsed in d3js?
- D3 updating graph with new elements create edges with the wrong nodes
- change the style with 'selectAll' and 'select' problems
- How to show the total per column in tooltip title with c3.js?
- Reusable charts in d3: how do the create and update selections work?
- Count the number of rows of a CSV file, with d3.js
- Using dc.js on the clientside with crossfilter on the server
- Join existing elements of the DOM to data with d3.js
- Binding to zoom ending with the zoom behavior
- D3.js - how to add zoom button with the default wheelmouse zoom behavior
- D3 V4 Transition on entering elements using General Update Pattern with merge
More Query from same tag
- D3 update circle-pack data new nodes overlap existing nodes
- d3 version 4 zoom behaviour on g element
- D3 V4 Error: <path> attribute d: Expected number, "MNaN,0LNaN,0LNaN,… scaleLinear().domain().range()
- How to change existing elements in D3
- Redraw a d3 force layout without moving nodes around
- D3.js substitute text in a paragraph
- Convert d3 event from Javascript to Typescript (Angular2)
- how to move circles(data points) in d3.js
- d3.js select by id not working. Not sure why not
- Need Help in D3 Sankey Chart
- Cannot add capitals to geojson world map
- Uncaught TypeError: n is not a function d3.js. While trying to overlay us_map on google maps
- D3 + VueJs + Typescript | Fixing Errors
- Creating tooltips for SVG objects after they were translated and scaled
- Is there a way to make interactive standalone SVGs in a webpage?
- D3.js v4 colors to names mapping
- D3.js non linear scale line chart
- Unexpected value translate parsing transform attribute
- vega-lite: how to specify date in JSON as separate fields containing year, month, and day numbers?
- Can't read json in D3
- Cannot bind JSON to d3
- d3 force layout repulsive charge formula
- d3.layout.cloud is not a function
- Google API V3: How to remove overlay using Custom Overlay's onRemove() method
- Loading a huge image (5mb) into svg background leads to pixelation and performance issues
- Timing issue on multi-line chart?
- d3 - problem aligning text with circle center - dominant-baseline not working on Firefox
- Can an array be used as a d3 nest key?
- d3.json is not executed
- Root node size to take sum of children nodes size when collapsed