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

Side by Side Diff: packages/charted/lib/selection/src/selection_impl.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 2014 Google Inc. All rights reserved. 2 * Copyright 2014 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.selection; 8 part of charted.selection;
9 9
10 /** 10 /**
11 * Implementation of [Selection]. 11 * Implementation of [Selection].
12 * Selections cannot be created directly - they are only created using 12 * Selections cannot be created directly - they are only created using
13 * the select or selectAll methods on [SelectionScope] and [Selection]. 13 * the select or selectAll methods on [SelectionScope] and [Selection].
14 */ 14 */
15 class _SelectionImpl implements Selection { 15 class _SelectionImpl implements Selection {
16
17 Iterable<SelectionGroup> groups; 16 Iterable<SelectionGroup> groups;
18 SelectionScope scope; 17 SelectionScope scope;
19 18
20 /** 19 /**
21 * Creates a new selection. 20 * Creates a new selection.
22 * 21 *
23 * When [source] is not specified, the new selection would have exactly 22 * When [source] is not specified, the new selection would have exactly
24 * one group with [SelectionScope.root] as it's parent. Otherwise, one group 23 * one group with [SelectionScope.root] as it's parent. Otherwise, one group
25 * per for each non-null element is created with element as it's parent. 24 * per for each non-null element is created with element as it's parent.
26 * 25 *
27 * When [selector] is specified, each group contains all elements matching 26 * When [selector] is specified, each group contains all elements matching
28 * [selector] and under the group's parent element. Otherwise, [fn] is 27 * [selector] and under the group's parent element. Otherwise, [fn] is
29 * called once per group with parent element's "data", "index" and the 28 * called once per group with parent element's "data", "index" and the
30 * "element" itself passed as parameters. [fn] must return an iterable of 29 * "element" itself passed as parameters. [fn] must return an iterable of
31 * elements to be used in each group. 30 * elements to be used in each group.
32 */ 31 */
33 _SelectionImpl.all({String selector, SelectionCallback<Iterable<Element>> fn, 32 _SelectionImpl.all(
34 SelectionScope this.scope, Selection source}) { 33 {String selector,
34 SelectionCallback<Iterable<Element>> fn,
35 SelectionScope this.scope,
36 Selection source}) {
35 assert(selector != null || fn != null); 37 assert(selector != null || fn != null);
36 assert(source != null || scope != null); 38 assert(source != null || scope != null);
37 39
38 if (selector != null) { 40 if (selector != null) {
39 fn = (d, i, c) => c == null ? 41 fn = (d, i, c) => c == null
40 scope.root.querySelectorAll(selector) : 42 ? scope.root.querySelectorAll(selector)
41 c.querySelectorAll(selector); 43 : c.querySelectorAll(selector);
42 } 44 }
43 45
44 var tmpGroups = new List<SelectionGroup>(); 46 var tmpGroups = new List<SelectionGroup>();
45 if (source != null) { 47 if (source != null) {
46 scope = source.scope; 48 scope = source.scope;
47 for (int gi = 0; gi < source.groups.length; ++gi) { 49 for (int gi = 0; gi < source.groups.length; ++gi) {
48 final g = source.groups.elementAt(gi); 50 final g = source.groups.elementAt(gi);
49 for (int ei = 0; ei < g.elements.length; ++ei) { 51 for (int ei = 0; ei < g.elements.length; ++ei) {
50 final e = g.elements.elementAt(ei); 52 final e = g.elements.elementAt(ei);
51 if (e != null) { 53 if (e != null) {
52 tmpGroups.add( 54 tmpGroups.add(
53 new _SelectionGroupImpl( 55 new _SelectionGroupImpl(fn(scope.datum(e), gi, e), parent: e));
54 fn(scope.datum(e), gi, e), parent: e));
55 } 56 }
56 } 57 }
57 } 58 }
58 } else { 59 } else {
59 tmpGroups.add( 60 tmpGroups
60 new _SelectionGroupImpl(fn(null, 0, null), parent: scope.root)); 61 .add(new _SelectionGroupImpl(fn(null, 0, null), parent: scope.root));
61 } 62 }
62 groups = tmpGroups; 63 groups = tmpGroups;
63 } 64 }
64 65
65 /** 66 /**
66 * Same as [all] but only uses the first element matching [selector] when 67 * Same as [all] but only uses the first element matching [selector] when
67 * [selector] is specified. Otherwise, call [fn] which must return the 68 * [selector] is specified. Otherwise, call [fn] which must return the
68 * element to be selected. 69 * element to be selected.
69 */ 70 */
70 _SelectionImpl.single({String selector, SelectionCallback<Element> fn, 71 _SelectionImpl.single(
71 SelectionScope this.scope, Selection source}) { 72 {String selector,
73 SelectionCallback<Element> fn,
74 SelectionScope this.scope,
75 Selection source}) {
72 assert(selector != null || fn != null); 76 assert(selector != null || fn != null);
73 assert(source != null || scope != null); 77 assert(source != null || scope != null);
74 78
75 if (selector != null) { 79 if (selector != null) {
76 fn = (d, i, c) => c == null ? 80 fn = (d, i, c) => c == null
77 scope.root.querySelector(selector) : 81 ? scope.root.querySelector(selector)
78 c.querySelector(selector); 82 : c.querySelector(selector);
79 } 83 }
80 84
81 if (source != null) { 85 if (source != null) {
82 scope = source.scope; 86 scope = source.scope;
83 groups = new List<SelectionGroup>.generate(source.groups.length, (gi) { 87 groups = new List<SelectionGroup>.generate(source.groups.length, (gi) {
84 SelectionGroup g = source.groups.elementAt(gi); 88 SelectionGroup g = source.groups.elementAt(gi);
85 return new _SelectionGroupImpl( 89 return new _SelectionGroupImpl(
86 new List.generate(g.elements.length, (ei) { 90 new List.generate(g.elements.length, (ei) {
87 var e = g.elements.elementAt(ei); 91 var e = g.elements.elementAt(ei);
88 if (e != null) { 92 if (e != null) {
89 var datum = scope.datum(e); 93 var datum = scope.datum(e);
90 var enterElement = fn(datum, ei, e); 94 var enterElement = fn(datum, ei, e);
91 if (datum != null) { 95 if (datum != null) {
92 scope.associate(enterElement, datum); 96 scope.associate(enterElement, datum);
93 } 97 }
94 return enterElement; 98 return enterElement;
95 } else { 99 } else {
96 return null; 100 return null;
97 } 101 }
98 }), parent: g.parent); 102 }),
103 parent: g.parent);
99 }); 104 });
100 } else { 105 } else {
101 groups = new List<SelectionGroup>.generate(1, 106 groups = new List<SelectionGroup>.generate(
102 (_) => new _SelectionGroupImpl(new List.generate(1, 107 1,
103 (_) => fn(null, 0, null), growable: false)), growable: false); 108 (_) => new _SelectionGroupImpl(
109 new List.generate(1, (_) => fn(null, 0, null), growable: false)),
110 growable: false);
104 } 111 }
105 } 112 }
106 113
107 /** Creates a selection using the pre-computed list of [SelectionGroup] */ 114 /** Creates a selection using the pre-computed list of [SelectionGroup] */
108 _SelectionImpl.selectionGroups( 115 _SelectionImpl.selectionGroups(
109 Iterable<SelectionGroup> this.groups, SelectionScope this.scope); 116 Iterable<SelectionGroup> this.groups, SelectionScope this.scope);
110 117
111 /** 118 /**
112 * Creates a selection using the list of elements. All elements will 119 * Creates a selection using the list of elements. All elements will
113 * be part of the same group, with [SelectionScope.root] as the group's parent 120 * be part of the same group, with [SelectionScope.root] as the group's parent
114 */ 121 */
115 _SelectionImpl.elements(Iterable elements, SelectionScope this.scope) { 122 _SelectionImpl.elements(Iterable elements, SelectionScope this.scope) {
116 groups = new List<SelectionGroup>() 123 groups = new List<SelectionGroup>()..add(new _SelectionGroupImpl(elements));
117 ..add(new _SelectionGroupImpl(elements));
118 } 124 }
119 125
120 /** 126 /**
121 * Utility to evaluate value of parameters (uses value when given 127 * Utility to evaluate value of parameters (uses value when given
122 * or invokes a callback to get the value) and calls [action] for 128 * or invokes a callback to get the value) and calls [action] for
123 * each non-null element in this selection 129 * each non-null element in this selection
124 */ 130 */
125 void _do(SelectionCallback f, Function action) { 131 void _do(SelectionCallback f, Function action) {
126 each((d, i, e) => action(e, f == null ? null : f(scope.datum(e), i, e))); 132 each((d, i, e) => action(e, f == null ? null : f(scope.datum(e), i, e)));
127 } 133 }
128 134
129 /** Calls a function on each non-null element in the selection */ 135 /** Calls a function on each non-null element in the selection */
130 void each(SelectionCallback fn) { 136 void each(SelectionCallback fn) {
131 if (fn == null) return; 137 if (fn == null) return;
132 for (int gi = 0, gLen = groups.length; gi < gLen; ++gi) { 138 for (int gi = 0, gLen = groups.length; gi < gLen; ++gi) {
133 final g = groups.elementAt(gi); 139 final g = groups.elementAt(gi);
134 for (int ei = 0, eLen = g.elements.length; ei < eLen; ++ei) { 140 for (int ei = 0, eLen = g.elements.length; ei < eLen; ++ei) {
135 final e = g.elements.elementAt(ei); 141 final e = g.elements.elementAt(ei);
136 if (e != null) fn(scope.datum(e), ei, e); 142 if (e != null) fn(scope.datum(e), ei, e);
137 } 143 }
138 } 144 }
139 } 145 }
140 146
141 void on(String type, [SelectionCallback listener, bool capture]) { 147 void on(String type, [SelectionCallback listener, bool capture]) {
142 Function getEventHandler(i, e) => (Event event) { 148 Function getEventHandler(i, e) => (Event event) {
143 var previous = scope.event; 149 var previous = scope.event;
144 scope.event = event; 150 scope.event = event;
145 try { 151 try {
146 listener(scope.datum(e), i, e); 152 listener(scope.datum(e), i, e);
147 } finally { 153 } finally {
148 scope.event = previous; 154 scope.event = previous;
149 } 155 }
150 }; 156 };
151 157
152 if (!type.startsWith('.')) { 158 if (!type.startsWith('.')) {
153 if (listener != null) { 159 if (listener != null) {
154 // Add a listener to each element. 160 // Add a listener to each element.
155 each((d, i, Element e){ 161 each((d, i, Element e) {
156 var handlers = scope._listeners[e]; 162 var handlers = scope._listeners[e];
157 if (handlers == null) scope._listeners[e] = handlers = {}; 163 if (handlers == null) scope._listeners[e] = handlers = {};
158 handlers[type] = new Pair(getEventHandler(i, e), capture); 164 handlers[type] = new Pair(getEventHandler(i, e), capture);
159 e.addEventListener(type, handlers[type].first, capture); 165 e.addEventListener(type, handlers[type].first, capture);
160 }); 166 });
161 } else { 167 } else {
162 // Remove the listener from each element. 168 // Remove the listener from each element.
163 each((d, i, Element e) { 169 each((d, i, Element e) {
164 var handlers = scope._listeners[e]; 170 var handlers = scope._listeners[e];
165 if (handlers != null && handlers[type] != null) { 171 if (handlers != null && handlers[type] != null) {
166 e.removeEventListener( 172 e.removeEventListener(
167 type, handlers[type].first, handlers[type].last); 173 type, handlers[type].first, handlers[type].last);
168 } 174 }
169 }); 175 });
170 } 176 }
171 } else { 177 } else {
172 // Remove all listeners on the event type (ignoring the namespace) 178 // Remove all listeners on the event type (ignoring the namespace)
173 each((d, i, Element e) { 179 each((d, i, Element e) {
174 var handlers = scope._listeners[e], 180 var handlers = scope._listeners[e], t = type.substring(1);
175 t = type.substring(1);
176 handlers.forEach((String s, Pair<Function, bool> value) { 181 handlers.forEach((String s, Pair<Function, bool> value) {
177 if (s.split('.')[0] == t) { 182 if (s.split('.')[0] == t) {
178 e.removeEventListener(s, value.first, value.last); 183 e.removeEventListener(s, value.first, value.last);
179 } 184 }
180 }); 185 });
181 }); 186 });
182 } 187 }
183 } 188 }
184 189
185 int get length { 190 int get length {
(...skipping 17 matching lines...) Expand all
203 return null; 208 return null;
204 } 209 }
205 210
206 void attr(String name, val) { 211 void attr(String name, val) {
207 assert(name != null && name.isNotEmpty); 212 assert(name != null && name.isNotEmpty);
208 attrWithCallback(name, toCallback(val)); 213 attrWithCallback(name, toCallback(val));
209 } 214 }
210 215
211 void attrWithCallback(String name, SelectionCallback fn) { 216 void attrWithCallback(String name, SelectionCallback fn) {
212 assert(fn != null); 217 assert(fn != null);
213 _do(fn, (e, v) => v == null ? 218 _do(
214 e.attributes.remove(name) : e.attributes[name] = "$v"); 219 fn,
220 (e, v) =>
221 v == null ? e.attributes.remove(name) : e.attributes[name] = "$v");
215 } 222 }
216 223
217 void classed(String name, [bool val = true]) { 224 void classed(String name, [bool val = true]) {
218 assert(name != null && name.isNotEmpty); 225 assert(name != null && name.isNotEmpty);
219 classedWithCallback(name, toCallback(val)); 226 classedWithCallback(name, toCallback(val));
220 } 227 }
221 228
222 void classedWithCallback(String name, SelectionCallback<bool> fn) { 229 void classedWithCallback(String name, SelectionCallback<bool> fn) {
223 assert(fn != null); 230 assert(fn != null);
224 _do(fn, (e, v) => 231 _do(fn,
225 v == false ? e.classes.remove(name) : e.classes.add(name)); 232 (e, v) => v == false ? e.classes.remove(name) : e.classes.add(name));
226 } 233 }
227 234
228 void style(String property, val, {String priority}) { 235 void style(String property, val, {String priority}) {
229 assert(property != null && property.isNotEmpty); 236 assert(property != null && property.isNotEmpty);
230 styleWithCallback(property, 237 styleWithCallback(property, toCallback(val as String), priority: priority);
231 toCallback(val as String), priority: priority);
232 } 238 }
233 239
234 void styleWithCallback(String property, 240 void styleWithCallback(String property, SelectionCallback<String> fn,
235 SelectionCallback<String> fn, {String priority}) { 241 {String priority}) {
236 assert(fn != null); 242 assert(fn != null);
237 _do(fn, (Element e, String v) => 243 _do(
238 v == null || v.isEmpty ? 244 fn,
239 e.style.removeProperty(property) : 245 (Element e, String v) => v == null || v.isEmpty
240 e.style.setProperty(property, v, priority)); 246 ? e.style.removeProperty(property)
247 : e.style.setProperty(property, v, priority));
241 } 248 }
242 249
243 void text(String val) => textWithCallback(toCallback(val)); 250 void text(String val) => textWithCallback(toCallback(val));
244 251
245 void textWithCallback(SelectionCallback<String> fn) { 252 void textWithCallback(SelectionCallback<String> fn) {
246 assert(fn != null); 253 assert(fn != null);
247 _do(fn, (e, v) => e.text = v == null ? '' : v); 254 _do(fn, (e, v) => e.text = v == null ? '' : v);
248 } 255 }
249 256
250 void html(String val) => htmlWithCallback(toCallback(val)); 257 void html(String val) => htmlWithCallback(toCallback(val));
251 258
252 void htmlWithCallback(SelectionCallback<String> fn) { 259 void htmlWithCallback(SelectionCallback<String> fn) {
253 assert(fn != null); 260 assert(fn != null);
254 _do(fn, (e, v) => e.innerHtml = v == null ? '' : v); 261 _do(fn, (e, v) => e.innerHtml = v == null ? '' : v);
255 } 262 }
256 263
257 void remove() => _do(null, (e, _) => e.remove()); 264 void remove() => _do(null, (e, _) => e.remove());
258 265
259 Selection select(String selector) { 266 Selection select(String selector) {
260 assert(selector != null && selector.isNotEmpty); 267 assert(selector != null && selector.isNotEmpty);
261 return new _SelectionImpl.single(selector: selector, source: this); 268 return new _SelectionImpl.single(selector: selector, source: this);
262 } 269 }
263 270
264 Selection selectWithCallback(SelectionCallback<Element> fn) { 271 Selection selectWithCallback(SelectionCallback<Element> fn) {
265 assert(fn != null); 272 assert(fn != null);
266 return new _SelectionImpl.single(fn: fn, source:this); 273 return new _SelectionImpl.single(fn: fn, source: this);
267 } 274 }
268 275
269 Selection append(String tag) { 276 Selection append(String tag) {
270 assert(tag != null && tag.isNotEmpty); 277 assert(tag != null && tag.isNotEmpty);
271 return appendWithCallback( 278 return appendWithCallback(
272 (d, ei, e) => Namespace.createChildElement(tag, e)); 279 (d, ei, e) => Namespace.createChildElement(tag, e));
273 } 280 }
274 281
275 Selection appendWithCallback(SelectionCallback<Element> fn) { 282 Selection appendWithCallback(SelectionCallback<Element> fn) {
276 assert(fn != null); 283 assert(fn != null);
277 return new _SelectionImpl.single(fn: (datum, ei, e) { 284 return new _SelectionImpl.single(fn: (datum, ei, e) {
278 Element child = fn(datum, ei, e); 285 Element child = fn(datum, ei, e);
279 return child == null ? null : e.append(child); 286 return child == null ? null : e.append(child);
280 }, source: this); 287 }, source: this);
281 } 288 }
282 289
283 Selection insert(String tag, 290 Selection insert(String tag,
284 {String before, SelectionCallback<Element> beforeFn}) { 291 {String before, SelectionCallback<Element> beforeFn}) {
285 assert(tag != null && tag.isNotEmpty); 292 assert(tag != null && tag.isNotEmpty);
286 return insertWithCallback( 293 return insertWithCallback(
287 (d, ei, e) => Namespace.createChildElement(tag, e), 294 (d, ei, e) => Namespace.createChildElement(tag, e),
288 before: before, beforeFn: beforeFn); 295 before: before,
296 beforeFn: beforeFn);
289 } 297 }
290 298
291 Selection insertWithCallback(SelectionCallback<Element> fn, 299 Selection insertWithCallback(SelectionCallback<Element> fn,
292 {String before, SelectionCallback<Element> beforeFn}) { 300 {String before, SelectionCallback<Element> beforeFn}) {
293 assert(fn != null); 301 assert(fn != null);
294 beforeFn = 302 beforeFn =
295 before == null ? beforeFn : (d, ei, e) => e.querySelector(before); 303 before == null ? beforeFn : (d, ei, e) => e.querySelector(before);
296 return new _SelectionImpl.single( 304 return new _SelectionImpl.single(fn: (datum, ei, e) {
297 fn: (datum, ei, e) { 305 Element child = fn(datum, ei, e);
298 Element child = fn(datum, ei, e); 306 Element before = beforeFn(datum, ei, e);
299 Element before = beforeFn(datum, ei, e); 307 return child == null ? null : e.insertBefore(child, before);
300 return child == null ? null : e.insertBefore(child, before); 308 }, source: this);
301 },
302 source: this);
303 } 309 }
304 310
305 Selection selectAll(String selector) { 311 Selection selectAll(String selector) {
306 assert(selector != null && selector.isNotEmpty); 312 assert(selector != null && selector.isNotEmpty);
307 return new _SelectionImpl.all(selector: selector, source: this); 313 return new _SelectionImpl.all(selector: selector, source: this);
308 } 314 }
309 315
310 Selection selectAllWithCallback(SelectionCallback<Iterable<Element>> fn) { 316 Selection selectAllWithCallback(SelectionCallback<Iterable<Element>> fn) {
311 assert(fn != null); 317 assert(fn != null);
312 return new _SelectionImpl.all(fn: fn, source:this); 318 return new _SelectionImpl.all(fn: fn, source: this);
313 } 319 }
314 320
315 DataSelection data(Iterable vals, [SelectionKeyFunction keyFn]) { 321 DataSelection data(Iterable vals, [SelectionKeyFunction keyFn]) {
316 assert(vals != null); 322 assert(vals != null);
317 return dataWithCallback(toCallback(vals), keyFn); 323 return dataWithCallback(toCallback(vals), keyFn);
318 } 324 }
319 325
320 DataSelection dataWithCallback( 326 DataSelection dataWithCallback(SelectionCallback<Iterable> fn,
321 SelectionCallback<Iterable> fn, [SelectionKeyFunction keyFn]) { 327 [SelectionKeyFunction keyFn]) {
322 assert(fn != null); 328 assert(fn != null);
323 329
324 var enterGroups = [], 330 var enterGroups = [], updateGroups = [], exitGroups = [];
325 updateGroups = [],
326 exitGroups = [];
327 331
328 // Create a dummy node to be used with enter() selection. 332 // Create a dummy node to be used with enter() selection.
329 Object dummy(val) { 333 Object dummy(val) {
330 var element = new Object(); 334 var element = new Object();
331 scope.associate(element, val); 335 scope.associate(element, val);
332 return element; 336 return element;
333 }; 337 }
338 ;
334 339
335 // Joins data to all elements in the group. 340 // Joins data to all elements in the group.
336 void join(SelectionGroup g, Iterable vals) { 341 void join(SelectionGroup g, Iterable vals) {
337 final int valuesLength = vals.length; 342 final int valuesLength = vals.length;
338 final int elementsLength = g.elements.length; 343 final int elementsLength = g.elements.length;
339 344
340 // Nodes exiting, entering and updating in this group. 345 // Nodes exiting, entering and updating in this group.
341 // We maintain the nodes at the same index as they currently 346 // We maintain the nodes at the same index as they currently
342 // are (for exiting) or where they should be (for entering and updating) 347 // are (for exiting) or where they should be (for entering and updating)
343 var update = new List(valuesLength), 348 var update = new List(valuesLength),
344 enter = new List(valuesLength), 349 enter = new List(valuesLength),
345 exit = new List(elementsLength); 350 exit = new List(elementsLength);
346 351
347 // Use key function to determine DOMElement to data associations. 352 // Use key function to determine DOMElement to data associations.
348 if (keyFn != null) { 353 if (keyFn != null) {
349 var keysOnDOM = [], 354 var keysOnDOM = [], elementsByKey = {}, valuesByKey = {};
350 elementsByKey = {},
351 valuesByKey = {};
352 355
353 // Create a key to DOM element map. 356 // Create a key to DOM element map.
354 // Used later to see if an element already exists for a key. 357 // Used later to see if an element already exists for a key.
355 for (int ei = 0, len = elementsLength; ei < len; ++ei) { 358 for (int ei = 0, len = elementsLength; ei < len; ++ei) {
356 final e = g.elements.elementAt(ei); 359 final e = g.elements.elementAt(ei);
357 var keyValue = keyFn(scope.datum(e)); 360 var keyValue = keyFn(scope.datum(e));
358 if (elementsByKey.containsKey(keyValue)) { 361 if (elementsByKey.containsKey(keyValue)) {
359 exit[ei] = e; 362 exit[ei] = e;
360 } else { 363 } else {
361 elementsByKey[keyValue] = e; 364 elementsByKey[keyValue] = e;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 // List of elements exiting this group 415 // List of elements exiting this group
413 for (int len = elementsLength; i < len; ++i) { 416 for (int len = elementsLength; i < len; ++i) {
414 exit[i] = g.elements.elementAt(i); 417 exit[i] = g.elements.elementAt(i);
415 } 418 }
416 } 419 }
417 420
418 // Create the element groups and set parents from the current group. 421 // Create the element groups and set parents from the current group.
419 enterGroups.add(new _SelectionGroupImpl(enter, parent: g.parent)); 422 enterGroups.add(new _SelectionGroupImpl(enter, parent: g.parent));
420 updateGroups.add(new _SelectionGroupImpl(update, parent: g.parent)); 423 updateGroups.add(new _SelectionGroupImpl(update, parent: g.parent));
421 exitGroups.add(new _SelectionGroupImpl(exit, parent: g.parent)); 424 exitGroups.add(new _SelectionGroupImpl(exit, parent: g.parent));
422 }; 425 }
426 ;
423 427
424 for (int gi = 0; gi < groups.length; ++gi) { 428 for (int gi = 0; gi < groups.length; ++gi) {
425 final g = groups.elementAt(gi); 429 final g = groups.elementAt(gi);
426 join(g, fn(scope.datum(g.parent), gi, g.parent)); 430 join(g, fn(scope.datum(g.parent), gi, g.parent));
427 } 431 }
428 432
429 return new _DataSelectionImpl( 433 return new _DataSelectionImpl(updateGroups, enterGroups, exitGroups, scope);
430 updateGroups, enterGroups, exitGroups, scope);
431 } 434 }
432 435
433 void datum(Iterable vals) { 436 void datum(Iterable vals) {
434 throw new UnimplementedError(); 437 throw new UnimplementedError();
435 } 438 }
436 439
437 void datumWithCallback(SelectionCallback<Iterable> fn) { 440 void datumWithCallback(SelectionCallback<Iterable> fn) {
438 throw new UnimplementedError(); 441 throw new UnimplementedError();
439 } 442 }
440 443
441 Transition transition() => new Transition(this); 444 Transition transition() => new Transition(this);
442 } 445 }
443 446
444 /* Implementation of [DataSelection] */ 447 /* Implementation of [DataSelection] */
445 class _DataSelectionImpl extends _SelectionImpl implements DataSelection { 448 class _DataSelectionImpl extends _SelectionImpl implements DataSelection {
446 EnterSelection enter; 449 EnterSelection enter;
447 ExitSelection exit; 450 ExitSelection exit;
448 451
449 _DataSelectionImpl(Iterable updated, Iterable entering, Iterable exiting, 452 _DataSelectionImpl(Iterable updated, Iterable entering, Iterable exiting,
450 SelectionScope scope) : super.selectionGroups(updated, scope) { 453 SelectionScope scope)
454 : super.selectionGroups(updated, scope) {
451 enter = new _EnterSelectionImpl(entering, this); 455 enter = new _EnterSelectionImpl(entering, this);
452 exit = new _ExitSelectionImpl(exiting, this); 456 exit = new _ExitSelectionImpl(exiting, this);
453 } 457 }
454 } 458 }
455 459
456 /* Implementation of [EnterSelection] */ 460 /* Implementation of [EnterSelection] */
457 class _EnterSelectionImpl implements EnterSelection { 461 class _EnterSelectionImpl implements EnterSelection {
458 final DataSelection update; 462 final DataSelection update;
459 463
460 SelectionScope scope; 464 SelectionScope scope;
461 Iterable<SelectionGroup> groups; 465 Iterable<SelectionGroup> groups;
462 466
463 _EnterSelectionImpl(Iterable this.groups, DataSelection this.update) { 467 _EnterSelectionImpl(Iterable this.groups, DataSelection this.update) {
464 scope = update.scope; 468 scope = update.scope;
465 } 469 }
466 470
467 bool get isEmpty => false; 471 bool get isEmpty => false;
468 472
469 Selection insert(String tag, 473 Selection insert(String tag,
470 {String before, SelectionCallback<Element> beforeFn}) { 474 {String before, SelectionCallback<Element> beforeFn}) {
471 assert(tag != null && tag.isNotEmpty); 475 assert(tag != null && tag.isNotEmpty);
472 return insertWithCallback( 476 return insertWithCallback(
473 (d, ei, e) => Namespace.createChildElement(tag, e), 477 (d, ei, e) => Namespace.createChildElement(tag, e),
474 before: before, beforeFn: beforeFn); 478 before: before,
479 beforeFn: beforeFn);
475 } 480 }
476 481
477 Selection insertWithCallback(SelectionCallback<Element> fn, 482 Selection insertWithCallback(SelectionCallback<Element> fn,
478 {String before, SelectionCallback<Element> beforeFn}) { 483 {String before, SelectionCallback<Element> beforeFn}) {
479 assert(fn != null); 484 assert(fn != null);
480 return selectWithCallback((d, ei, e) { 485 return selectWithCallback((d, ei, e) {
481 Element child = fn(d, ei, e); 486 Element child = fn(d, ei, e);
482 e.insertBefore(child, e.querySelector(before)); 487 e.insertBefore(child, e.querySelector(before));
483 return child; 488 return child;
484 }); 489 });
485 } 490 }
486 491
487 Selection append(String tag) { 492 Selection append(String tag) {
488 assert(tag != null && tag.isNotEmpty); 493 assert(tag != null && tag.isNotEmpty);
489 return appendWithCallback( 494 return appendWithCallback(
490 (d, ei, e) => Namespace.createChildElement(tag, e)); 495 (d, ei, e) => Namespace.createChildElement(tag, e));
491 } 496 }
492 497
493 Selection appendWithCallback(SelectionCallback<Element> fn) { 498 Selection appendWithCallback(SelectionCallback<Element> fn) {
494 assert(fn != null); 499 assert(fn != null);
495 return selectWithCallback((datum, ei, e) { 500 return selectWithCallback((datum, ei, e) {
496 Element child = fn(datum, ei, e); 501 Element child = fn(datum, ei, e);
497 e.append(child); 502 e.append(child);
498 return child; 503 return child;
499 }); 504 });
500 } 505 }
501 506
502 Selection select(String selector) { 507 Selection select(String selector) {
503 assert(selector == null && selector.isNotEmpty); 508 assert(selector == null && selector.isNotEmpty);
504 return selectWithCallback((d, ei, e) => e.querySelector(selector)); 509 return selectWithCallback((d, ei, e) => e.querySelector(selector));
505 } 510 }
506 511
507 Selection selectWithCallback(SelectionCallback<Element> fn) { 512 Selection selectWithCallback(SelectionCallback<Element> fn) {
508 var subgroups = []; 513 var subgroups = [];
509 for (int gi = 0, len = groups.length; gi < len; ++gi) { 514 for (int gi = 0, len = groups.length; gi < len; ++gi) {
510 final g = groups.elementAt(gi); 515 final g = groups.elementAt(gi);
511 final u = update.groups.elementAt(gi); 516 final u = update.groups.elementAt(gi);
512 final subgroup = []; 517 final subgroup = [];
513 for (int ei = 0, eLen = g.elements.length; ei < eLen; ++ei) { 518 for (int ei = 0, eLen = g.elements.length; ei < eLen; ++ei) {
514 final e = g.elements.elementAt(ei); 519 final e = g.elements.elementAt(ei);
515 if (e != null) { 520 if (e != null) {
516 var datum = scope.datum(e), 521 var datum = scope.datum(e), selected = fn(datum, ei, g.parent);
517 selected = fn(datum, ei, g.parent);
518 scope.associate(selected, datum); 522 scope.associate(selected, datum);
519 u.elements[ei] = selected; 523 u.elements[ei] = selected;
520 subgroup.add(selected); 524 subgroup.add(selected);
521 } else { 525 } else {
522 subgroup.add(null); 526 subgroup.add(null);
523 } 527 }
524 } 528 }
525 subgroups.add(new _SelectionGroupImpl(subgroup, parent: g.parent)); 529 subgroups.add(new _SelectionGroupImpl(subgroup, parent: g.parent));
526 } 530 }
527 return new _SelectionImpl.selectionGroups(subgroups, scope); 531 return new _SelectionImpl.selectionGroups(subgroups, scope);
528 } 532 }
529 } 533 }
530 534
531 /* Implementation of [ExitSelection] */ 535 /* Implementation of [ExitSelection] */
532 class _ExitSelectionImpl extends _SelectionImpl implements ExitSelection { 536 class _ExitSelectionImpl extends _SelectionImpl implements ExitSelection {
533 final DataSelection update; 537 final DataSelection update;
534 _ExitSelectionImpl(Iterable groups, DataSelection update) 538 _ExitSelectionImpl(Iterable groups, DataSelection update)
535 : update = update, super.selectionGroups(groups, update.scope); 539 : update = update,
540 super.selectionGroups(groups, update.scope);
536 } 541 }
537 542
538 class _SelectionGroupImpl implements SelectionGroup { 543 class _SelectionGroupImpl implements SelectionGroup {
539 Iterable<Element> elements; 544 Iterable<Element> elements;
540 Element parent; 545 Element parent;
541 _SelectionGroupImpl(this.elements, {this.parent}); 546 _SelectionGroupImpl(this.elements, {this.parent});
542 } 547 }
OLDNEW
« no previous file with comments | « packages/charted/lib/selection/selection_scope.dart ('k') | packages/charted/lib/selection/src/transition_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698