1 | <!DOCTYPE html> |
---|
2 | <html> |
---|
3 | <meta charset="utf-8"> |
---|
4 | |
---|
5 | <!-- Example based on http://bl.ocks.org/mbostock/3887118 --> |
---|
6 | <!-- Tooltip example from http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html --> |
---|
7 | <!-- Coding style based on http://gist.github.com/mbostock/5977197 --> |
---|
8 | |
---|
9 | <style> |
---|
10 | body { |
---|
11 | font: 11px sans-serif; |
---|
12 | } |
---|
13 | |
---|
14 | .axis path, |
---|
15 | .axis line { |
---|
16 | fill: none; |
---|
17 | stroke: #000; |
---|
18 | shape-rendering: crispEdges; |
---|
19 | } |
---|
20 | |
---|
21 | .dot { |
---|
22 | stroke: #000; |
---|
23 | } |
---|
24 | |
---|
25 | .tooltip { |
---|
26 | position: absolute; |
---|
27 | width: 200px; |
---|
28 | height: 28px; |
---|
29 | pointer-events: none; |
---|
30 | } |
---|
31 | </style> |
---|
32 | <body> |
---|
33 | <script src="https://d3js.org/d3.v3.min.js"></script> |
---|
34 | |
---|
35 | <!-- Add 2 buttons --> |
---|
36 | <button onclick="update_x_axis(data, 'ncpus')">Years/Day vs nCPUs</button> |
---|
37 | <button onclick="update_x_axis(data, 'CostPerYear')">Years/Day vs Cost/Year</button> |
---|
38 | |
---|
39 | <script> |
---|
40 | |
---|
41 | function update_x_axis(d, key){ |
---|
42 | for (var i = 0; i < d.length; i++){ |
---|
43 | d[i].x_value = d[i][key]; |
---|
44 | // console.log(d[i]['x_value']); |
---|
45 | } |
---|
46 | |
---|
47 | refresh_graph(key); |
---|
48 | } |
---|
49 | |
---|
50 | |
---|
51 | var base_width = 768; |
---|
52 | |
---|
53 | |
---|
54 | |
---|
55 | var base_height = 280; |
---|
56 | |
---|
57 | |
---|
58 | |
---|
59 | var margin = {top: 20, right: 20, bottom: 30, left: 40}, |
---|
60 | width = base_width - margin.left - margin.right, |
---|
61 | height = base_height - margin.top - margin.bottom; |
---|
62 | /* |
---|
63 | * value accessor - returns the value to encode for a given data object. |
---|
64 | * scale - maps value to a visual display encoding, such as a pixel position. |
---|
65 | * map function - maps from data value to display value |
---|
66 | * axis - sets up axis |
---|
67 | */ |
---|
68 | |
---|
69 | |
---|
70 | // setup x |
---|
71 | var xValue = function(d) { return d.x_value;}, // data -> value |
---|
72 | xScale = d3.scale.linear().range([0, width]), // value -> display |
---|
73 | xMap = function(d) { return xScale(xValue(d));}, // data -> display |
---|
74 | xAxis = d3.svg.axis().scale(xScale).orient("bottom"); |
---|
75 | |
---|
76 | // setup y |
---|
77 | var yValue = function(d) { return d.YearsPerDay;}, // data -> value |
---|
78 | yScale = d3.scale.linear().range([height, 0]), // value -> display |
---|
79 | yMap = function(d) { return yScale(yValue(d));}, // data -> display |
---|
80 | yAxis = d3.svg.axis().scale(yScale).orient("left"); |
---|
81 | |
---|
82 | // setup fill color |
---|
83 | var cValue = function(d) { return d.nOMP;}, |
---|
84 | color = d3.scale.category10(); |
---|
85 | |
---|
86 | |
---|
87 | // add the graph canvas to the body of the webpage |
---|
88 | var svg = d3.select("body").append("svg") |
---|
89 | .attr("width", width + margin.left + margin.right) |
---|
90 | .attr("height", height + margin.top + margin.bottom) |
---|
91 | .append("g") |
---|
92 | .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
---|
93 | |
---|
94 | |
---|
95 | // add the tooltip area to the webpage |
---|
96 | var tooltip = d3.select("body").append("div") |
---|
97 | .attr("class", "tooltip") |
---|
98 | .style("opacity", 0); |
---|
99 | |
---|
100 | var data = [{"EW": 24, "NS": 21, "nOMP": 2, "walltime": 7176.0, "ncpus": 1008, "YearsPerDay": 3.0100334448160537, "CostPerYear": 120.5568}, {"EW": 30, "NS": 28, "nOMP": 1, "walltime": 9100.0, "ncpus": 840, "YearsPerDay": 2.3736263736263736, "CostPerYear": 127.39999999999999}, {"EW": 24, "NS": 25, "nOMP": 2, "walltime": 6985.0, "ncpus": 1200, "YearsPerDay": 3.0923407301360055, "CostPerYear": 139.7}, {"EW": 26, "NS": 18, "nOMP": 1, "walltime": 11375.0, "ncpus": 480, "YearsPerDay": 1.898901098901099, "CostPerYear": 91.0}, {"EW": 26, "NS": 24, "nOMP": 2, "walltime": 6833.0, "ncpus": 1248, "YearsPerDay": 3.161129811210303, "CostPerYear": 142.1264}, {"EW": 36, "NS": 28, "nOMP": 1, "walltime": 8064.0, "ncpus": 1008, "YearsPerDay": 2.6785714285714284, "CostPerYear": 135.4752}, {"EW": 14, "NS": 18, "nOMP": 2, "walltime": 11729.0, "ncpus": 504, "YearsPerDay": 1.8415892232926934, "CostPerYear": 98.52359999999999}, {"EW": 18, "NS": 20, "nOMP": 2, "walltime": 9468.0, "ncpus": 720, "YearsPerDay": 2.2813688212927756, "CostPerYear": 113.61599999999999}, {"EW": 24, "NS": 21, "nOMP": 2, "walltime": 6546.0, "ncpus": 1008, "YearsPerDay": 3.2997250229147568, "CostPerYear": 109.97279999999999}, {"EW": 26, "NS": 24, "nOMP": 1, "walltime": 9334.0, "ncpus": 624, "YearsPerDay": 2.3141204199700023, "CostPerYear": 97.07359999999998}, {"EW": 18, "NS": 20, "nOMP": 2, "walltime": 9792.0, "ncpus": 720, "YearsPerDay": 2.2058823529411766, "CostPerYear": 117.50399999999999}, {"EW": 14, "NS": 18, "nOMP": 2, "walltime": 11814.0, "ncpus": 504, "YearsPerDay": 1.8283392585068563, "CostPerYear": 99.2376}]; |
---|
101 | var graph_labels = { |
---|
102 | "x_axis" : { |
---|
103 | "ncpus" : "CPUs", |
---|
104 | "CostPerYear": "kAU per Model Year" |
---|
105 | }, |
---|
106 | "y_axis" : "Model Years Per Day" |
---|
107 | } |
---|
108 | |
---|
109 | function refresh_graph(label_code){ |
---|
110 | |
---|
111 | // don't want dots overlapping axis, so add in buffer to data domain |
---|
112 | xScale.domain([d3.min(data, xValue)-1, d3.max(data, xValue)+1]); |
---|
113 | yScale.domain([d3.min(data, yValue)-1, d3.max(data, yValue)+1]); |
---|
114 | |
---|
115 | // x-axis (remove (both???) axes first?? |
---|
116 | d3.select("svg").selectAll(".axis").remove(); |
---|
117 | svg.append("g") |
---|
118 | .attr("class", "x axis") |
---|
119 | .attr("transform", "translate(0," + height + ")") |
---|
120 | .call(xAxis) |
---|
121 | .append("text") |
---|
122 | .attr("class", "label") |
---|
123 | .attr("x", width) |
---|
124 | .attr("y", -6) |
---|
125 | .style("text-anchor", "end") |
---|
126 | .text(graph_labels["x_axis"][label_code]); |
---|
127 | |
---|
128 | // y-axis |
---|
129 | svg.append("g") |
---|
130 | .attr("class", "y axis") |
---|
131 | .call(yAxis) |
---|
132 | .append("text") |
---|
133 | .attr("class", "label") |
---|
134 | .attr("transform", "rotate(-90)") |
---|
135 | .attr("y", 6) |
---|
136 | .attr("dy", ".71em") |
---|
137 | .style("text-anchor", "end") |
---|
138 | .text(graph_labels["y_axis"]); |
---|
139 | // draw dots |
---|
140 | d3.select("svg").selectAll(".dot").remove(); |
---|
141 | svg.selectAll(".dot") |
---|
142 | .data(data) |
---|
143 | .enter().append("circle") |
---|
144 | .attr("class", "dot") |
---|
145 | .attr("r", 3.5) |
---|
146 | .attr("cx", xMap) |
---|
147 | .attr("cy", yMap) |
---|
148 | .style("fill", function(d) { return color(cValue(d));}) |
---|
149 | .on("mouseover", function(d) { |
---|
150 | tooltip.transition() |
---|
151 | .duration(200) |
---|
152 | .style("opacity", .9); |
---|
153 | tooltip.html("nOMP = " + d.nOMP + "<br/> (NS, EW) = (" + d.NS |
---|
154 | + ", " + d.EW + ")") |
---|
155 | .style("left", (d3.event.pageX + 5) + "px") |
---|
156 | .style("top", (d3.event.pageY - 28) + "px"); |
---|
157 | }) |
---|
158 | .on("mouseout", function(d) { |
---|
159 | tooltip.transition() |
---|
160 | .duration(500) |
---|
161 | .style("opacity", 0); |
---|
162 | }); |
---|
163 | |
---|
164 | // draw legend |
---|
165 | var legend = svg.selectAll(".legend") |
---|
166 | .data(color.domain()) |
---|
167 | .enter().append("g") |
---|
168 | .attr("class", "legend") |
---|
169 | .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); |
---|
170 | |
---|
171 | // draw legend colored rectangles |
---|
172 | legend.append("rect") |
---|
173 | .attr("x", width - 18) |
---|
174 | .attr("width", 18) |
---|
175 | .attr("height", 18) |
---|
176 | .style("fill", color); |
---|
177 | |
---|
178 | // draw legend text |
---|
179 | legend.append("text") |
---|
180 | .attr("x", width - 24) |
---|
181 | .attr("y", 9) |
---|
182 | .attr("dy", ".35em") |
---|
183 | .style("text-anchor", "end") |
---|
184 | .text(function(d) { return d;}); |
---|
185 | //}); |
---|
186 | }; |
---|
187 | // initially choose ncpus |
---|
188 | update_x_axis(data, 'ncpus') |
---|
189 | |
---|
190 | </script> |
---|
191 | </body> |
---|
192 | </html> |
---|