【问题标题】:Basic example of rendering a d3 SVG with a backbone View使用主干视图渲染 d3 SVG 的基本示例
【发布时间】:2013-04-29 18:46:08
【问题描述】:

我正在尝试在主干视图中从静态 html SVG(具有动态值)切换到动态 d3 SVG。我目前正在使用模板(并且希望对其他一些属性保持这种方式),但不必这样做(因为我可以使用模板将这些属性重构到他们自己的视图中)。

任何人都有一个干净的快速示例,比如只有一个圆圈?

我找到的 Backbone 和 d3 最接近的版本是 here,但这是我想要的,并且还没有足够的 d3 经验来理解函数调用和结构。

当前提供问题的代码在 View 的 render() 中:

    var pathFunction = d3.svg.line()
        .x(function (d) {return d.x;})
        .y(function (d) {return d.y;})
        .interpolate("basis"); // bundle | basis | linear | cardinal are also options

    //The Circle SVG Path we draw
    var svgContainer = d3.select('#measure'+measure.cid);

    var circle = svgContainer.append("g")
        .append("path")
        .data([circleStates[0]])
        .attr("d", pathFunction)
        .attr("class", "circle");

    var compiledTemplate = _.template(this.representations[this.currentRepresentation], measureTemplateParamaters);
    $(this.el).find('.addMeasure').before( compiledTemplate );

基本上我正在尝试绘制一个带有路径的圆,该路径由已计算的点定义。我只是不知道如何通过 Backbone.View 将其传递给模板或 DOM

this 页面上选择“Bead”时出现控制台错误:

Error: Problem parsing d="function line(data) {
  var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
  function segment() {
    segments.push("                         jquery.js:6326
jQuery.extend.clean jquery.js:6326
jQuery.buildFragment jquery.js:6165
jQuery.fn.extend.domManip jquery.js:5975
jQuery.fn.extend.before jquery.js:5795
(anonymous function) measuresView.js:227
_.each._.forEach underscore.js:78
Backbone.View.extend.render measuresView.js:133
Backbone.View.extend.changeMeasureRepresentation measuresView.js:90
triggerEvents backbone.js:96
Backbone.Events.trigger backbone.js:187
Backbone.View.extend.cycle wholeMeasureRepresentationView.js:46
jQuery.event.dispatch jquery.js:3059
elemData.handle.eventHandle jquery.js:2677

这是完整的错误,与我的代码不匹配,让我相信这似乎是在尝试获取 d3 的函数并呈现它,而不是我期望 d3 返回的内容。堆栈跟踪最终将我带回到传入的已编译模板 ((anonymous function) measuresView.js:227),这就是我想要弄清楚的,如何将 d3 SVG 传递到模板中。

【问题讨论】:

  • 您发布的示例非常完整。你缺少什么部分?如何渲染模板然后使用 d3.js 注入内容?
  • 您必须发布更多代码,并且除了重现您的问题的代码之外,还可以选择包含一个 jsFiddle。
  • 我已经在这个fiddle中尽可能地最小化了文件,但是,我不知道如何消除require.js,我认为模板没有正确传递为类似!text 版本的字符串。但是,我确实对站点 here 进行了更改,因此您可以看到错误。只需将“度量表示”切换到 Bead,您就可以在控制台中看到错误。完整代码可以看here。感谢您的帮助!尝试替换为this
  • 我在您推送到的站点中没有看到任何错误。您能否发布您在控制台中看到的错误,行号等。
  • 我不确定您将 svg 传递给模板是什么意思。您真正想要做的是在视图的渲染函数中渲染模板,将 html 附加到 dom,然后使用模板中的元素作为可视化的根元素。

标签: backbone.js svg d3.js


【解决方案1】:

您遇到的问题在于珠模板。在模板中,您引用属性pathFunction,这是一个函数,您应该在其中引用该函数的返回值。只需将 pathFunction 更改为 pathFunction() ,假设 pathFunction 被编写为返回没有任何参数的 svg 路径,您应该没问题。如果是这样的话,模板应该是这样的:

<div id="measure<%= measure.cid %>" class="measure">
  <div class="btn" id="a">Unroll</div>
  <div class="btn" id="b">Rollup</div>
  <span class="title">Measure <span class="number"><%= measureCount %></span>
  <% if(measureCount == 1) { %>
  <% } else { %>
   - <span class="delete">[X]</span>
  <% } %>
  </span>
  <svg id="svg<%= measure.cid %>" xmlns="http://www.w3.org/2000/svg" version="1.1" class="circular-pie">
    <path d="<%= pathFunction() %>" />
    <!-- <circle cx="<%= cx %>" cy="<%= cy %>" r="<%= measureR %>" stroke="black" stroke-dasharray="1,3" stroke-width="1" fill="none" /> -->
    <g id="<%= beatHolder %>">
    </g>
  </svg> 
</div>

就您想要实现的目标而言,我认为您想要做的是将 SVG 元素呈现为模板的一部分,然后在将 HTML 附加到 DOM 之后,使用 SVG 元素作为根你的可视化,所以:

    // This should be in your view's render function
    // Render the template
    var compiledTemplate = _.template(this.representations[this.currentRepresentation], measureTemplateParamaters);
    // Insert the html into the DOM
    d3.select('#someContainer').html(compiledTemplate);
    // Then draw your visualization
    var pathFunction = d3.svg.line()
        .x(function (d) {return d.x;})
        .y(function (d) {return d.y;})
        .interpolate("basis");

    //The Circle SVG Path we draw
    var svgContainer = d3.select('#measure'+measure.cid);

    var circle = svgContainer.append("g")
        .append("path")
        .data([circleStates[0]])
        .attr("d", pathFunction(/*you'll need to insert some coordinate 
            information here see http://www.dashingd3js.com/svg-paths-and-d3js*/))
        .attr("class", "circle");
    // Do some other stuff

【讨论】:

  • 感谢您的帮助。我得到了它。我不知道我必须先创建模板,然后将 d3 应用/附加到模板。
【解决方案2】:

我认为这是因为您在 xml 和函数内部使用了相同的字符串分隔符 "。 JQuery 尝试解析您编译的模板,但无法评估在 ...segments.push( 处停止的“d”属性中的函数。

segments.push("M" 更改为segments.push('M' 并将segments.join("") 更改为segments.join(''),您应该没问题。

【讨论】:

  • 那是JQuery代码。那不是我的代码。我将代码中的所有双引号都更新为单引号,没有任何改变,同样的错误。我已经更新了 github 链接以显示新代码。我认为是在模板的编译中,我没有正确传递参数,或者没有正确编译模板。
猜你喜欢
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
相关资源
最近更新 更多