uniapp开发app框架在提升开发效率中的独特优势与应用探索
895
2022-09-01
深入学习D3js:d3-array Transformations部分
d3.rollup(iterable, reduce, …keys)
将可迭代的值转化为Map,转化结果从key到value,并支持嵌套。
function dogroup(values, keyof) { const map = new Map(); let index = -1; for (const value of values) { const key = keyof(value, ++index, values); const group = map.get(key); if (group) group.push(value); else map.set(key, [value]); } return map;}export default function rollup(values, reduce, ...keys) { return (function regroup(values, i) { if (i >= keys.length) return reduce(values); const map = dogroup(values, keys[i]); return new Map(Array.from(map, ([k, v]) => [k, regroup(v, i + 1)])); })(values, 0);}
这里rollup返回一个立即执行函数,该函数会首先执行一次dogroup函数,根据keys的对应关系生成一个map,然后根据keys的长度去递归的调用regroup生成嵌套map,最后调用reduce。形成一条k=>k=>value递归链。用法如下:
d3.rollup(data, v => v.length, d => d.name, d => d.date)
结果为
Map(3) { "jim" => Map(1) { "11/12/2015" => 1 } "carl" => Map(1) { "11/12/2015" => 1 } "stacy" => Map(1) { "01/04/2016" => 2 }}
d3.group(iterable, …keys)
import identity from "./identity.js";import rollup from "./rollup.js";export default function group(values, ...keys) { return rollup(values, identity, ...keys);}
identity.js
export default function(x) { return x;}
该函数是简化的rollup,rollup的结果是key对应到value上,group则是key对应到数组上,减少了计算值的一个函数(使用默认的identity)。用法如下:
data = [ {name: "jim", amount: "34.0", date: "11/12/2015"}, {name: "carl", amount: "120.11", date: "11/12/2015"}, {name: "stacy", amount: "12.01", date: "01/04/2016"}, {name: "stacy", amount: "34.05", date: "01/04/2016"}]d3.group(data, d => d.name)Map(3) { "jim" => Array(1) "carl" => Array(1) "stacy" => Array(2)}
d3.cross(…iterables[, reducer])
function length(array) { return array.length | 0;}function empty(length) { return !(length > 0);}function arrayify(values) { return typeof values !== "object" || "length" in values ? values : Array.from(values);}function reducer(reduce) { return values => reduce(...values);}export default function cross(...values) { const reduce = typeof values[values.length - 1] === "function" && reducer(values.pop());//如果最后参数传入函数,对每一个valuesz执行该函数 values = values.map(arrayify);//调用array,from将values转化为数组 const lengths = values.map(length);//length保存数组长度的数组 const j = values.length - 1; const index = new Array(j + 1).fill(0);//见过这道题。。 const product = []; if (j < 0 || lengths.some(empty)) return product;//如果数组长度小于0或者有数组为空,就返回一个空数组 while (true) {//这个函数修改了原数组的顺序 product.push(index.map((j, i) => values[i][j])); let i = j; while (++index[i] === lengths[i]) { if (i === 0) return reduce ? product.map(reduce) : product; index[i--] = 0; } }}
返回两个数组的笛卡儿积。
d3.merge(iterables)
和concat类似,讲数组进行合并,用法如下:
d3.merge([[1], [2, 3]]); // returns [1, 2, 3]
function* flatten(arrays) { for (const array of arrays) { yield* array; }}export default function merge(arrays) { return Array.from(flatten(arrays));}
实现中用到了生成器函数返回生成器的迭代器对象,再通过array.from转化成数组,array.from转化条件有2条,1,是要求维数组对象,拥有一个length属性和若干索引属性的任意对象2,可迭代对象,可以获取对象中的元素,如map,set
d3.pairs(iterable[, reducer])
d3.pairs([1, 2, 3, 4]); // returns [[1, 2], [2, 3], [3, 4]]d3.pairs([1, 2, 3, 4], (a, b) => b - a); // returns [1, 1, 1];
返回一个数组对,如果给定了reducer函数,返回计算后的数组。
export default function pairs(values, pairof = pair) { const pairs = []; let previous; let first = false; for (const value of values) { if (first) pairs.push(pairof(previous, value)); previous = value; first = true; } return pairs;}export function pair(a, b) { return [a, b];}
这个很简单,就是一个for循环,用一个previous记录上一个数组的值,第一次有特殊处理。
d3.permute(array, indexes)
permute(["a", "b", "c"], [1, 2, 0]); // returns ["b", "c", "a"]
export default function(source, keys) { return Array.from(keys, key => source[key]);}
根据输入的数组以及一个key值数组,修改原数组顺序。
d3.shuffle(array[, start[, stop]])
export default function shuffle(array, i0 = 0, i1 = array.length) { var m = i1 - (i0 = +i0), t, i; while (m) { i = Math.random() * m-- | 0; t = array[m + i0]; array[m + i0] = array[i + i0]; array[i + i0] = t; } return array;}
随机打乱数组顺序,说是用Fisher–Yates Shuffle算法,代码就是一个随机数互换位置。
d3.ticks(start, stop, count)
d3.range([start, ]stop[, step])
根据输入值返回一个数组。
export default function(start, stop, step) { start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0, range = new Array(n); while (++i < n) { range[i] = start + i * step; } return range;}
d3.zip(arrays…)
根据输入数组,返回的多维数组第i个元素包含每个输入数组的第一个元素。
import min from "./min.js";export default function(matrix) { if (!(n = matrix.length)) return []; for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) { row[j] = matrix[j][i]; } } return transpose;}function length(d) { return d.length;}
d3.transpose(matrix)
和d3.zip一样对矩阵进行操作
d3.ticks(start, stop, count)
根据输入,返回一个分段数组,这个有点复杂,后面在仔细分析。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~