I am attempting to integrate a D3.js
visualization into a Meteor app. After the page has loaded, a D3 function injects DOM elements into a <div>
in my template, based on available data.
Whenever there is a reactive update anywhere on the page, however, Meteor dumps the contents of the template that were injected by my D3.js function. I can re-insert the elements, but this leads to an undesirable flicker and decrease in performance.
Any idea on how to suppress this dropping of externally injected elements? I gather that since these elements were not part of the template originally, they are discarded as part of Meteor's 'cleanup' process.
With the introduction of the Spark templating engine in version 0.4.0, they've introduced the {{#constant}} block helpers to address this issue.
http://meteor.com/blog/2012/08/31/introducing-spark-a-new-live-page-update-engine
Your html template should look something like this....
<template name="samplePageTemplate">
<div id="samplePage" class="page">
{{#constant}}
<div id="sampleGraph"></div>
{{/constant}}
</div>
</template>
And the javascript should look something like this...
Template.samplePageTemplate.destroyed = function () {
this.handle && this.handle.stop();
};
Template.samplePageTemplate.rendered = function () {
self.node = self.find("svg");
if (!self.handle) {
self.handle = Meteor.autorun(function(){
$('#sampleGraph').html('');
renderChart();
});
};
};
function renderChart(){
// lots of d3 chart specific stuff
var vis = d3.select("#sampleGraph").append("svg:svg")
.attr("width", window.innerWidth)
.attr("height", window.innerHeight)
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
// more d3 chart specific stuff
});
};
I've sometimes had to use self.node instead of self.handle, but otherwise it should be fairly straight forward.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With