所以,我一直在使用R& ggplot2取得良好进展并分享我们的数据分析结果。但是,我们想要更具互动性的东西。我们使用过Highcharts.js,但它在许多数据点的重压下破解,并且在定制方面不是很灵活。所以,我过去曾经和protovis玩过一段时间,但现在我想让D3工作。
我的两个关键问题如下:
在下面的代码中,我高举了行声明,然后调用这些函数添加到svg&样式。
我正在寻找的是帮助弄清楚如何将参数传递给line函数以指定要添加到给定行的数据元素。我可能需要以不同的方式格式化数据,如果这是最好的解决方案,这是完全可能的。
感谢任何输入!
----------------的更新 ----------------
此处需要帮助:
// MPGL
var line1 = d3.svg.line()
.x(function(d,i) {return x(startTime + (timeStep*i));})
.y(function(d) {return y(d.MPGL+d.MPGI+d.MTTFB);})
而不是传递
.y(function(d) {return y(d.MPGL+d.MPGI+d.MTTFB);})
我希望有一个更通用的声明,如:
.y(function(d) {return y(Z);})
然后以这样的方式调用该泛型行语句:
graph.append("svg:path").attr("d", line1(<something_corresponding_to_Z_here>)).attr("class", "MPGL");
那么,这是可能的,还是我只是在做梦?我需要以不同的方式划分我的数据吗?
----------------的 / UPDATE ----------------
完整代码:
<html>
<head>
<title>D3.js Test</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
body { font-family: "Helvetica Neue", Helvetica;}
/* tell the SVG path to be a thin line without any area fill */
path { stroke-width: 1; fill: none;}
/* Define Line color based on category class */
.MPGL {stroke: #644a9b;}
.MPGI {stroke: #009966;}
.MTTFB {stroke: #0066FF;}
/* Axis Formatting/styling */
.axis {
shape-rendering: crispEdges;
}
.x.axis line {
stroke: lightgrey;
}
.x.axis .minor {
stroke-opacity: .5;
}
.x.axis path {
display: none;
}
.x.axis text {
font-size: 10px;
}
.y.axis line, .y.axis path {
fill: none;
stroke: lightgrey;
}
.y.axis text {
font-size: 12px;
}
</style>
</head>
<body>
<div id="graph" class="aGraph" style="position:absolute;top:0px;left:0; float:left;"></div>
<script>
// define dimensions of graph
var m = [20, 20, 20, 40]; // margins
var w = 550; // width
var h = 300; // height
data = [ { "WK" : 14, "EOBSHR" : 1364839200000, "VOL" : 71383, "MPGL" : 2.901, "MPGI" : 1.203, "MTTFB" : 1.221, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364842800000, "VOL" : 70447, "MPGL" : 2.804, "MPGI" : 1.182, "MTTFB" : 1.211, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364846400000, "VOL" : 64878, "MPGL" : 2.781, "MPGI" : 1.169, "MTTFB" : 1.172, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364850000000, "VOL" : 56668, "MPGL" : 2.734, "MPGI" : 1.18, "MTTFB" : 1.153, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364853600000, "VOL" : 48721, "MPGL" : 2.722, "MPGI" : 1.134, "MTTFB" : 1.137, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364857200000, "VOL" : 45605, "MPGL" : 2.862, "MPGI" : 1.155, "MTTFB" : 1.116, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364860800000, "VOL" : 51002, "MPGL" : 3.219, "MPGI" : 1.136, "MTTFB" : 1.124, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364864400000, "VOL" : 62180, "MPGL" : 3.7, "MPGI" : 1.13, "MTTFB" : 1.143, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364868000000, "VOL" : 67299, "MPGL" : 3.965, "MPGI" : 1.198, "MTTFB" : 1.221, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364871600000, "VOL" : 58893, "MPGL" : 3.953, "MPGI" : 1.275, "MTTFB" : 1.24, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364875200000, "VOL" : 52752, "MPGL" : 4.082, "MPGI" : 1.373, "MTTFB" : 1.295, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364878800000, "VOL" : 55881, "MPGL" : 4.401, "MPGI" : 1.393, "MTTFB" : 1.39, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364882400000, "VOL" : 65844, "MPGL" : 4.608, "MPGI" : 1.394, "MTTFB" : 1.37, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364886000000, "VOL" : 78441, "MPGL" : 4.484, "MPGI" : 1.366, "MTTFB" : 1.399, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364889600000, "VOL" : 91130, "MPGL" : 4.047, "MPGI" : 1.321, "MTTFB" : 1.57, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364893200000, "VOL" : 89911, "MPGL" : 3.674, "MPGI" : 1.248, "MTTFB" : 1.314, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364896800000, "VOL" : 81673, "MPGL" : 3.548, "MPGI" : 1.298, "MTTFB" : 1.301, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364900400000, "VOL" : 85718, "MPGL" : 3.515, "MPGI" : 1.245, "MTTFB" : 1.289, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364904000000, "VOL" : 95746, "MPGL" : 3.541, "MPGI" : 1.236, "MTTFB" : 1.306, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 },
{ "WK" : 14, "EOBSHR" : 1364907600000, "VOL" : 105282, "MPGL" : 3.296, "MPGI" : 1.201, "MTTFB" : 1.273, "mPGL" : 3.549, "mPGI" : 1.274, "mTTFB" : 1.248 }]
// Find timeframe of dataset to create variables for display
var startTime = d3.min(data, function(d) { return d.EOBSHR; });
var endTime = d3.max(data, function(d) { return d.EOBSHR; })
var timeStep = 3600000;
// Setup scales to adjust display size based on content
var x = d3.time.scale().domain([startTime, endTime]).range([0, w]);
x.tickFormat(d3.time.format("%Y-%m-%d"));
var y = d3.scale.linear().domain([0, d3.max(data, function(d) { return d.MPGL+d.MPGI+d.MTTFB; })]).range([h, 0]);
// create a line function that can convert data[] into x and y points
//*********************************************
//*********************************************
//
// This is the area where input is needed!
//
//*********************************************
//*********************************************
// MPGL
var line1 = d3.svg.line()
.x(function(d,i) {return x(startTime + (timeStep*i));})
.y(function(d) {return y(d.MPGL+d.MPGI+d.MTTFB);})
// MPGI
var line2 = d3.svg.line()
.x(function(d,i) {return x(startTime + (timeStep*i));})
.y(function(d) {return y(d.MPGI+d.MTTFB);})
// MTTFB
var line3 = d3.svg.line()
.x(function(d,i) { return x(startTime + (timeStep*i)); })
.y(function(d) { return y(d.MTTFB);})
//--------------------------------------------------------------------
// Creating the visualization by pulling all of the elements together
//--------------------------------------------------------------------
// Add an SVG element with the desired dimensions and margin.
var graph = d3.select("#graph").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
// create yAxis
var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(1);
// Add the x-axis.
graph.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
// create left yAxis
var yAxisLeft = d3.svg.axis().scale(y).ticks(6).orient("left");
// Add the y-axis to the left
graph.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(-10,0)")
.call(yAxisLeft);
//*********************************************************
// How do I pass something in the line_x_(...) portion
// that would give the function a clue which data point
// to add to the line/path?
//*********************************************************
// add lines
// do this AFTER the axes above so that the line is above the tick-lines
graph.append("svg:path").attr("d", line1(data)).attr("class", "MPGL");
graph.append("svg:path").attr("d", line2(data)).attr("class", "MPGI");
graph.append("svg:path").attr("d", line3(data)).attr("class", "MTTFB");
</script>
</body>
</html>
答案 0 :(得分:1)
使用D3时,在传入数据时,最好坚持选择模式。例如,请参阅this tutorial。在您的特定情况下,您可以将数据提供给datum()
函数,然后相应地添加行。也就是说,代码的最后三行将成为
graph.append("path")
.datum(data)
.attr("class", "MPGL")
.attr("d", line1);
和其他线类似。现在,您可以将data
参数替换为要绘制的数据子集并更新该行。您可以使用任何D3或Javascript函数来过滤数据。 This tutorial详细介绍了更新数据。
对于工具提示,this answer应该有所帮助。