1 | import { isArray } from "d3-let";
|
2 | import { select } from "d3-selection";
|
3 | import { createComponent, protoView } from "../core/component";
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | export default {
|
12 | create(expression) {
|
13 | var bits = [];
|
14 | expression
|
15 | .trim()
|
16 | .split(" ")
|
17 | .forEach(v => {
|
18 | v ? bits.push(v) : null;
|
19 | });
|
20 | if (bits.length !== 3 || bits[1] != "in")
|
21 | return this.logWarn(
|
22 | `directive requires "item in expression" template, got "${expression}"`
|
23 | );
|
24 | this.itemName = bits[0];
|
25 | this.itemClass = `for${this.uid}`;
|
26 | return bits[2];
|
27 | },
|
28 |
|
29 | preMount() {
|
30 | return true;
|
31 | },
|
32 |
|
33 | mount(model) {
|
34 | this.creator = this.el;
|
35 | this.el = this.creator.parentNode;
|
36 |
|
37 | select(this.creator).remove();
|
38 | if (this.el) return model;
|
39 | },
|
40 |
|
41 | refresh(model, items) {
|
42 | if (!isArray(items)) return;
|
43 | let d;
|
44 |
|
45 | var creator = this.creator,
|
46 | itemClass = this.itemClass,
|
47 | selector = `.${itemClass}`,
|
48 | itemName = this.itemName,
|
49 | sel = this.sel,
|
50 | allItems = sel.selectAll(selector),
|
51 | entries = allItems
|
52 | .filter(function() {
|
53 | d = this.__d3_view__.model[itemName];
|
54 | return items.indexOf(d) > -1;
|
55 | })
|
56 | .data(items),
|
57 | exits = allItems
|
58 | .filter(function() {
|
59 | d = this.__d3_view__.model[itemName];
|
60 | return items.indexOf(d) === -1;
|
61 | })
|
62 | .classed(itemClass, false),
|
63 | vm = sel.view();
|
64 |
|
65 | let forComponent = vm.components.get(creator.tagName.toLowerCase());
|
66 | if (!forComponent) forComponent = createComponent("forView", protoView);
|
67 |
|
68 | let x, el, fel, tr;
|
69 |
|
70 | (this.transition(exits) || exits).style("opacity", 0).remove();
|
71 |
|
72 |
|
73 | entries
|
74 | .enter()
|
75 | .append(() => {
|
76 | el = creator.cloneNode(true);
|
77 | fel = vm.select(el);
|
78 | if (vm.transitionDuration(fel) > 0) fel.style("opacity", 0);
|
79 | return el;
|
80 | })
|
81 | .each(function(d, index) {
|
82 | x = { index: index };
|
83 | x[itemName] = d;
|
84 | forComponent({
|
85 | model: x,
|
86 | parent: vm
|
87 | })
|
88 | .mount(this, { model: vm.model })
|
89 | .then(fv => {
|
90 | fv.sel.classed(itemClass, true);
|
91 |
|
92 |
|
93 | items[index] = fv.model[itemName];
|
94 | tr = fv.transition();
|
95 | if (tr) tr.style("opacity", 1);
|
96 | });
|
97 | });
|
98 |
|
99 | sel.selectAll(selector).each(function(d) {
|
100 |
|
101 | this.__d3_view__.model[itemName] = d;
|
102 | });
|
103 | }
|
104 | };
|