Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: Source/devtools/front_end/profiler/d3js_trace/sequences.js

Issue 887673002: DevTools: CPU profiler sunburst view (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/devtools/front_end/profiler/d3js_trace/sequences.css ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 function sequences(root) {
2
3 // Dimensions of sunburst.
4 var width = 1600;
5 var height = 800;
6 var radius = Math.min(width, height) / 2;
7
8 var x = d3.scale.linear()
9 .range([0, 2 * Math.PI]);
10
11 var y = d3.scale.sqrt()
12 .range([0, radius]);
13
14 // Breadcrumb dimensions: width, height, spacing, width of tip/tail.
15 var b = {
16 w: 75, h: 30, s: 3, t: 10
17 };
18
19 var path ={};
20 var nodes = {};
21
22 // Mapping of step names to colors.
23 var colors = {
24 "home": "#5687d1",
25 "product": "#7b615c",
26 "search": "#de783b",
27 "account": "#6ab975",
28 "other": "#a173d1",
29 "end": "#bbbbbb"
30 };
31
32 // Total size of all segments; we set this later, after loading the data.
33 var totalSize = 0;
34
35 var svg = d3.select("#chart").append("svg:svg")
36 .attr("width", width)
37 .attr("height", height)
38 .append("svg:g")
39 .attr("id", "container")
40 .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
41
42 var partition = d3.layout.partition()
43 .size([2 * Math.PI, radius * radius])
44 .value(function(d) { return d.size; });
45
46 var arc = d3.svg.arc()
47 .startAngle(function(d) { return d.x; })
48 .endAngle(function(d) { return d.x + d.dx; })
49 .innerRadius(function(d) { return Math.sqrt(d.y); })
50 .outerRadius(function(d) { return Math.sqrt(d.y + d.dy); });
51
52 initializePage();
53 createVisualization(root);
54
55 function initializePage() {
56
57 // Basic setup of page elements.
58 initializeBreadcrumbTrail();
59 drawLegend();
60 d3.select("#togglelegend").on("click", toggleLegend);
61
62 // Bounding circle underneath the sunburst, to make it easier to detect
63 // when the mouse leaves the parent g.
64 svg.append("svg:circle")
65 .attr("r", radius)
66 .style("opacity", 0);
67 }
68
69 // Main function to draw and set up the visualization, once we have the data.
70 function createVisualization(json) {
71
72 // For efficiency, filter nodes to keep only those large enough to see.
73 nodes = partition.nodes(root)
74 .filter(function(d) {
75 return (d.dx > 0.005); // 0.005 radians = 0.29 degrees
76 });
77
78 //var path = svg.data([json]).selectAll("path")
79 path = svg.selectAll("path")
80 .data(nodes)
81 .enter().append("svg:path")
82 .attr("display", function(d) { return d.depth ? null : "none"; })
83 .attr("d", arc)
84 .attr("fill-rule", "evenodd")
85 .style("fill", function(d) { return colors[d.name]; })
86 .style("opacity", 1)
87 .on("mouseover", mouseover)
88 .on("click", click);
89
90 // Add the mouseleave handler to the bounding circle.
91 d3.select("#container").on("mouseleave", mouseleave);
92
93 // Get total size of the tree = value of root node from partition.
94 totalSize = path.node().__data__.value;
95 };
96
97 function click(d) {
98
99 console.log(d);
100 }
101
102 // Fade all but the current sequence, and show it in the breadcrumb trail.
103 function mouseover(d) {
104
105 var percentage = (100 * d.value / totalSize).toPrecision(3);
106 var percentageString = percentage + "%";
107 if (percentage < 0.1) {
108 percentageString = "< 0.1%";
109 }
110
111 d3.select("#percentage")
112 .text(percentageString);
113
114 d3.select("#funcname")
115 .text(d.name);
116
117 d3.select("#explanation")
118 .style("visibility", "");
119
120 var sequenceArray = getAncestors(d);
121 updateBreadcrumbs(sequenceArray, percentageString);
122
123 // Fade all the segments.
124 d3.selectAll("path")
125 .style("opacity", 0.3);
126
127 // Then highlight only those that are an ancestor of the current segment.
128 svg.selectAll("path")
129 .filter(function(node) {
130 return (sequenceArray.indexOf(node) >= 0);
131 })
132 .style("opacity", 1);
133 }
134
135 // Restore everything to full opacity when moving off the visualization.
136 function mouseleave(d) {
137
138 // Hide the breadcrumb trail
139 d3.select("#trail")
140 .style("visibility", "hidden");
141
142 // Deactivate all segments during transition.
143 d3.selectAll("path").on("mouseover", null);
144
145 // Transition each segment to full opacity and then reactivate it.
146 d3.selectAll("path")
147 .transition()
148 .duration(1000)
149 .style("opacity", 1)
150 .each("end", function() {
151 d3.select(this).on("mouseover", mouseover);
152 });
153
154 d3.select("#explanation")
155 .transition()
156 .duration(1000)
157 .style("visibility", "hidden");
158 }
159
160 // Given a node in a partition layout, return an array of all of its ancestor
161 // nodes, highest first, but excluding the root.
162 function getAncestors(node) {
163 var path = [];
164 var current = node;
165 while (current.parent) {
166 path.unshift(current);
167 current = current.parent;
168 }
169 return path;
170 }
171
172 function initializeBreadcrumbTrail() {
173 // Add the svg area.
174 var trail = d3.select("#sequence").append("svg:svg")
175 .attr("width", width)
176 .attr("height", 50)
177 .attr("id", "trail");
178 // Add the label at the end, for the percentage.
179 trail.append("svg:text")
180 .attr("id", "endlabel")
181 .style("fill", "#000");
182 }
183
184 // Generate a string that describes the points of a breadcrumb polygon.
185 function breadcrumbPoints(d, i) {
186 var points = [];
187 points.push("0,0");
188 points.push(b.w + ",0");
189 points.push(b.w + b.t + "," + (b.h / 2));
190 points.push(b.w + "," + b.h);
191 points.push("0," + b.h);
192 if (i > 0) { // Leftmost breadcrumb; don't include 6th vertex.
193 points.push(b.t + "," + (b.h / 2));
194 }
195 return points.join(" ");
196 }
197
198 // Update the breadcrumb trail to show the current sequence and percentage.
199 function updateBreadcrumbs(nodeArray, percentageString) {
200
201 // Data join; key function combines name and depth (= position in sequence).
202 var g = d3.select("#trail")
203 .selectAll("g")
204 .data(nodeArray, function(d) { return d.name + d.depth; });
205
206 // Add breadcrumb and label for entering nodes.
207 var entering = g.enter().append("svg:g");
208
209 entering.append("svg:polygon")
210 .attr("points", breadcrumbPoints)
211 .style("fill", function(d) { return colors[d.name]; });
212
213 entering.append("svg:text")
214 .attr("x", (b.w + b.t) / 2)
215 .attr("y", b.h / 2)
216 .attr("dy", "0.35em")
217 .attr("text-anchor", "middle")
218 .text(function(d) {
219 var str = d.name;
220 if (str.length > 10) {
221 str = str.substr(0, 8) + "...";
222 }
223 return str;
224 });
225
226 // Set position for entering and updating nodes.
227 g.attr("transform", function(d, i) {
228 return "translate(" + i * (b.w + b.s) + ", 0)";
229 });
230
231 // Remove exiting nodes.
232 g.exit().remove();
233
234 // Now move and update the percentage at the end.
235 d3.select("#trail").select("#endlabel")
236 .attr("x", (nodeArray.length + 0.5) * (b.w + b.s))
237 .attr("y", b.h / 2)
238 .attr("dy", "0.35em")
239 .attr("text-anchor", "middle")
240 .text(percentageString);
241
242 // Make the breadcrumb trail visible, if it's hidden.
243 d3.select("#trail")
244 .style("visibility", "");
245
246 }
247
248 function drawLegend() {
249
250 // Dimensions of legend item: width, height, spacing, radius of rounded rect.
251 var li = {
252 w: 75, h: 30, s: 3, r: 3
253 };
254
255 var legend = d3.select("#legend").append("svg:svg")
256 .attr("width", li.w)
257 .attr("height", d3.keys(colors).length * (li.h + li.s));
258
259 var g = legend.selectAll("g")
260 .data(d3.entries(colors))
261 .enter().append("svg:g")
262 .attr("transform", function(d, i) {
263 return "translate(0," + i * (li.h + li.s) + ")";
264 });
265
266 g.append("svg:rect")
267 .attr("rx", li.r)
268 .attr("ry", li.r)
269 .attr("width", li.w)
270 .attr("height", li.h)
271 .style("fill", function(d) { return d.value; });
272
273 g.append("svg:text")
274 .attr("x", li.w / 2)
275 .attr("y", li.h / 2)
276 .attr("dy", "0.35em")
277 .attr("text-anchor", "middle")
278 .text(function(d) { return d.key; });
279 }
280
281 function toggleLegend() {
282 var legend = d3.select("#legend");
283 if (legend.style("visibility") == "hidden") {
284 legend.style("visibility", "");
285 } else {
286 legend.style("visibility", "hidden");
287 }
288 }
289
290 }
291
292 window.addEventListener("message", function(event) {
293 var data = {
294 name: "Foo",
295 size: 20,
296 children: [
297 {
298 name: "Bar1",
299 children: [
300 {
301 name: "Bar11",
302 size: 5,
303 children: []
304 },
305 {
306 name: "Bar12",
307 size: 5,
308 children: []
309 }
310 ]
311 },
312 {
313 name: "Bar2",
314 children: [
315 {
316 name: "Bar21",
317 size: 1,
318 children: []
319 },
320 {
321 name: "Bar22",
322 size: 2,
323 children: []
324 }
325 ]
326 }
327 ]
328 }
329 // sequences(data);
330 sequences(event.data);
331 })
OLDNEW
« no previous file with comments | « Source/devtools/front_end/profiler/d3js_trace/sequences.css ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698