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

Side by Side Diff: packages/charted/lib/layout/src/treemap_layout.dart

Issue 1521693002: Roll Observatory deps (charted -> ^0.3.0) (Closed) Base URL: https://chromium.googlesource.com/external/github.com/dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. All rights reserved. 2 * Copyright 2015 Google Inc. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style 4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at 5 * license that can be found in the LICENSE file or at
6 * https://developers.google.com/open-source/licenses/bsd 6 * https://developers.google.com/open-source/licenses/bsd
7 */ 7 */
8 part of charted.layout; 8 part of charted.layout;
9 9
10 /// PaddingFunction takes a node and generates the padding for the particular 10 /// PaddingFunction takes a node and generates the padding for the particular
11 /// node 11 /// node
12 typedef List PaddingFunction(TreeMapNode node); 12 typedef List PaddingFunction(TreeMapNode node);
13 13
14 /** 14 /**
15 * Utility layout class which recursively subdivides area into rectangles which 15 * Utility layout class which recursively subdivides area into rectangles which
16 * can be used to quickly visualize the size of any node in the tree. 16 * can be used to quickly visualize the size of any node in the tree.
17 */ 17 */
18 class TreeMapLayout extends HierarchyLayout { 18 class TreeMapLayout extends HierarchyLayout {
19 /// Rectangular subdivision; squareness controlled via the target ratio. 19 /// Rectangular subdivision; squareness controlled via the target ratio.
20 static const TREEMAP_LAYOUT_SQUARIFY = 0; 20 static const TREEMAP_LAYOUT_SQUARIFY = 0;
21 21
22 /// Horizontal subdivision. 22 /// Horizontal subdivision.
23 static const TREEMAP_LAYOUT_SLICE= 1; 23 static const TREEMAP_LAYOUT_SLICE = 1;
24 24
25 /// Vertical subdivision. 25 /// Vertical subdivision.
26 static const TREEMAP_LAYOUT_DICE = 2; 26 static const TREEMAP_LAYOUT_DICE = 2;
27 27
28 /// Alternating between horizontal and vertical subdivision. 28 /// Alternating between horizontal and vertical subdivision.
29 static const TREEMAP_LAYOUT_SLICE_DICE = 3; 29 static const TREEMAP_LAYOUT_SLICE_DICE = 3;
30 30
31 static const _DEFAULT_PADDING = const [0, 0, 0, 0]; 31 static const _DEFAULT_PADDING = const [0, 0, 0, 0];
32 32
33 /// A sticky treemap layout will preserve the relative arrangement of nodes 33 /// A sticky treemap layout will preserve the relative arrangement of nodes
34 /// across transitions. (not yet implemented) 34 /// across transitions. (not yet implemented)
35 bool _sticky = false; 35 bool _sticky = false;
36 36
37 /// The available layout size to the specified two-element array of numbers 37 /// The available layout size to the specified two-element array of numbers
38 /// representing width and height. 38 /// representing width and height.
39 List size = [1, 1]; 39 List size = [1, 1];
40 40
41 /// The mode to layout the Treemap. 41 /// The mode to layout the Treemap.
42 int mode = TREEMAP_LAYOUT_SQUARIFY; 42 int mode = TREEMAP_LAYOUT_SQUARIFY;
43 43
44 /// The ration to scale the Treemap. 44 /// The ration to scale the Treemap.
45 num ratio = .5 * (1 + math.sqrt(5)); 45 num ratio = .5 * (1 + math.sqrt(5));
46 46
47 /// The paddingFunction for each node, defaults to return [0, 0, 0, 0]. 47 /// The paddingFunction for each node, defaults to return [0, 0, 0, 0].
48 PaddingFunction paddingFunction = (node) => _DEFAULT_PADDING; 48 PaddingFunction paddingFunction = (node) => _DEFAULT_PADDING;
49 49
50 /// TODO(midoringo): Implement sticky related feature. 50 /// TODO(midoringo): Implement sticky related feature.
51 get sticky => _sticky; 51 get sticky => _sticky;
52 set sticky (bool sticky) { 52 set sticky(bool sticky) {
53 _sticky = sticky; 53 _sticky = sticky;
54 } 54 }
55 55
56 // TODO (midoringo): handle the sticky case. 56 // TODO (midoringo): handle the sticky case.
57 @override 57 @override
58 List<TreeMapNode> layout(List rows, int parentColumn, int labelColumn, 58 List<TreeMapNode> layout(
59 int valueColumn) { 59 List rows, int parentColumn, int labelColumn, int valueColumn) {
60 var nodes = super.layout(rows, parentColumn, labelColumn, valueColumn); 60 var nodes = super.layout(rows, parentColumn, labelColumn, valueColumn);
61 var root = nodes[0]; 61 var root = nodes[0];
62 root.x = 0; 62 root.x = 0;
63 root.y = 0; 63 root.y = 0;
64 root.dx = size.first; 64 root.dx = size.first;
65 root.dy = size.last; 65 root.dy = size.last;
66 _scale([root], root.dx * root.dy / root.value); 66 _scale([root], root.dx * root.dy / root.value);
67 _squarify(root); 67 _squarify(root);
68 return nodes; 68 return nodes;
69 } 69 }
70 70
71 @override 71 @override
72 TreeMapNode createNode(label, value, depth) { 72 TreeMapNode createNode(label, value, depth) {
73 return new TreeMapNode() 73 return new TreeMapNode()
74 ..label = label 74 ..label = label
75 ..value = value 75 ..value = value
76 ..depth = depth; 76 ..depth = depth;
77 } 77 }
78 78
79 void _position(List<TreeMapNode> nodes, num length, MutableRect rect, 79 void _position(List<TreeMapNode> nodes, num length, MutableRect rect,
80 bool flush, num area) { 80 bool flush, num area) {
81 var x = rect.x; 81 var x = rect.x;
82 var y = rect.y; 82 var y = rect.y;
83 var v = length > 0 ? (area / length).round() : 0; 83 var v = length > 0 ? (area / length).round() : 0;
84 if (length == rect.width) { 84 if (length == rect.width) {
85 if (flush || (v > rect.height)) v = rect.height; 85 if (flush || (v > rect.height)) v = rect.height;
86 for (var node in nodes) { 86 for (var node in nodes) {
87 node.x = x; 87 node.x = x;
88 node.y = y; 88 node.y = y;
89 node.dy = v; 89 node.dy = v;
90 x += node.dx = math.min(rect.x + rect.width - x, v > 0 ? 90 x += node.dx = math.min(
91 (node.area / v).round() : 0); 91 rect.x + rect.width - x, v > 0 ? (node.area / v).round() : 0);
92 } 92 }
93 nodes.last.sticky = true; 93 nodes.last.sticky = true;
94 nodes.last.dx += rect.x + rect.width - x; 94 nodes.last.dx += rect.x + rect.width - x;
95 rect.y += v; 95 rect.y += v;
96 rect.height -= v; 96 rect.height -= v;
97 } else { 97 } else {
98 if (flush || (v > rect.width)) v = rect.width; 98 if (flush || (v > rect.width)) v = rect.width;
99 for (var node in nodes) { 99 for (var node in nodes) {
100 node.x = x; 100 node.x = x;
101 node.y = y; 101 node.y = y;
102 node.dx = v; 102 node.dx = v;
103 y += node.dy = math.min(rect.y + rect.height - y, v > 0 ? 103 y += node.dy = math.min(
104 (node.area / v).round() : 0); 104 rect.y + rect.height - y, v > 0 ? (node.area / v).round() : 0);
105 } 105 }
106 nodes.last.sticky = false; 106 nodes.last.sticky = false;
107 nodes.last.dy += rect.y + rect.height - y; 107 nodes.last.dy += rect.y + rect.height - y;
108 rect.x += v; 108 rect.x += v;
109 rect.width -= v; 109 rect.width -= v;
110 } 110 }
111 } 111 }
112 112
113 /// Applies padding between each nodes. 113 /// Applies padding between each nodes.
114 MutableRect _treeMapPad(TreeMapNode node, padding) { 114 MutableRect _treeMapPad(TreeMapNode node, padding) {
(...skipping 27 matching lines...) Expand all
142 var rmax = 0; 142 var rmax = 0;
143 var rmin = double.INFINITY; 143 var rmin = double.INFINITY;
144 for (var node in nodes) { 144 for (var node in nodes) {
145 area = node.area; 145 area = node.area;
146 if (area <= 0) continue; 146 if (area <= 0) continue;
147 if (area < rmin) rmin = area; 147 if (area < rmin) rmin = area;
148 if (area > rmax) rmax = area; 148 if (area > rmax) rmax = area;
149 } 149 }
150 pArea *= pArea; 150 pArea *= pArea;
151 length *= length; 151 length *= length;
152 return (pArea > 0) ? math.max(length * rmax * ratio / pArea, 152 return (pArea > 0)
153 pArea / (length * rmin * ratio)) : double.INFINITY; 153 ? math.max(
154 length * rmax * ratio / pArea, pArea / (length * rmin * ratio))
155 : double.INFINITY;
154 } 156 }
155 157
156 /// Recursively compute each nodes (and its children nodes) position and size 158 /// Recursively compute each nodes (and its children nodes) position and size
157 /// base on the node's property and layout mode. 159 /// base on the node's property and layout mode.
158 void _squarify(TreeMapNode node) { 160 void _squarify(TreeMapNode node) {
159 var children = node.children; 161 var children = node.children;
160 if (children.isNotEmpty) { 162 if (children.isNotEmpty) {
161 var rect = _treeMapPad(node, paddingFunction(node)); 163 var rect = _treeMapPad(node, paddingFunction(node));
162 List<TreeMapNode> nodes = []; 164 List<TreeMapNode> nodes = [];
163 var area = 0; 165 var area = 0;
164 var remaining = new List.from(children); 166 var remaining = new List.from(children);
165 var score, n, 167 var score,
166 best = double.INFINITY, 168 n,
167 length = (mode == TREEMAP_LAYOUT_SLICE) ? rect.width : 169 best = double.INFINITY,
168 (mode == TREEMAP_LAYOUT_DICE) ? rect.height : 170 length = (mode == TREEMAP_LAYOUT_SLICE)
169 (mode == TREEMAP_LAYOUT_SLICE_DICE) ? (node.depth & 1 == 1) ? 171 ? rect.width
170 rect.height : rect.width : math.min(rect.width, rect.height); 172 : (mode == TREEMAP_LAYOUT_DICE)
173 ? rect.height
174 : (mode == TREEMAP_LAYOUT_SLICE_DICE)
175 ? (node.depth & 1 == 1) ? rect.height : rect.width
176 : math.min(rect.width, rect.height);
171 _scale(remaining, rect.width * rect.height / node.value); 177 _scale(remaining, rect.width * rect.height / node.value);
172 while ((n = remaining.length) > 0) { 178 while ((n = remaining.length) > 0) {
173 var child = remaining[n - 1]; 179 var child = remaining[n - 1];
174 nodes.add(child); 180 nodes.add(child);
175 area += child.area; 181 area += child.area;
176 score = _worst(nodes, length, area); 182 score = _worst(nodes, length, area);
177 if (mode != TREEMAP_LAYOUT_SQUARIFY || score <= best) { 183 if (mode != TREEMAP_LAYOUT_SQUARIFY || score <= best) {
178 remaining.removeLast(); 184 remaining.removeLast();
179 best = score; 185 best = score;
180 } else { 186 } else {
(...skipping 27 matching lines...) Expand all
208 214
209 /// The y-extent of the node position. 215 /// The y-extent of the node position.
210 num dy = 0; 216 num dy = 0;
211 217
212 /// The area the node should take up. 218 /// The area the node should take up.
213 num area = 0; 219 num area = 0;
214 220
215 /// Attribute for the last node in the row, only used for sticky layout. 221 /// Attribute for the last node in the row, only used for sticky layout.
216 bool sticky = false; 222 bool sticky = false;
217 } 223 }
OLDNEW
« no previous file with comments | « packages/charted/lib/layout/src/pie_layout.dart ('k') | packages/charted/lib/locale/format.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698