@vizabi/core
Advanced tools
Comparing version 1.23.2 to 1.23.3
@@ -1,2 +0,2 @@ | ||
// http://vizabi.org v1.23.2 Copyright 2022 Jasper Heeffer and others at Gapminder Foundation | ||
// http://vizabi.org v1.23.3 Copyright 2022 Jasper Heeffer and others at Gapminder Foundation | ||
(function (global, factory) { | ||
@@ -1076,5 +1076,5 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('mobx')) : | ||
*/ | ||
function interpolate(df, fields = df.fields) { | ||
function interpolate(df, fields = df.fields, interpolators = {}) { | ||
for (let field of fields) { | ||
interpolateField(df, field); | ||
interpolateField(df, field, interpolators[field]); | ||
} | ||
@@ -1084,6 +1084,6 @@ return df; | ||
function interpolateField(df, field) { | ||
function interpolateField(df, field, interpolator) { | ||
const gap = newGap(); | ||
for (let row of df.values()) { | ||
evaluateGap(row, field, gap); | ||
evaluateGap(row, field, gap, interpolator); | ||
} | ||
@@ -1099,3 +1099,3 @@ } | ||
function evaluateGap(row, field, gap) { | ||
function evaluateGap(row, field, gap, interpolator) { | ||
const { rows, start } = gap; | ||
@@ -1109,3 +1109,3 @@ const fieldVal = row[field]; | ||
if (rows.length > 0) { | ||
interpolateGap(rows, start, row, field); | ||
interpolateGap(rows, start, row, field, interpolator); | ||
rows.length = 0; | ||
@@ -1117,6 +1117,6 @@ } | ||
function interpolateGap(gapRows, startRow, endRow, field) { | ||
function interpolateGap(gapRows, startRow, endRow, field, interpolator = d3.interpolate) { | ||
const startVal = startRow[field]; | ||
const endVal = endRow[field]; | ||
const int = d3.interpolate(startVal, endVal); | ||
const int = interpolator(startVal, endVal); | ||
const delta = 1 / (gapRows.length+1); | ||
@@ -1134,3 +1134,3 @@ let mu = 0; | ||
function interpolateGroup(group, { fields = group.fields, ammendNewRow = () => {} } = {}) { | ||
function interpolateGroup(group, { fields = group.fields, interpolators = {}, ammendNewRow = () => {} } = {}) { | ||
@@ -1174,3 +1174,3 @@ // what fields to interpolate? | ||
const endRow = group.get(frameKeys[i]).get(markerKey); | ||
interpolateGap(gapRows, startRow, endRow, field); | ||
interpolateGap(gapRows, startRow, endRow, field, interpolators[field]); | ||
} | ||
@@ -1487,5 +1487,5 @@ lastIndexPerMarker.set(markerKey, i); | ||
*/ | ||
function interpolateBetween(from, to, mu) { | ||
function interpolateBetween(from, to, mu, fields = from.fields, interpolators = {}) { | ||
const df = DataFrame([], from.key); | ||
let newRow, row2; | ||
@@ -1498,4 +1498,4 @@ for(const key of from.keys()) { | ||
newRow = Object.assign({}, row1); | ||
for (let field in newRow) { | ||
newRow[field] = d3.interpolate(row1[field], row2[field])(mu); | ||
for (let field of fields) { | ||
newRow[field] = (interpolators[field] || d3.interpolate)(row1[field], row2[field])(mu); | ||
} | ||
@@ -1535,3 +1535,3 @@ } else { | ||
interpolate: () => interpolate(df), | ||
interpolateTowards: (df2, mu) => interpolateBetween(df, df2, mu), | ||
interpolateTowards: (df2, mu, fields, interpolators) => interpolateBetween(df, df2, mu, fields, interpolators), | ||
reindex: (iterable) => reindex(df, iterable), | ||
@@ -1538,0 +1538,0 @@ fillNull: (fillValues) => fillNull(df, fillValues), |
{ | ||
"name": "@vizabi/core", | ||
"version": "1.23.2", | ||
"version": "1.23.3", | ||
"description": "Vizabi core (data layer)", | ||
@@ -5,0 +5,0 @@ "main": "dist/Vizabi.js", |
@@ -21,8 +21,2 @@ import { encoding } from './encoding'; | ||
functions: { | ||
get grouping () { | ||
return this.config.grouping ?? {}; | ||
}, | ||
get measures() { | ||
return this.config.measures ?? []; | ||
}, | ||
//"geo" | ||
@@ -42,43 +36,3 @@ get row() { | ||
console.log("called transformation in facet enc", df) | ||
const max = {}; | ||
[...df.values() ].forEach(v => { | ||
if (!v.shapedata) return; | ||
const maxForRow = d3.max(v.shapedata.split(",").map(m=>+m)); | ||
if (!max[v.country] || max[v.country] < maxForRow) max[v.country] = maxForRow; | ||
}) | ||
df.addColumn("max", (row)=>max[row.country]); | ||
return df; | ||
const groupSizes = filterObject(this.grouping, | ||
(val, key) => df.key.includes(key) && val['grouping'] > 1 | ||
); | ||
const measures = this.measures; | ||
if (Object.keys(groupSizes).length == 0) { | ||
return df; | ||
} | ||
let result = DataFrame([], df.key); | ||
for (const row of df.rows()) { | ||
// new grouped key | ||
const newKeyObj = pick(row, df.key); | ||
for (const dim in groupSizes) { | ||
const groupSize = groupSizes[dim]['grouping']; | ||
newKeyObj[dim] = Math.floor(+row[dim] / groupSize) * groupSize; | ||
} | ||
const keyStr = result.keyFn(newKeyObj); | ||
// sum if group already exists, otherwise create | ||
if (result.hasByStr(keyStr)) { | ||
const newRow = result.getByStr(keyStr); | ||
measures.forEach(measure => newRow[measure] += row[measure]) | ||
} else { | ||
const newRow = assign({}, row, newKeyObj); | ||
result.setByStr(keyStr, newRow) | ||
} | ||
} | ||
return result; | ||
}, | ||
@@ -85,0 +39,0 @@ get transformationFns() { |
import { encoding } from './encoding'; | ||
import { action, observable, reaction, computed, trace } from 'mobx' | ||
import { FULFILLED } from 'mobx-utils' | ||
import { assign, applyDefaults, relativeComplement, configValue, parseConfigValue, inclusiveRange, combineStates, equals, createModel } from '../utils'; | ||
import { assign, applyDefaults, relativeComplement, configValue, parseConfigValue, inclusiveRange, combineStates, equals, createModel, stepBeforeInterpolator } from '../utils'; | ||
import { DataFrameGroup } from '../../dataframe/dataFrameGroup'; | ||
@@ -241,2 +241,3 @@ import { createKeyFn } from '../../dataframe/dfutils'; | ||
fields: this.changeBetweenFramesEncodings, | ||
interpolators: this.fieldCustomInterpolators, | ||
ammendNewRow: row => row[this.data.concept] = row[encName] | ||
@@ -257,2 +258,14 @@ }); | ||
}, | ||
get fieldCustomInterpolators() { | ||
const enc = this.marker.encoding; | ||
return this.changeBetweenFramesEncodings.reduce((result, encName) => { | ||
if(!["measure", "time"].includes(enc[encName].data?.conceptProps?.concept_type) | ||
&& !enc[encName].scale?.interpolate | ||
&& !enc[encName].data?.conceptProps?.interpolate){ | ||
//use zero order interpolation instead default d3.interpolate | ||
result[encName] = stepBeforeInterpolator; | ||
} | ||
return result; | ||
}, {}); | ||
}, | ||
@@ -310,6 +323,9 @@ get interval() { | ||
}, | ||
get fieldsToInterpolate() { | ||
return [this.name, this.data.concept, ...this.changeBetweenFramesEncodings]; | ||
}, | ||
getInterpolatedFrame(df, step, stepsAround) { | ||
const keys = Array.from(df.keys()); | ||
const [before, after] = stepsAround.map(step => df.get(keys[step])); | ||
return before.interpolateTowards(after, step % 1); | ||
return before.interpolateTowards(after, step % 1, this.fieldsToInterpolate, this.fieldCustomInterpolators); | ||
}, | ||
@@ -316,0 +332,0 @@ get stepsAround() { |
@@ -608,2 +608,10 @@ import { fromPromise } from "mobx-utils"; | ||
return typeof obj[Symbol.iterator] === 'function'; | ||
} | ||
} | ||
export function stepBeforeInterpolator(startVal, endVal) { | ||
if (typeof startVal === "object") { | ||
const jsonStartVal = JSON.stringify(startVal); | ||
const jsonEndtVal = JSON.stringify(endVal); | ||
return t => JSON.parse(t < 1 ? jsonStartVal : jsonEndtVal); | ||
} else return t => t < 1 ? startVal : endVal; | ||
} |
@@ -45,3 +45,3 @@ import { order } from "./transforms/order"; | ||
interpolate: () => interpolate(df), | ||
interpolateTowards: (df2, mu) => interpolateBetween(df, df2, mu), | ||
interpolateTowards: (df2, mu, fields, interpolators) => interpolateBetween(df, df2, mu, fields, interpolators), | ||
reindex: (iterable) => reindex(df, iterable), | ||
@@ -48,0 +48,0 @@ fillNull: (fillValues) => fillNull(df, fillValues), |
@@ -7,5 +7,5 @@ import { assign, pickGetters, relativeComplement } from "../../core/utils"; | ||
*/ | ||
export function interpolate(df, fields = df.fields) { | ||
export function interpolate(df, fields = df.fields, interpolators = {}) { | ||
for (let field of fields) { | ||
interpolateField(df, field); | ||
interpolateField(df, field, interpolators[field]); | ||
} | ||
@@ -15,6 +15,6 @@ return df; | ||
function interpolateField(df, field) { | ||
function interpolateField(df, field, interpolator) { | ||
const gap = newGap(); | ||
for (let row of df.values()) { | ||
evaluateGap(row, field, gap); | ||
evaluateGap(row, field, gap, interpolator); | ||
} | ||
@@ -30,3 +30,3 @@ } | ||
export function evaluateGap(row, field, gap) { | ||
export function evaluateGap(row, field, gap, interpolator) { | ||
const { rows, start } = gap; | ||
@@ -40,3 +40,3 @@ const fieldVal = row[field]; | ||
if (rows.length > 0) { | ||
interpolateGap(rows, start, row, field); | ||
interpolateGap(rows, start, row, field, interpolator); | ||
rows.length = 0; | ||
@@ -48,6 +48,6 @@ } | ||
function interpolateGap(gapRows, startRow, endRow, field) { | ||
function interpolateGap(gapRows, startRow, endRow, field, interpolator = d3.interpolate) { | ||
const startVal = startRow[field]; | ||
const endVal = endRow[field]; | ||
const int = d3.interpolate(startVal, endVal); | ||
const int = interpolator(startVal, endVal); | ||
const delta = 1 / (gapRows.length+1); | ||
@@ -65,3 +65,3 @@ let mu = 0; | ||
export function interpolateGroup(group, { fields = group.fields, ammendNewRow = () => {} } = {}) { | ||
export function interpolateGroup(group, { fields = group.fields, interpolators = {}, ammendNewRow = () => {} } = {}) { | ||
@@ -105,3 +105,3 @@ // what fields to interpolate? | ||
const endRow = group.get(frameKeys[i]).get(markerKey); | ||
interpolateGap(gapRows, startRow, endRow, field); | ||
interpolateGap(gapRows, startRow, endRow, field, interpolators[field]); | ||
} | ||
@@ -108,0 +108,0 @@ lastIndexPerMarker.set(markerKey, i); |
@@ -8,5 +8,5 @@ import { DataFrame } from "../dataFrame"; | ||
*/ | ||
export function interpolateBetween(from, to, mu) { | ||
export function interpolateBetween(from, to, mu, fields = from.fields, interpolators = {}) { | ||
const df = DataFrame([], from.key); | ||
let newRow, row2; | ||
@@ -19,4 +19,4 @@ for(const key of from.keys()) { | ||
newRow = Object.assign({}, row1); | ||
for (let field in newRow) { | ||
newRow[field] = d3.interpolate(row1[field], row2[field])(mu); | ||
for (let field of fields) { | ||
newRow[field] = (interpolators[field] || d3.interpolate)(row1[field], row2[field])(mu); | ||
} | ||
@@ -23,0 +23,0 @@ } else { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1226354
12830