JavaScript模板中的D3.js图形(jsRender/jsViews,jquery tmpl等) [英] D3.js Graphs in JavaScript Templates (jsRender/jsViews, jquery tmpl, etc.)

查看:101
本文介绍了JavaScript模板中的D3.js图形(jsRender/jsViews,jquery tmpl等)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图创建一个使用JavaScript模板的页面,该页面结合了使用d3.js制作的图形来显示有关每个库存项目的信息(在本示例中,我有一个包含晶体管数据的JSON blob数组.)例如,我需要样板绝对最大额定值"表,然后是诸如一系列门电压的阻抗曲线之类的图形.这是我到目前为止的内容:

I've been trying to create a page that uses JavaScript Templates which incorporate graphs made using d3.js to display information about each inventory item (in this example, I have an array of JSON blobs containing transistor data.) For example, I need boilerplate "Absolute Max Ratings" table followed by graphs like the impedance curve for a range of Gate Voltages. Here's what I have so far:

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/

Here is my jsfiddle since jsRender doesn't quite work: http://jsfiddle.net/xaty70b6/

由于D3.js似乎可以通过在主体上添加SVG元素并将数据插入到选区中来工作,所以我被认为我需要以某种方式选择带有jquery的模板实例并将其提供给D3 .js来构建图形,但是我不知道如何在构建行时获取模板实例.确实,我要做的就是使用该实例的JSON Blob中提供的数据在我的模板实例中显示一个D3.js图.也许还有另一种方法可以将SVG与相关的数据数组一起插入D3.js中?

Since D3.js appears to work by appending an SVG element to the body and inserting data to the selection, I've been led to believe that I need to somehow select the instance of a template with jquery and feed that to D3.js to build the graph, but I have no idea how to get the template instance while building the rows. Really, All I want to do is have a D3.js graph appear in my template instance using the data provided inside the JSON blob for that instance. Is there perhaps another way to insert the SVG to be passed into D3.js with the pertinent data array?

推荐答案

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

I have not worked with D3.js, but on looking into it, it is clear the D3 works directly on the DOM - whereas JsRender rendering is independent of the DOM - and produces an HTML string that you then insert into the DOM yourself.

但是,JsViews完全了解DOM",并且在模板实例,数据和DOM之间进行绑定.所以我建议使用JsViews.

However JsViews is completely 'DOM aware' and does binding between the template instances, the data and the DOM. So I would suggest using JsViews.

此外,这还提供了使用JsViews数据绑定以交互方式更新数据的可能性. JsView数据绑定当然不同于D3的数据绑定,但是探索将它们集成起来很有趣.

In addition that opens the possibility of using JsViews data-binding to update the data interactively. JsView data-binding is of course different than D3's data-binding, but it is interesting to explore integrating them.

因此,这里(在下面的代码段中,也在这里: http://jsfiddle.net/BorisMoore/Lbfn5aog/1/)是一种解决方法.

So here (in the code snippet below, and also here: http://jsfiddle.net/BorisMoore/Lbfn5aog/1/) is one approach to that.

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

I have created a custom {{barChart}} tag, to integrate the D3 chart:

$.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);
    });
  }
});

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

and included it in the template like so:

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

(也可以使用标记渲染的div创建一个版本,因此您可以写{^{barChart impedanceGraph /}}代替...)

(One could also create a version with the div rendered by the tag, so you could write {^{barChart impedanceGraph /}} instead...)

如果您不希望进行动态数据绑定,则可以省略onAfterLink方法.

If you don't want the dynamic data-binding, you can omit the onAfterLink method.

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

But if you include it, then now you can modify the values in the text boxes and the data will be updated by JsViews. The data-linked barChart tag will pick up the change and pass it to D3 which will recalculate the columns, with a new scaling factor as appropriate.

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>

这篇关于JavaScript模板中的D3.js图形(jsRender/jsViews,jquery tmpl等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆