UNPKG

d3-visualize

Version:

d3-view components for data visualization

121 lines (105 loc) 3.17 kB
import {isArray} from 'd3-let'; import crossfilter from 'crossfilter'; import getColumns from './impl/get-columns'; import accessor from '../utils/accessor'; export default function DataFrame (data, store) { if (isArray(data) || !arguments.length) data = { store: store, data: data || [], dimensions: {} }; Object.defineProperties(this, { _inner: { get () { return data; } }, store: { get () { return data.store; } }, data: { get () { return data.data; } }, dimensions: { get () { return data.dimensions; } }, type: { get () { return 'dataframe'; } }, columns: { get () { if (!data.columns) data.columns = getColumns(data.data); return data.columns; } } }); } DataFrame.prototype = { constructor: DataFrame, dataFrame () { return this; }, size () { return this.data.length; }, new (serie) { if (isArray(serie)) return new DataFrame(serie, null, this.store); else return new DataFrame(this._inner, serie); }, cf () { if (!this._inner.cf) this._inner.cf = crossfilter(this.data); return this._inner.cf; }, // Create and return a crossfilter dimension // If value is not specified, keepExisting is by default true, and any // existing dimension name is recycled. dimension (name, value, keepExisting) { if (arguments.length === 1) keepExisting = true; var current = this.dimensions[name]; if (current) { if (keepExisting) return current; current.dispose(); } if (!value) value = accessor(name); this.dimensions[name] = this.cf().dimension(value); return this.dimensions[name]; }, // Sort a dataframe by name and return the top values or all of them if // top is not defined. The name can be a function. sortby (name, top) { return this.new(this.dimension(name).top(top || Infinity)); }, // return a new dataframe by pivoting values for field name pivot (dimension, key, value, total) { var group = this.dimension(dimension).group(); if (!total) total = 'total'; return this.new(group.reduce(pivoter(1), pivoter(-1), Object).all().map(d => d.value)); function pivoter (m) { let pk, pv; return function (o, record) { pk = ''+record[key]; pv = m*record[value]; o[dimension] = record[dimension]; if (pk in o) o[pk] += pv; else o[pk] = pv; if (total in o) o[total] += pv; else o[total] = pv; return o; }; } }, add () { //this._inner.cf.add(data); }, map (mapper) { return this.new(this.data.map(mapper)); } };