【问题标题】:D3.js Graphs in JavaScript Templates (jsRender/jsViews, jquery tmpl, etc.)JavaScript 模板中的 D3.js 图形(jsRender/jsViews、jquery tmpl 等)
【发布时间】:2015-09-09 21:40:13
【问题描述】:

我一直在尝试创建一个使用 JavaScript 模板的页面,其中包含使用 d3.js 制作的图表以显示有关每个库存项目的信息(在此示例中,我有一个包含晶体管数据的 JSON blob 数组。)例如,我需要样板“绝对最大额定值”表,然后是一系列栅极电压的阻抗曲线图。这是我目前所拥有的:

var partData = [
	{
		name: "IRF10",
		maxRatings:
		{
			vds: 200,
			vgs: 20,
			id: 2.1,
			pd: 36
		},
		impedanceGraph:
		[
			[1, 0.7],
			[2, 1.6],
			[3, 2.0],
			[4, 2.5]
		]
	},
	{
		name: "2n7000",
		maxRatings:
		{
			vds: 60,
			vgs: 20,
			id: 0.2,
			pd: 0.4
		},
		impedanceGraph:
		[
			[1, 0.6],
			[2, 1.5],
			[3, 1.9],
			[4, 2.4]
		]
	}
]

$('#container').html($('#partTemplate').render(partData));
<script id="partTemplate" type="text/x-jsrender">
    <div style="background-color:mintcream">
        <h2>{{>name}}</h2>
        Max Ratings
        {{props maxRatings}}
            <li>{{>key}}: {{>prop}}</li>
        {{/props}}
        <br />
        Impedance Graph: <br />
        PLACE_D3_GRAPH_HERE
    </div>
</script>
<div id="container"></div>

这是我的 jsfiddle,因为 jsRender 不太好用: http://jsfiddle.net/xaty70b6/

由于 D3.js 似乎通过将 SVG 元素附加到正文并将数据插入到选择中来工作,我被引导相信我需要以某种方式使用 jquery 选择模板实例并将其提供给 D3 .js 来构建图表,但我不知道如何在构建行时获取模板实例。真的,我想要做的就是使用在该实例的 JSON blob 中提供的数据,在我的模板实例中显示一个 D3.js 图。是否有另一种方法可以将 SVG 插入到带有相关数据数组的 D3.js 中?

【问题讨论】:

    标签: jquery templates d3.js jsrender jsviews


    【解决方案1】:

    我没有使用过 D3.js,但是在研究它时,很明显 D3 直接在 DOM 上工作 - 而 JsRender 渲染独立于 DOM - 并生成一个 HTML 字符串,然后您将其插入 DOM自己。

    然而,JsViews 完全是“DOM 感知”的,并且在模板实例、数据和 DOM 之间进行绑定。所以我建议使用 JsViews。

    此外,这还开启了使用 JsViews 数据绑定以交互方式更新数据的可能性。 JsView 数据绑定当然不同于 D3 的数据绑定,但是探索整合它们还是很有趣的。

    所以这里(在下面的代码 sn-p 中,也在这里:http://jsfiddle.net/BorisMoore/Lbfn5aog/1/)是一种方法。

    我创建了一个自定义 {{barChart}} 标签,用于集成 D3 图表:

    $.views.tags("barChart", {
      init: function(tagCtx, linkCtx) {
        this.data = tagCtx.args[0];
        this.svg = initChart(linkCtx.elem, this.data);
      },
      onAfterLink: function(tagCtx, linkCtx) {
        var tag = this;
        $.observable(tag.data).observeAll(function() {
          updateChart(tag.data, tag.svg);
        });
      }
    });
    

    并将其包含在模板中,如下所示:

    <div class="chart" data-link="{barChart impedanceGraph}"></div>
    

    (也可以使用标签呈现的 div 创建一个版本,因此您可以改为写{^{barChart impedanceGraph /}}...)

    如果您不想要动态数据绑定,可以省略onAfterLink 方法。

    但是如果你包含它,那么现在你可以修改文本框中的值,数据将由 JsViews 更新。数据链接的 barChart 标记将获取更改并将其传递给 D3,D3 将重新计算列,并酌情使用新的缩放因子。

    var margin = {top: 20, right: 20, bottom: 30, left: 40},
      width = 180 - margin.left - margin.right,
      height = 200 - margin.top - margin.bottom;
    
    function scaleChart(data) {
      var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);
    
      var y = d3.scale.linear()
        .range([height, 0]);
    
      var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");
    
      var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(10, "%");
    
      x.domain(data.map(function(d) { 
        return d.name; }));
      y.domain([0, d3.max(data, function(d) {
        return d.amt; 
      })]);
    
      return {x:x, y:y, xAxis: xAxis, yAxis: yAxis};
    }
    
    function initChart(element, data) {
      var chart = scaleChart(data);
      var svg = d3.select(element).append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
      svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(chart.xAxis);
    
      svg.selectAll(".bar")
        .data(data)
        .enter().append("rect")
          .attr("class", "bar")
          .attr("x", function(d) {
            return chart.x(d.name);
          })
          .attr("width", chart.x.rangeBand())
          .attr("y", function(d) { return chart.y(d.amt); })
          .attr("height", function(d) {
            return height - chart.y(d.amt);
          });
      return svg;
    }
    
    function updateChart(data, svg) {
      var chart = scaleChart(data);
        svg.selectAll(".bar")
          .data(data)
          .attr("y", function(d) { return chart.y(d.amt); })
          .attr("height", function(d) {
            return height - chart.y(d.amt);
          });
    }
    
    var partData = [
      {
        name: "IRF10",
        maxRatings:
        {
          vds: 200,
          vgs: 20,
          id: 2.1,
          pd: 36
        },
        impedanceGraph:
        [
          {name: 1, amt: 0.7},
          {name: 2, amt: 1.6},
          {name: 3, amt: 2.0},
          {name: 4, amt: 2.0},
          {name: 5, amt: 0.5}
        ]
      },
      {
        name: "2n7000",
        maxRatings:
        {
          vds: 60,
          vgs: 20,
          id: 0.2,
          pd: 0.4
        },
        impedanceGraph:
        [
          {name: 1, amt: 0.6},
          {name: 2, amt: 1.5},
          {name: 3, amt: 1.9},
          {name: 4, amt: 2.4}
        ]
      }
    ]
    
    $.views.tags("barChart", {
      init: function(tagCtx, linkCtx) {
        this.data = tagCtx.args[0];
        this.svg = initChart(linkCtx.elem, this.data);
      },
      onAfterLink: function(tagCtx, linkCtx) {
        var tag = this;
        $.observable(tag.data).observeAll(function() {
          updateChart(tag.data, tag.svg);
        });
      }
    });
    
    var tmpl = $.templates("#partTemplate");
    
    tmpl.link('#container', partData);
    li {
      list-style:none
    }
    .bar {
      fill: steelblue;
    }
    
    .bar:hover {
      fill: brown;
    }
    
    .axis {
      font: 10px sans-serif;
    }
    
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
    
    .x.axis path {
      display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//www.jsviews.com/download/jsviews.js"></script>
    
    <script id="partTemplate" type="text/x-jsrender">
        <div style="background-color:mintcream">
            <h2>{{>name}}</h2>
            Max Ratings
            <ul>
              {{props maxRatings}}
                <li>{{>key}}: {{>prop}}</li>
              {{/props}}
            </ul>
            <br />
            Impedance Graph: <br />
            <ul>
              {{for impedanceGraph}}
                <li><input data-link="amt" /></li>
              {{/for}}
            </ul>
            <div class="chart" data-link="{barChart impedanceGraph}"></div>
        </div>
    </script>
    
    <div id="container"></div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 2011-08-18
      • 2013-02-27
      • 2012-04-15
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多