Quy tắc chung khi sử dụng data-join là bạn muốn ánh xạ một-một từ dữ liệu đến các thành phần. Vì vậy, nếu bạn có hai chuỗi trong phân tán của mình, bạn sẽ muốn có hai phần tử vùng chứa (chẳng hạn như G elements) để đại diện cho chuỗi. Vì hiện tại bạn chỉ có một mảng data
, bạn cũng sẽ muốn sử dụng array.map để chuyển đổi đại diện dữ liệu thành hai mảng song song có cùng biểu diễn. Bằng cách này, bạn không phải lặp lại mã cho mỗi chuỗi.
Giả sử dữ liệu của bạn đã được đại diện trong một tập tin CSV với một cột cho x -values, và nhiều cột khác cho y -values của mỗi series:
x,y1,y2
5,90,22
25,30,25
45,50,80
65,55,9
85,25,95
Nếu bạn muốn mã hoàn toàn chung chung, trước tiên bạn cần phải tính toán tên của chuỗi, chẳng hạn như ["y1", "y2"]
. (Nếu bạn đã thêm cột thứ ba vào tệp CSV, có thể là ["y1", "y2", "y3"]
.) Bạn có thể tính toán tên bằng cách sử dụng d3.keys, trích xuất các thuộc tính được đặt tên từ một đối tượng. Ví dụ: d3.keys({foo: 1, bar: 2})
trả lại ["foo", "bar"]
.
// Compute the series names ("y1", "y2", etc.) from the loaded CSV.
var seriesNames = d3.keys(data[0])
.filter(function(d) { return d !== "x"; })
.sort();
Bây giờ bạn có tên chuỗi, bạn có thể tạo một mảng các mảng điểm. Mảng bên ngoài đại diện cho chuỗi (trong đó có hai) và mảng bên trong lưu trữ các điểm dữ liệu. Bạn có thể đồng thời chuyển đổi các điểm thành một biểu diễn nhất quán (các đối tượng có các thuộc tính x
và y
), cho phép bạn sử dụng lại mã qua hàng loạt.
// Map the data to an array of arrays of {x, y} tuples.
var series = seriesNames.map(function(series) {
return data.map(function(d) {
return {x: +d.x, y: +d[series]};
});
});
Lưu ý mã này sử dụng toán tử +
để ép buộc giá trị CSV thành số. (Tệp CSV không được nhập, vì vậy ban đầu chúng là chuỗi.)
Bây giờ bạn đã ánh xạ dữ liệu của mình theo định dạng thông thường, bạn có thể tạo các phần tử G cho mỗi chuỗi và sau đó khoanh tròn các phần tử bên trong cho từng điểm. Kết quả là cấu trúc SVG sẽ trông như thế này:
<g class="series">
<circle class="point" r="4.5" cx="1" cy="2"/>
<circle class="point" r="4.5" cx="3" cy="2"/>
…
</g>
<g class="series">
<circle class="point" r="4.5" cx="5" cy="4"/>
<circle class="point" r="4.5" cx="7" cy="6"/>
…
</g>
Và mã D3 tương ứng:
// Add the points!
svg.selectAll(".series")
.data(series)
.enter().append("g")
.attr("class", "series")
.style("fill", function(d, i) { return z(i); })
.selectAll(".point")
.data(function(d) { return d; })
.enter().append("circle")
.attr("class", "point")
.attr("r", 4.5)
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); });
tôi tôi cũng đã thêm một chút mã để gán từng loạt một màu độc đáo bằng cách thêm một phong cách điền với phần tử G chứa. Có rất nhiều cách khác nhau để làm điều này, tất nhiên. (Ví dụ: bạn có thể muốn cụ thể hơn về màu sắc cho mỗi chuỗi). Tôi cũng đã để lại mã tính toán các miền của các quy mô x và y của bạn (cũng như hiển thị các trục), nhưng nếu bạn muốn xem toàn bộ ví dụ làm việc:
gần như một hướng dẫn ... điều này và các câu hỏi tương tự khác đã được trả lời thông qua câu trả lời dài như vậy bởi Mike Bostock nên được đưa vào Câu hỏi thường gặp – paxRoman