D3js从数组而不是文件获取数据 [英] D3js take data from an array instead of a file

查看:97
本文介绍了D3js从数组而不是文件获取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现这个优秀的d3js图表这里。然而在我的情况下,我想要这个图表从一个数组,而不是tsv文件的价值。我想让它从表[]中取值。我怎么能这样做?因为它使用了一个函数,我不知道应该把数组放在哪里。

 使用d3-tip添加工具提示到d3条形图。 
<!DOCTYPE html>
< meta charset =utf-8>
< style>

body {
font:10px sans-serif;
}

.axis路径,
.axis行{
fill:none;
stroke:#000;
shape-rendering:crispEdges;
}

.bar {
fill:orange;
}

.bar:hover {
fill:orangered;
}

.x.axis路径{
display:none;
}

.d3-tip {
line-height:1;
font-weight:bold;
padding:12px;
background:rgba(0,0,0,0.8);
color:#fff;
border-radius:2px;
}

/ *为工具提示创建一个小三角形扩展器* /
.d3-tip:{
box-sizing:border-box;
display:inline;
font-size:10px;
width:100%;
line-height:1;
color:rgba(0,0,0,0.8);
content:\25BC;
position:absolute;
text-align:center;
}

/ *风格向北的工具提示不同* /
.d3-tip.n:after {
margin:-1px 0 0 0;
top:100%;
left:0;
}
< / style>
< body>
< script src =http://d3js.org/d3.v3.min.js>< / script>
< script src =http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js>< / script>
< script>

var margin = {top:40,right:20,bottom:30,left:40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

var formatPercent = d3.format(。0%);

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)
.tickFormat(formatPercent);

var tip = d3.tip()
.attr('class','d3-tip')
.offset([ - 10,0])
.html(function(d){
return Frequency:< / strong>< span style ='color:red'>+ d.frequency +< / span& ;
})

var svg = d3.select(body)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.call(tip);

d3.tsv(data.tsv,type,function(error,data){
x.domain(data.map(function(d){return d.letter;} ));
y.domain([0,d3.max(data,function(d){return d.frequency;})]);

svg.append(g )
.attr(class,x axis)
.attr(transform,translate(0,+ height +))
.call(xAxis) ;

svg.append(g)
.attr(class,y axis)
.call(yAxis)
.append文本)
.attr(transform,rotate(-90))
.attr(y,6)
.attr(dy,.71em )
.style(text-anchor,end)
.text(Frequency);

svg.selectAll(。bar)
.data(data)
.enter()。append(rect)
.attr(class,bar)
.attr(x,function ){return x(d.letter);})
.attr(width,x.rangeBand())
.attr(y频率);})
.attr(height,function(d){return height - y(d.frequency);})
.on('mouseover',tip.show)
.on('mouseout',tip.hide)

});

函数类型(d){
d.frequency = + d.frequency;
return d;
}

< / script>

D3图库有很多很好的示例,但是很多示例都会从制表符分隔值文件加载数据。这是一个很好的方法来分离数据和可视化在简短的例子,但它可能有点混乱,如果你是新的D3和JavaScript,因为它需要一些基本知识关于d3.tsv()和回调函数,以了解什么是




h2> d3.tsv()是什么?

d3.tsv()基本上负责从data.tsv加载数据,将其解析为一个名为data的变量,并将此变量发送到回调函数

  d3.tsv(data.tsv,type,function(error,data){<  - 这是回调函数!
//此代码在加载data.tsv文件时执行
});

加载数据后,会将其作为数据参数发送到函数。然后在回调函数内部的代码被执行。因为我们不需要回调函数作为d3.tsv()函数的参数,所以我们直接使用

这种使用回调和匿名函数是非常典型的JavaScript,是值得值得一读的。 了解JavaScript回调函数并使用它了解JavaScript回调应该让您开始。



如何重写示例以使用来自局部变量的数据?



首先,我们要使变量包含我们的数据。让我们将它称为data,与在回调函数中相同,并给出示例中的值。

  var data = [
{letter:A,frequency:.08167},
{letter:B,frequency:.01492},
{letter:C,frequency:。 02780},
{letter:D,frequency:.04253},
{letter:E,frequency:.12702},
{letter:F .02288},
{letter:G,frequency:.02022},
{letter:H,frequency:.06094},
{letter:I :.06973},
{letter:J,frequency:.00153},
{letter:K,frequency:.00747},
{letter:L频率:.04025},
{letter:M,frequency:.02517},
{letter:N,frequency:.06749},
{letter:O ,频率:.07507},
{letter:P,frequency:.01929},
{letter:Q,frequency:.00098},
{letter:R ,频率:.05987},
{字母:S,频率:.06333},
{字母:T,频率:.09056},
{ U,频率:.02758},
{letter:V,frequency:.01037},
{letter:W,frequency:.02465},
{ X,频率:.00150},
{letter:Y,frequency:.01971},
{letter:Z,frequency:.00074}
];

将此变量放在调用d3.tsv之前的某处,因为回调函数中的代码是依赖的对这个变量。



我选择将数据表示为具有字母和频率属性的对象列表。这是一个简单的方法,因为它非常类似于d3.tsv()解析.tsv文件的方式。这意味着我们不必更改回调函数中的代码,因为它已经预期了一个变量,该数据具有此格式。您可以根据需要更改此设置,但请记住更改回调代码如何使用data变量。



现在我们可以删除与d3.tsv相关的代码调用,只需留下包含在回调函数中的代码。所以这段代码:

  d3.tsv(data.tsv,type,function(error,data){
x.domain(data.map(function(d){return d.letter;}));
//代码省略
.on('mouseout',tip.hide)
});

成为此代码:

  x.domain(data.map(function(d){return d.letter;})); 
//代码省略。
.on('mouseout',tip.hide)

精细。你可以使用这个策略来重写D3库中的其他示例。



最后,我包含了新的index.html文件的代码。有关工作示例,请访问 JSFiddle

 <!DOCTYPE html> 
< meta charset =utf-8>
< style>

body {
font:10px sans-serif;
}

.axis路径,
.axis行{
fill:none;
stroke:#000;
shape-rendering:crispEdges;
}

.bar {
fill:orange;
}

.bar:hover {
fill:orangered;
}

.x.axis路径{
display:none;
}

.d3-tip {
line-height:1;
font-weight:bold;
padding:12px;
background:rgba(0,0,0,0.8);
color:#fff;
border-radius:2px;
}

/ *为工具提示创建一个小三角形扩展器* /
.d3-tip:{
box-sizing:border-box;
display:inline;
font-size:10px;
width:100%;
line-height:1;
color:rgba(0,0,0,0.8);
content:\25BC;
position:absolute;
text-align:center;
}

/ *风格向北的工具提示不同* /
.d3-tip.n:after {
margin:-1px 0 0 0;
top:100%;
left:0;
}
< / style>
< body>
< script src =http://d3js.org/d3.v3.min.js>< / script>
< script src =http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js>< / script>
< script>

var margin = {top:40,right:20,bottom:30,left:40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

var formatPercent = d3.format(。0%);

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)
.tickFormat(formatPercent);

var tip = d3.tip()
.attr('class','d3-tip')
.offset([ - 10,0])
.html(function(d){
return Frequency:< / strong>< span style ='color:red'>+ d.frequency +< / span& ;
})

var svg = d3.select(body)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.call(tip);

//新的数据变量。
var data = [
{letter:A,frequency:.08167},
{letter:B,frequency:.01492},
{letter: C,频率:.02780},
{letter:D,frequency:.04253},
{letter:E,frequency:.12702},
{ F,频率:.02288},
{letter:G,frequency:.02022},
{letter:H,frequency:.06094},
{letter :I,频率:.06973},
{字母:J,频率:.00153},
{字母:K,频率:.00747}字母:L,频率:.04025},
{letter:M,frequency:.02517},
{letter:N,frequency:.06749},
{letter:O,frequency:.07507},
{letter:P,frequency:.01929},
{letter:Q,frequency:.00098},
{letter:R,frequency:.05987},
{letter:S,frequency:.06333},
{letter:T,frequency:.09056},
{letter:U,frequency:.02758},
{letter:V,frequency:.01037},
{letter:W,frequency:.02465},
{letter:X,frequency:.00150},
{letter:Y,frequency:.01971},
{letter:Z,frequency:.00074}
];

//下面的代码包含在回调函数中。
x.domain(data.map(function(d){return d.letter;}));
y.domain([0,d3.max(data,function(d){return d.frequency;})]);

svg.append(g)
.attr(class,x axis)
.attr(transform height +))
.call(xAxis);

svg.append(g)
.attr(class,y axis)
.call(yAxis)
.append )
.attr(transform,rotate(-90))
.attr(y,6)
.attr(dy,.71em)
.style(text-anchor,end)
.text(Frequency);

svg.selectAll(。bar)
.data(data)
.enter()。append(rect)
.attr ,bar)
.attr(x,function(d){return x(d.letter);})
.attr(width,x.rangeBand b $ b .attr(y,function(d){return y(d.frequency);})
.attr(height,function(d){return height - y(d.frequency) ;})
.on('mouseover',tip.show)
.on('mouseout',tip.hide)

函数类型(d){
d.frequency = + d.frequency;
return d;
}

< / script>


I have found this excellent d3js chart here. However in my case I want this chart to take value from an array instead of a tsv file. I want to make it to take values from a table []. How I can do that? because it uses a function for that, and I do not know where I should put my array.

Using d3-tip to add tooltips to a d3 bar chart.
<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: orange;
}

.bar:hover {
  fill: orangered ;
}

.x.axis path {
  display: none;
}

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var formatPercent = d3.format(".0%");

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")
    .tickFormat(formatPercent);

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
  })

var svg = d3.select("body").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.call(tip);

d3.tsv("data.tsv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.letter; }));
  y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Frequency");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.letter); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.frequency); })
      .attr("height", function(d) { return height - y(d.frequency); })
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide)

});

function type(d) {
  d.frequency = +d.frequency;
  return d;
}

</script>

Thanks a lot

解决方案

The D3 gallery has a lot of good examples, but a lot of the examples loads their data from a tab-separated values file. This is a nice way to separate data and visualization in short examples, but it can be a bit confusing if you are new to D3 and JavaScript, since it requires some basic knowledge about both d3.tsv() and callback functions to understand what is going on.

Disclaimer: The following sections will give some very simplified explanations.

What is d3.tsv() doing?

d3.tsv() is basically responsible for loading the data from data.tsv, parse it into a variable called data, and send this variable to a callback function.

d3.tsv("data.tsv", type, function(error, data) { <- This is the callback function!
  // This code is executed when the data.tsv file is loaded.
});

As soon as the data is loaded, it is sent as the data argument to the function. Then the code inside the callback function is executed. Since we don't need the callback function for anything else than as an argument to the d3.tsv() function, we make it directly as an anonymous function, instead of giving it a name like usual.

This kind of use of callback and anonymous functions is very typical of JavaScript, and is well worth reading up on. Understand JavaScript Callback Functions and Use Them and Understanding JavaScript Callbacks should get you started.

Let's see how we can use this information to rewrite our code.

How can I rewrite the example to use data from a local variable?

First we have to make variable containing our data. Let's call it "data", the same as in our callback function, and give it the values from the example.

var data = [
  {letter: "A", frequency: .08167},
  {letter: "B", frequency: .01492},
  {letter: "C", frequency: .02780},
  {letter: "D", frequency: .04253},
  {letter: "E", frequency: .12702},
  {letter: "F", frequency: .02288},
  {letter: "G", frequency: .02022},
  {letter: "H", frequency: .06094},
  {letter: "I", frequency: .06973},
  {letter: "J", frequency: .00153},
  {letter: "K", frequency: .00747},
  {letter: "L", frequency: .04025},
  {letter: "M", frequency: .02517},
  {letter: "N", frequency: .06749},
  {letter: "O", frequency: .07507},
  {letter: "P", frequency: .01929},
  {letter: "Q", frequency: .00098},
  {letter: "R", frequency: .05987},
  {letter: "S", frequency: .06333},
  {letter: "T", frequency: .09056},
  {letter: "U", frequency: .02758},
  {letter: "V", frequency: .01037},
  {letter: "W", frequency: .02465},
  {letter: "X", frequency: .00150},
  {letter: "Y", frequency: .01971},
  {letter: "Z", frequency: .00074}
];

Put this variable somewhere before the call to d3.tsv, as the code in the callback function is dependent on this variable.

I have choose to represent the data as a list of objects with a letter and frequency property. This is an easy way to do it, since it closely resembles the way d3.tsv() would parse the .tsv file. This means that we don't have to change the code in the callback function, since it already expects a variable with data in this format. You can change this if you like, but remember to change how the callback code uses the "data" variable.

Now we can remove the code related to the d3.tsv call, just leaving the code contained in the callback function. So this code:

d3.tsv("data.tsv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.letter; }));
  // code omitted.
  .on('mouseout', tip.hide)
});

Becomes this code:

x.domain(data.map(function(d) { return d.letter; }));
// code omitted.
.on('mouseout', tip.hide)

Now the example should be working fine. You can play around with this strategy for rewriting other examples in the D3 gallery as well.

Finally, I have included the code for the new index.html file. A working example can be found at JSFiddle.

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: orange;
}

.bar:hover {
  fill: orangered ;
}

.x.axis path {
  display: none;
}

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>

var margin = {top: 40, right: 20, bottom: 30, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var formatPercent = d3.format(".0%");

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")
    .tickFormat(formatPercent);

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
  })

var svg = d3.select("body").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.call(tip);

// The new data variable.
var data = [
  {letter: "A", frequency: .08167},
  {letter: "B", frequency: .01492},
  {letter: "C", frequency: .02780},
  {letter: "D", frequency: .04253},
  {letter: "E", frequency: .12702},
  {letter: "F", frequency: .02288},
  {letter: "G", frequency: .02022},
  {letter: "H", frequency: .06094},
  {letter: "I", frequency: .06973},
  {letter: "J", frequency: .00153},
  {letter: "K", frequency: .00747},
  {letter: "L", frequency: .04025},
  {letter: "M", frequency: .02517},
  {letter: "N", frequency: .06749},
  {letter: "O", frequency: .07507},
  {letter: "P", frequency: .01929},
  {letter: "Q", frequency: .00098},
  {letter: "R", frequency: .05987},
  {letter: "S", frequency: .06333},
  {letter: "T", frequency: .09056},
  {letter: "U", frequency: .02758},
  {letter: "V", frequency: .01037},
  {letter: "W", frequency: .02465},
  {letter: "X", frequency: .00150},
  {letter: "Y", frequency: .01971},
  {letter: "Z", frequency: .00074}
];

// The following code was contained in the callback function.
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
  .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("Frequency");

svg.selectAll(".bar")
    .data(data)
  .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return x(d.letter); })
    .attr("width", x.rangeBand())
    .attr("y", function(d) { return y(d.frequency); })
    .attr("height", function(d) { return height - y(d.frequency); })
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide)

function type(d) {
  d.frequency = +d.frequency;
  return d;
}

</script>

这篇关于D3js从数组而不是文件获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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