使用d3和从rails传递的JSON数据对象绘制线 [英] Plotting a line using d3 and an JSON data object passed from rails

查看:140
本文介绍了使用d3和从rails传递的JSON数据对象绘制线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里推动经验的界限,看不到我做错了什么。

I'm pushing the boundaries of experience here and cant see what I am doing wrong.

我从rails中的一个数据库中提取一堆数据,

I'm pulling a bunch of data from a DB in rails, converting it to JSON and trying to plot it in d3.

数据是一个简单的{date => number}的JSON,数据很好。

The data is a simple JSON of {date => number} and the data is fine.

我在代码底部的循环中做了一些错误,但看不到什么。

I'm doing something wrong with d3 in the loop at the bottom of the code but cant see what.

这是我的代码:

var data = <%= @signups.to_json.html_safe %>;

var date, signups

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

var parseDate = d3.time.format("%d-%b-%Y").parse;

var x = d3.time.scale()
    .range([0, width]);

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");

var line = d3.svg.line()
    .x(date)
    .y(signups)
    .interpolate("linear");

var svg = d3.select(".container").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 + ")");

// Find range of data for domain
var min_date = Infinity, max_date = -Infinity;
var min_signups = Infinity, max_signups = -Infinity;
var x;

$.each(data, function(key, value) {

    temp = parseDate(key)
    if( temp < min_date) min_date = temp;
    if( temp > max_date) max_date = temp;

    if( +value < min_signups) min_signups = +value;
    if( +value > max_signups) max_signups = +value;

});

x.domain([min_date, max_date]);
y.domain([0, max_signups]);

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("Price ($)");

svg.append("path")

$.each(data, function(key, value) {
    date = parseDate(key);
    signups = value;

    d3.select("path")
    .append("svg")
    .attr("d", d3.svg.line()
        .x(date)
        .y(signups)
        .interpolate("linear"));    
});

任何帮助将非常感谢

推荐答案

D3方法是将所有数据传递到合适的行生成器。这在你的情况下是相当简单的,你只需要将包含所有数据的对象转换为D3可以使用的数组,使用 d3.entries()

The D3 way would be to pass all your data to a suitable line generator. This is fairly simple in your case, you just need to convert the object that contains all the data to an array that D3 can work with using d3.entries().

var line = d3.svg.line()
             .x(function(d) { return x(parseDate(d.key)); })
             .y(function(d) { return y(d.value); });
svg.selectAll("path").data([d3.entries(data)])
   .enter().append("path").attr("d", line);

由于您只有一行,您还可以使用 .datum )以绑定数据,但使用 .data()可以让您稍后传递数据以供更多行使用。

As you have only a single line, you could also use .datum() to bind the data, but using .data() leaves you the option of passing in data for more lines later.

完成jsfiddle 这里。修改此项时,请务必在添加轴之前创建线,否则D3的数据匹配将无法使用默认匹配,您将不会得到任何线。为了解决这个问题,你可以提供一个匹配的函数,但开始它更容易保持这个顺序。

Complete jsfiddle here. When modifying this, make sure that you create the line before adding the axes, otherwise D3's data matching won't work with the default matching and you won't get any lines. To fix this, you could supply a matching function, but to start with it's much easier to keep to this order.

这篇关于使用d3和从rails传递的JSON数据对象绘制线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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