source: Dev/trunk/d3/examples/splom/splom.js @ 76

Last change on this file since 76 was 76, checked in by fpvanagthoven, 14 years ago

d3

File size: 4.2 KB
Line 
1d3.json("flowers.json", function(flower) {
2
3  // Size parameters.
4  var size = 150,
5      padding = 20;
6
7  // Color scale.
8  var color = d3.scale.ordinal().range([
9    "rgb(50%, 0%, 0%)",
10    "rgb(0%, 50%, 0%)",
11    "rgb(0%, 0%, 50%)"
12  ]);
13
14  // Position scales.
15  var position = {};
16  flower.traits.forEach(function(trait) {
17    function value(d) { return d[trait]; }
18    position[trait] = d3.scale.linear()
19        .domain([d3.min(flower.values, value), d3.max(flower.values, value)])
20        .range([padding / 2, size - padding / 2]);
21  });
22
23  // Root panel.
24  var svg = d3.select("#chart")
25    .append("svg:svg")
26      .attr("width", size * flower.traits.length)
27      .attr("height", size * flower.traits.length);
28
29  // One column per trait.
30  var column = svg.selectAll("g")
31      .data(flower.traits)
32    .enter().append("svg:g")
33      .attr("transform", function(d, i) { return "translate(" + i * size + ",0)"; });
34
35  // One row per trait.
36  var row = column.selectAll("g")
37      .data(cross(flower.traits))
38    .enter().append("svg:g")
39      .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; });
40
41  // X-ticks. TODO Cross the trait into the tick data?
42  row.selectAll("line.x")
43      .data(function(d) { return position[d.x].ticks(5).map(position[d.x]); })
44    .enter().append("svg:line")
45      .attr("class", "x")
46      .attr("x1", function(d) { return d; })
47      .attr("x2", function(d) { return d; })
48      .attr("y1", padding / 2)
49      .attr("y2", size - padding / 2);
50
51  // Y-ticks. TODO Cross the trait into the tick data?
52  row.selectAll("line.y")
53      .data(function(d) { return position[d.y].ticks(5).map(position[d.y]); })
54    .enter().append("svg:line")
55      .attr("class", "y")
56      .attr("x1", padding / 2)
57      .attr("x2", size - padding / 2)
58      .attr("y1", function(d) { return d; })
59      .attr("y2", function(d) { return d; });
60
61  // Frame.
62  row.append("svg:rect")
63      .attr("x", padding / 2)
64      .attr("y", padding / 2)
65      .attr("width", size - padding)
66      .attr("height", size - padding)
67      .style("fill", "none")
68      .style("stroke", "#aaa")
69      .style("stroke-width", 1.5)
70      .attr("pointer-events", "all")
71      .on("mousedown", mousedown);
72
73  // Dot plot.
74  var dot = row.selectAll("circle")
75      .data(cross(flower.values))
76    .enter().append("svg:circle")
77      .attr("cx", function(d) { return position[d.x.x](d.y[d.x.x]); })
78      .attr("cy", function(d) { return size - position[d.x.y](d.y[d.x.y]); })
79      .attr("r", 3)
80      .style("fill", function(d) { return color(d.y.species); })
81      .style("fill-opacity", .5)
82      .attr("pointer-events", "none");
83
84  d3.select(window)
85      .on("mousemove", mousemove)
86      .on("mouseup", mouseup);
87
88  var rect, x0, x1, count;
89
90  function mousedown() {
91    x0 = d3.svg.mouse(this);
92    count = 0;
93
94    rect = d3.select(this.parentNode)
95      .append("svg:rect")
96        .style("fill", "#999")
97        .style("fill-opacity", .5);
98
99    d3.event.preventDefault();
100  }
101
102  function mousemove() {
103    if (!rect) return;
104    x1 = d3.svg.mouse(rect.node());
105
106    x1[0] = Math.max(padding / 2, Math.min(size - padding / 2, x1[0]));
107    x1[1] = Math.max(padding / 2, Math.min(size - padding / 2, x1[1]));
108
109    var minx = Math.min(x0[0], x1[0]),
110        maxx = Math.max(x0[0], x1[0]),
111        miny = Math.min(x0[1], x1[1]),
112        maxy = Math.max(x0[1], x1[1]);
113
114    rect
115        .attr("x", minx - .5)
116        .attr("y", miny - .5)
117        .attr("width", maxx - minx + 1)
118        .attr("height", maxy - miny + 1);
119
120    var v = rect.node().__data__,
121        x = position[v.x],
122        y = position[v.y],
123        mins = x.invert(minx),
124        maxs = x.invert(maxx),
125        mint = y.invert(size - maxy),
126        maxt = y.invert(size - miny);
127
128    count = 0;
129    svg.selectAll("circle")
130        .style("fill", function(d) {
131          return mins <= d.y[v.x] && maxs >= d.y[v.x]
132              && mint <= d.y[v.y] && maxt >= d.y[v.y]
133              ? (count++, color(d.y.species))
134              : "#ccc";
135        });
136  }
137
138  function mouseup() {
139    if (!rect) return;
140    rect.remove();
141    rect = null;
142
143    if (!count) svg.selectAll("circle")
144        .style("fill", function(d) {
145          return color(d.y.species);
146        });
147  }
148
149});
Note: See TracBrowser for help on using the repository browser.