Skip to content

Commit

Permalink
join(): skipGaps bools -> nullModes flags
Browse files Browse the repository at this point in the history
  • Loading branch information
leeoniya committed Dec 12, 2020
1 parent 6a5d658 commit e22339c
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 53 deletions.
7 changes: 4 additions & 3 deletions demos/align-data.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@
// console.log(tables);

console.time("align");
let { data, isGap } = uPlot.join(tables);
let nullModes = tables.map(t => t.map(s => 2));
let { data, isGap } = uPlot.join(tables, nullModes);
// console.log(nullModes);
console.timeEnd("align");

// console.log(data3);
Expand Down Expand Up @@ -114,14 +116,13 @@
console.timeEnd("align3");
}, 1000);
*/
/*

setInterval(() => {
u.series.forEach(s => {
s.spanGaps = !s.spanGaps;
});
u.redraw();
}, 1000);
*/
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion demos/path-gap-clip.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
]
];

let alignedDataWithGapTest10 = uPlot.join(tables10);
let alignedDataWithGapTest10 = uPlot.join(tables10, tables10.map(t => t.map(s => 2)));

const opts10 = {
width: 1200,
Expand Down
30 changes: 18 additions & 12 deletions dist/uPlot.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,12 +334,17 @@ function assign(targ) {
return targ;
}

// skipGaps is a tables-matched bool array indicating which series can skip storing indices of original nulls
function join(tables, skipGaps) {
// nullModes
var NULL_IGNORE = 0; // all nulls are ignored by isGap
var NULL_GAP = 1; // alignment nulls are ignored by isGap (default)
var NULL_EXPAND = 2; // nulls are expand to include adjacent alignment nulls

// nullModes is a tables-matched array indicating how to treat nulls in each series
function join(tables, nullModes) {
if (tables.length == 1) {
return {
data: tables[0],
isGap: skipGaps ? function (u, seriesIdx, dataIdx) { return !skipGaps[0][seriesIdx]; } : function () { return true; },
isGap: nullModes ? function (u, seriesIdx, dataIdx) { return nullModes[0][seriesIdx] != NULL_IGNORE; } : function () { return true; },
};
}

Expand All @@ -354,11 +359,12 @@ function join(tables, skipGaps) {
for (var i = 0; i < len; i++)
{ xVals.add(xs[i]); }

for (var si$1 = 1; si$1 < t.length; si$1++) {
for (var si = 1; si < t.length; si++) {
var nulls = new Set();

if (skipGaps == null || !skipGaps[ti][si$1]) {
var ys = t[si$1];
// cache original nulls for isGap lookup
if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
var ys = t[si];

for (var i$1 = 0; i$1 < len; i$1++) {
if (ys[i$1] == null)
Expand All @@ -379,23 +385,23 @@ function join(tables, skipGaps) {
for (var i$2 = 0; i$2 < alignedLen; i$2++)
{ xIdxs.set(data[0][i$2], i$2); }

var si = 1;
var gsi = 1;

for (var ti$1 = 0; ti$1 < tables.length; ti$1++) {
var t$1 = tables[ti$1];
var xs$1 = t$1[0];

for (var j = 1; j < t$1.length; j++) {
var ys$1 = t$1[j];
for (var si$1 = 1; si$1 < t$1.length; si$1++) {
var ys$1 = t$1[si$1];

var yVals = Array(alignedLen).fill(null);

for (var i$3 = 0; i$3 < ys$1.length; i$3++)
{ yVals[xIdxs.get(xs$1[i$3])] = ys$1[i$3]; }

// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
{
var nulls$1 = xNulls[si];
if (nullModes && nullModes[ti$1][si$1] == NULL_EXPAND) {
var nulls$1 = xNulls[gsi];
var size = nulls$1.size;
var i$4 = 0;
var xi = (void 0);
Expand Down Expand Up @@ -426,7 +432,7 @@ function join(tables, skipGaps) {

data.push(yVals);

si++;
gsi++;
}
}

Expand Down
13 changes: 11 additions & 2 deletions dist/uPlot.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,23 @@ declare class uPlot {
/** converts a Date into new Date that's time-adjusted for the given IANA Time Zone Name */
static tzDate(date: Date, tzName: string): Date;

/** outerJoins multiple data tables on table[0] values. providing skipGaps can avoid null-caching for any series.spanGaps = true */
static join(tables: AlignedData[], skipGaps?: boolean[][]): AlignedDataWithGapTest;
/** outerJoins multiple data tables on table[0] values */
static join(tables: AlignedData[], nullModes?: JoinNullMode[][]): AlignedDataWithGapTest;

static addGap: Series.AddGap;

static clipGaps: Series.ClipPathBuilder;
}

export const enum JoinNullMode {
/** use for series with spanGaps = true */
Ignore = 0,
/** default */
Gaps = 1,
/** expand explicit null gaps to include adjacent alignment nulls */
Expand = 2,
}

export const enum Orientation {
Horizontal = 0,
Vertical = 1,
Expand Down
26 changes: 16 additions & 10 deletions dist/uPlot.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,17 @@ function assign(targ) {
return targ;
}

// skipGaps is a tables-matched bool array indicating which series can skip storing indices of original nulls
function join(tables, skipGaps) {
// nullModes
const NULL_IGNORE = 0; // all nulls are ignored by isGap
const NULL_GAP = 1; // alignment nulls are ignored by isGap (default)
const NULL_EXPAND = 2; // nulls are expand to include adjacent alignment nulls

// nullModes is a tables-matched array indicating how to treat nulls in each series
function join(tables, nullModes) {
if (tables.length == 1) {
return {
data: tables[0],
isGap: skipGaps ? (u, seriesIdx, dataIdx) => !skipGaps[0][seriesIdx] : () => true,
isGap: nullModes ? (u, seriesIdx, dataIdx) => nullModes[0][seriesIdx] != NULL_IGNORE : () => true,
};
}

Expand All @@ -356,7 +361,8 @@ function join(tables, skipGaps) {
for (let si = 1; si < t.length; si++) {
let nulls = new Set();

if (skipGaps == null || !skipGaps[ti][si]) {
// cache original nulls for isGap lookup
if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
let ys = t[si];

for (let i = 0; i < len; i++) {
Expand All @@ -378,23 +384,23 @@ function join(tables, skipGaps) {
for (let i = 0; i < alignedLen; i++)
xIdxs.set(data[0][i], i);

let si = 1;
let gsi = 1;

for (let ti = 0; ti < tables.length; ti++) {
let t = tables[ti];
let xs = t[0];

for (let j = 1; j < t.length; j++) {
let ys = t[j];
for (let si = 1; si < t.length; si++) {
let ys = t[si];

let yVals = Array(alignedLen).fill(null);

for (let i = 0; i < ys.length; i++)
yVals[xIdxs.get(xs[i])] = ys[i];

// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
{
let nulls = xNulls[si];
if (nullModes && nullModes[ti][si] == NULL_EXPAND) {
let nulls = xNulls[gsi];
let size = nulls.size;
let i = 0;
let xi;
Expand Down Expand Up @@ -425,7 +431,7 @@ function join(tables, skipGaps) {

data.push(yVals);

si++;
gsi++;
}
}

Expand Down
30 changes: 18 additions & 12 deletions dist/uPlot.iife.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,12 +335,17 @@ var uPlot = (function () {
return targ;
}

// skipGaps is a tables-matched bool array indicating which series can skip storing indices of original nulls
function join(tables, skipGaps) {
// nullModes
var NULL_IGNORE = 0; // all nulls are ignored by isGap
var NULL_GAP = 1; // alignment nulls are ignored by isGap (default)
var NULL_EXPAND = 2; // nulls are expand to include adjacent alignment nulls

// nullModes is a tables-matched array indicating how to treat nulls in each series
function join(tables, nullModes) {
if (tables.length == 1) {
return {
data: tables[0],
isGap: skipGaps ? function (u, seriesIdx, dataIdx) { return !skipGaps[0][seriesIdx]; } : function () { return true; },
isGap: nullModes ? function (u, seriesIdx, dataIdx) { return nullModes[0][seriesIdx] != NULL_IGNORE; } : function () { return true; },
};
}

Expand All @@ -355,11 +360,12 @@ var uPlot = (function () {
for (var i = 0; i < len; i++)
{ xVals.add(xs[i]); }

for (var si$1 = 1; si$1 < t.length; si$1++) {
for (var si = 1; si < t.length; si++) {
var nulls = new Set();

if (skipGaps == null || !skipGaps[ti][si$1]) {
var ys = t[si$1];
// cache original nulls for isGap lookup
if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
var ys = t[si];

for (var i$1 = 0; i$1 < len; i$1++) {
if (ys[i$1] == null)
Expand All @@ -380,23 +386,23 @@ var uPlot = (function () {
for (var i$2 = 0; i$2 < alignedLen; i$2++)
{ xIdxs.set(data[0][i$2], i$2); }

var si = 1;
var gsi = 1;

for (var ti$1 = 0; ti$1 < tables.length; ti$1++) {
var t$1 = tables[ti$1];
var xs$1 = t$1[0];

for (var j = 1; j < t$1.length; j++) {
var ys$1 = t$1[j];
for (var si$1 = 1; si$1 < t$1.length; si$1++) {
var ys$1 = t$1[si$1];

var yVals = Array(alignedLen).fill(null);

for (var i$3 = 0; i$3 < ys$1.length; i$3++)
{ yVals[xIdxs.get(xs$1[i$3])] = ys$1[i$3]; }

// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
{
var nulls$1 = xNulls[si];
if (nullModes && nullModes[ti$1][si$1] == NULL_EXPAND) {
var nulls$1 = xNulls[gsi];
var size = nulls$1.size;
var i$4 = 0;
var xi = (void 0);
Expand Down Expand Up @@ -427,7 +433,7 @@ var uPlot = (function () {

data.push(yVals);

si++;
gsi++;
}
}

Expand Down
2 changes: 1 addition & 1 deletion dist/uPlot.iife.min.js

Large diffs are not rendered by default.

28 changes: 16 additions & 12 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,17 +322,20 @@ export function assign(targ) {
return targ;
}

// skipGaps is a tables-matched bool array indicating which series can skip storing indices of original nulls
export function join(tables, skipGaps) {
// nullModes
const NULL_IGNORE = 0; // all nulls are ignored by isGap
const NULL_GAP = 1; // alignment nulls are ignored by isGap (default)
const NULL_EXPAND = 2; // nulls are expand to include adjacent alignment nulls

// nullModes is a tables-matched array indicating how to treat nulls in each series
export function join(tables, nullModes) {
if (tables.length == 1) {
return {
data: tables[0],
isGap: skipGaps ? (u, seriesIdx, dataIdx) => !skipGaps[0][seriesIdx] : () => true,
isGap: nullModes ? (u, seriesIdx, dataIdx) => nullModes[0][seriesIdx] != NULL_IGNORE : () => true,
};
}

let growGaps = true;

let xVals = new Set();
let xNulls = [new Set()];

Expand All @@ -347,7 +350,8 @@ export function join(tables, skipGaps) {
for (let si = 1; si < t.length; si++) {
let nulls = new Set();

if (skipGaps == null || !skipGaps[ti][si]) {
// cache original nulls for isGap lookup
if (nullModes == null || nullModes[ti][si] == NULL_GAP || nullModes[ti][si] == NULL_EXPAND) {
let ys = t[si];

for (let i = 0; i < len; i++) {
Expand All @@ -369,23 +373,23 @@ export function join(tables, skipGaps) {
for (let i = 0; i < alignedLen; i++)
xIdxs.set(data[0][i], i);

let si = 1;
let gsi = 1;

for (let ti = 0; ti < tables.length; ti++) {
let t = tables[ti];
let xs = t[0];

for (let j = 1; j < t.length; j++) {
let ys = t[j];
for (let si = 1; si < t.length; si++) {
let ys = t[si];

let yVals = Array(alignedLen).fill(null);

for (let i = 0; i < ys.length; i++)
yVals[xIdxs.get(xs[i])] = ys[i];

// mark all filler nulls as explicit when adjacent to existing explicit nulls (minesweeper)
if (growGaps) {
let nulls = xNulls[si];
if (nullModes && nullModes[ti][si] == NULL_EXPAND) {
let nulls = xNulls[gsi];
let size = nulls.size;
let i = 0;
let xi;
Expand Down Expand Up @@ -416,7 +420,7 @@ export function join(tables, skipGaps) {

data.push(yVals);

si++;
gsi++;
}
}

Expand Down

0 comments on commit e22339c

Please sign in to comment.