0

这是我用 d3.js 制作的图表,这是一个有效版本的截图

我为时间维度改变了一些东西。看这里

http://jsfiddle.net/GyWpN/14/

我正在比较连续几天的开放票和封闭票。

目前我觉得我的数据格式不正确。

 [
{
    "open": "1",
    "date": "2012-12-02 00:00:00+00",
    "completed": 0
},
{
    "open": "3",
    "date": "2012-12-11 00:00:00+00",
    "completed": 0
},
{
    "open": "1",
    "date": "2012-12-12 00:00:00+00",
    "completed": 0
},
{
    "open": "1",
    "date": "2012-12-17 00:00:00+00",
    "completed": 0
},



.
.
.
]

也许它应该采用不同的格式,因为我需要制作两组线进行比较。

数据应该是两个 json 数组吗?

我将如何完成这个图表?目前,在将x维度从更改为 后d3.scale.linear()d3.time.scale()我无法看到任何数据。我还将对象更改为您看到的当前 json 格式。

洞察力赞赏

4

1 回答 1

1

您可以使用这种数据格式来做您想做的事,这不是一种非常干燥的做事方式,但它可能会帮助您进行下一步:

var data = [
    {
        "open": "3",
        "date": "2012-12-02 00:00:00+00",
        "completed": 0
    },
    {
        "open": "4",
        "date": "2012-12-11 00:00:00+00",
        "completed": 1
    },
    {
        "open": "2",
        "date": "2012-12-12 00:00:00+00",
        "completed": 4
    },
    {
        "open": "5",
        "date": "2012-12-17 00:00:00+00",
        "completed": 9
    }];

var width = 276,
    height = 200,
    padding = 50;

// input format of date
var parse_date = d3.time.format("%Y-%m-%d 00:00:00+00").parse;

// clean data
data.forEach(function(d) {
    d.date = parse_date(d.date);
    d.open = parseInt(d.open);
    //d.completed = parseInt(d.completed);
});

// time scale for x axis
var x = d3.time.scale()
    .domain(d3.extent(data, function(d) { return d.date; }))
    .range([0, width-padding]);

// assume you start from 0 and that completed has max value
// probably needs improving
var y = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.completed; })])  
    .range([height-padding, 0]);

// verbose but simple way of defining lines and areas

var open_line = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.open); });

var complete_line = d3.svg.line()
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.completed); });

var open_area = d3.svg.area()
    .x(open_line.x())
    .y1(open_line.y())
    .y0(y(0));

var complete_area = d3.svg.area()
    .x(complete_line.x())
    .y1(complete_line.y())
    .y0(y(0));

// draw the svg
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);


// define xaxis
var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickFormat(d3.time.format("%d-%b"));

// attach data to a g object
var lines = svg.append( "g" )
    .data( [data] );  // a list with a single item as the whole path is generated from a single list

// draw lines and areas

lines.append( "path" )
    .attr("class", "line")
    .attr("d", open_line);

lines.append( "path" )
    .attr("class", "area")
    .attr("d", open_area);

lines.append( "path" )
    .attr("class", "line")
    .attr("d", complete_line);

lines.append( "path" )
    .attr("class", "area")
    .attr("d", complete_area);

// now use data without the additional nest as want to create an dot for each
// item in the list
dots = lines.selectAll(".dot")
    .data( data );

    // draw two lots of dots, one for opened and one for completed
    dots.enter()
    .append("circle")
    .attr("class", "dot")
    .attr("cx", open_line.x())
    .attr("cy", open_line.y())
    .attr("r",3.5);

    dots.enter()
    .append("circle")
    .attr("class", "dot")
    .attr("cx", complete_line.x())
    .attr("cy", complete_line.y())
    .attr("r",3.5);

// and put the xaxis in
svg.append("g")
    .attr("class", "axis")   // give it a class so it can be used to select only xaxis labels  below
    .attr("transform", "translate(0," + (height - padding) + ")")
    .call(xAxis)​

http://jsfiddle.net/phoebebright/JZJr8/4/

于 2013-01-03T22:41:05.117 回答