| 1855 | } |
| 1856 | |
| 1857 | function bindKey(parent, group, enter, update, exit, data, key) { |
| 1858 | var i, |
| 1859 | node, |
| 1860 | nodeByKeyValue = new Map, |
| 1861 | groupLength = group.length, |
| 1862 | dataLength = data.length, |
| 1863 | keyValues = new Array(groupLength), |
| 1864 | keyValue; |
| 1865 | |
| 1866 | // Compute the key for each node. |
| 1867 | // If multiple nodes have the same key, the duplicates are added to exit. |
| 1868 | for (i = 0; i < groupLength; ++i) { |
| 1869 | if (node = group[i]) { |
| 1870 | keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + ""; |
| 1871 | if (nodeByKeyValue.has(keyValue)) { |
| 1872 | exit[i] = node; |
| 1873 | } else { |
| 1874 | nodeByKeyValue.set(keyValue, node); |
| 1875 | } |
| 1876 | } |
| 1877 | } |
| 1878 | |
| 1879 | // Compute the key for each datum. |
| 1880 | // If there a node associated with this key, join and add it to update. |
| 1881 | // If there is not (or the key is a duplicate), add it to enter. |
| 1882 | for (i = 0; i < dataLength; ++i) { |
| 1883 | keyValue = key.call(parent, data[i], i, data) + ""; |
| 1884 | if (node = nodeByKeyValue.get(keyValue)) { |
| 1885 | update[i] = node; |
| 1886 | node.__data__ = data[i]; |
| 1887 | nodeByKeyValue.delete(keyValue); |
| 1888 | } else { |
| 1889 | enter[i] = new EnterNode(parent, data[i]); |
| 1890 | } |
| 1891 | } |
| 1892 | |
| 1893 | // Add any remaining nodes that were not bound to data to exit. |
| 1894 | for (i = 0; i < groupLength; ++i) { |
| 1895 | if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) { |
| 1896 | exit[i] = node; |
| 1897 | } |
| 1898 | } |
| 1899 | } |
| 1900 | |
| 1901 | function datum(node) { |
| 1902 | return node.__data__; |