我正在創建類似於Mike Bostock's可縮放區域圖的圖表。d3JS:在線/面積圖上縮小時繪製較大數據集的較低密度數據版本
對於我的具體項目,我有一堆傳感器每隔30秒記錄一次數值(溫度,光線,溼度和聲音)。我有縮放實現工作,但是當縮小到一年的縮放比例時,圖表密度會減慢瀏覽器速度,並且圖形也不會讀取。
如何編輯腳本,以便線圖的密度相對於縮放量發生變化?換句話說,x域控制着價值鏈上的點數。當我放大到一個小時的時間範圍時,我想擁有全密度(每30秒記錄一次),而當我縮小時,我想要更低的密度(每天記錄一次)。有任何想法嗎?來自上面鏈接的腳本的實現將會很有幫助。
謝謝!
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<script type="text/javascript" src="d3/d3.js"></script>
<script type="text/javascript" src="d3/d3.csv.js"></script>
<script type="text/javascript" src="d3/d3.time.js"></script>
<link type="text/css" rel="stylesheet" href="style.css"/>
<style type="text/css">
svg {
font-size: 10px;
}
.axis {
shape-rendering: crispEdges;
}
.axis path, .axis line {
fill: none;
stroke-width: .5px;
}
.x.axis path {
stroke: #000;
}
.x.axis line {
stroke: #fff;
stroke-opacity: .5;
}
.y.axis line {
stroke: #ddd;
}
path.line {
fill: none;
stroke: #000;
stroke-width: .5px;
}
rect.pane {
cursor: move;
fill: none;
pointer-events: all;
}
</style>
</head>
<body>
<div id="body">
<div id="footer">
<span>…</span>
<div class="hint">mousewheel to zoom, drag to pan</div>
</div>
</div>
<script type="text/javascript">
var m = [79, 80, 160, 79],
w = 1280 - m[1] - m[3],
h = 800 - m[0] - m[2],
parse = d3.time.format("%Y-%m-%d").parse,
format = d3.time.format("%Y");
// Scales. Note the inverted domain for the y-scale: bigger is up!
var x = d3.time.scale().range([0, w]),
y = d3.scale.linear().range([h, 0]),
xAxis = d3.svg.axis().scale(x).orient("bottom").tickSize(-h, 0).tickPadding(6),
yAxis = d3.svg.axis().scale(y).orient("right").tickSize(-w).tickPadding(6);
// An area generator.
var area = d3.svg.area()
.interpolate("step-after")
.x(function(d) { return x(d.date); })
.y0(y(0))
.y1(function(d) { return y(d.value); });
// A line generator.
var line = d3.svg.line()
.interpolate("step-after")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
var svg = d3.select("body").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] + ")");
var gradient = svg.append("svg:defs").append("svg:linearGradient")
.attr("id", "gradient")
.attr("x2", "0%")
.attr("y2", "100%");
gradient.append("svg:stop")
.attr("offset", "0%")
.attr("stop-color", "#fff")
.attr("stop-opacity", .5);
gradient.append("svg:stop")
.attr("offset", "100%")
.attr("stop-color", "#999")
.attr("stop-opacity", 1);
svg.append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("x", x(0))
.attr("y", y(1))
.attr("width", x(1) - x(0))
.attr("height", y(0) - y(1));
svg.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + w + ",0)");
svg.append("svg:path")
.attr("class", "area")
.attr("clip-path", "url(#clip)")
.style("fill", "url(#gradient)");
svg.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")");
svg.append("svg:path")
.attr("class", "line")
.attr("clip-path", "url(#clip)");
svg.append("svg:rect")
.attr("class", "pane")
.attr("width", w)
.attr("height", h)
.call(d3.behavior.zoom().on("zoom", zoom));
d3.csv("flights-departed.csv", function(data) {
// Parse dates and numbers.
data.forEach(function(d) {
d.date = parse(d.date);
d.value = +d.value;
});
// Compute the maximum price.
x.domain([new Date(1999, 0, 1), new Date(2003, 0, 0)]);
y.domain([0, d3.max(data, function(d) { return d.value; })]);
// Bind the data to our path elements.
svg.select("path.area").data([data]);
svg.select("path.line").data([data]);
draw();
});
function draw() {
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
svg.select("path.area").attr("d", area);
svg.select("path.line").attr("d", line);
d3.select("#footer span").text("U.S. Commercial Flights, " + x.domain().map(format).join("-"));
}
function zoom() {
d3.event.transform(x); // TODO d3.behavior.zoom should support extents
draw();
}
</script>
</body>
</html>
這實際上並不是一件微不足道的事情,因爲您必須更改底層數據如何「翻譯」爲DOM元素。具體而言,您將不得不減少取決於縮放級別的代表數據點的數量。 –
@LarsKotthoff是對的,它不是微不足道的。我正在做很多事情,我會聽取縮放事件,並根據縮放比例重新計算傳遞給圖表的數據。請記住,「平移」會被記錄爲縮放比例爲1的縮放。另外請記住,d3的縮放只是縮放矢量繪圖,它不縮放實際數據。 –
只是爲了解決@LarsKotthoff的評論:因爲這是一個線條/面積圖,因此對於整個數據集總是隻有一個DOM對象,因此更容易隨時更改數據集。在其他類型的圖表中,當您更改數據集的精度時,您需要輸入和退出DOM對象,顯着降低速度(儘管可能比嘗試立即繪製所有內容更好)。 – AmeliaBR