If there should be only one graph instance inside the template, then all you have to do is tell d3 to add the svg element inside the <script id="datatemplate"> instead of the body.
var svg = d3.select("#datatemplate").append("svg").attr("width",w).attr("height",h);
If, on the other hand, you would like your template to generate a d3 graph every time it is called, I don't think this is the right way to do something. Because d3 associates data with DOM elements, and Handlebars generates HTML strings from data structures.
You can wrap your graph code in a closure to which you pass your data and the element you want to bind to, and then generate a new graph instance from the Handlebars helper:
function graphic( dataset, element ) { var w = 154; var h = 42; var rect_1_h = 5; var rect_2_h = rect_1_h * 2; var rect_2_w = rect_1_h/2; var rect_1_color = "#A1C9D9"; var rect_2_color = "#999999"; var text_color = "#555555"; var font_size = 18; var font_family = "Segoe UI"; /*------controller----*/ var xScale = d3.scale.linear().domain([dataset[0],dataset[2]]) .range([0,w]); var svg = d3.select( element ).append("svg").attr("width",w).attr("height",h); var rect1 = svg.append("rect").attr("x",0).attr("y",3*h/4).attr("width",w).attr("height",rect_1_h) .style("fill",rect_1_color); var rect2 = svg.append("rect").attr("x",xScale(dataset[1])).attr("y",3*h/4-rect_1_h/2).attr("width",rect_2_w) .attr("height",rect_2_h).style("fill",rect_2_color); //var texts = svg.selectAll("text").data(dataset).enter().append("text").text(function(d){ return d; }).attr("fill","red").attr("x",function(d,i){ return i*50 }).attr("y",30) var text1 = svg.append("text").attr("x",2).attr("y",h/3+2).text(dataset[0]).style("fill",text_color) .attr("font-size",font_size).attr("font-family",font_family); var text2 = svg.append("text").attr("x",w-42).attr("y",h/3+2).text(dataset[2]).style("fill",text_color) .attr("font-size",font_size).attr("font-family",font_family); return svg; }; Handlebars.registerHelper('graphics', function( dataset, id ) { graphic( dataset, '#' + id ); });
And then in your template:
<script id="datatemplate" type="text/x-handlebars-template"> {{#each objects}} <tr> <td>{{lp}}<span class="text1">{{lp2}}</span></td> <td>{{dc}}<span class="text1">{{dc2}}</span></td> <td>{{lp}}<span class="text1">{{lp2}}</span></td> </tr> {{/each}} <div id={{ id }}></div> {{graphics dataset id}} </script>