Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Templates From Discarding DOM Elements

Tags:

meteor

d3.js

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.

like image 426
Matthew Lewis Avatar asked May 08 '12 16:05

Matthew Lewis


1 Answers

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.

like image 175
AbigailW Avatar answered Oct 12 '22 21:10

AbigailW