@steelbreeze/landscape
Advanced tools
Comparing version 3.0.0-rc.1 to 3.0.0-rc.2
@@ -1,1 +0,1 @@ | ||
var landscape;(()=>{"use strict";var e={};(()=>{var a=e;function t(e){return Object.assign(Object.assign({},e),{rowSpan:1,colSpan:1})}function n(e,a){return e*a/s(e,a)}function s(e,a){return a?s(a,e%a):e}function c(e,a){const t=[];for(let n=0;n<e;n++)t.push(a(n));return t}Object.defineProperty(a,"__esModule",{value:!0}),a.merge=a.split=void 0,a.split=function(e,a,s,l,r){const o=e.map((e=>e.map((e=>e.length||1)))),p=o[0].map(((e,a)=>r?o.map((e=>e[a])).reduce(n):1));return o.map((e=>r?1:e.reduce(n))).reduce(((a,n,r)=>[...a,...c(n,(a=>p.reduce(((s,o,p)=>[...s,...c(o,(s=>{const c=e[r][p],u=Math.floor(c.length*(a+s)/(o*n));return t(c.length?l(c[u]):{text:"",className:"empty"})}))]),s[r].data.map((e=>t({className:`axis y ${e.key}`,text:e.value}))))))]),c(a[0].data.length,(e=>a.reduce(((a,n,s)=>[...a,...c(p[s],(()=>t({className:`axis x ${n.data[e].key}`,text:n.data[e].value})))]),s[0].data.map((()=>t({className:"axis xy",text:""})))))))},a.merge=function(e,a=!0,t=!0){let n;for(let s=e.length;s--;)for(let c=e[s].length;c--;){const l=e[s][c];t&&s&&(n=e[s-1][c])&&n.text===l.text&&n.className===l.className&&n.colSpan===l.colSpan?(n.rowSpan+=l.rowSpan,e[s].splice(c,1)):a&&c&&(n=e[s][c-1])&&n.text===l.text&&n.className===l.className&&n.rowSpan===l.rowSpan&&(n.colSpan+=l.colSpan,e[s].splice(c,1))}}})(),landscape=e})(); | ||
var landscape;(()=>{"use strict";var e={};(()=>{var a=e;function t(e,a){for(let t=e.length;t--;)a(e[t],t)}function n(e,a,t){return e.forEach(((e,n)=>t.push(...a(e,n)))),t}function c(e,a){const t=[];for(let n=0;n<e;n++)t.push(a(n));return t}function s(e,a){return e*a/l(e,a)}function l(e,a){return a?l(a,e%a):e}function r(e){return Object.assign(Object.assign({},e),{rowSpan:1,colSpan:1})}Object.defineProperty(a,"__esModule",{value:!0}),a.merge=a.table=void 0,a.table=function(e,a,t,l,o){const u=c(a.length,(a=>o?e.map((e=>e[a].length||1)).reduce(s):1));return n(e.map((e=>e.map((e=>o?1:e.length||1)).reduce(s))),((a,s)=>c(a,(o=>n(u,((t,n)=>c(t,(c=>{const u=e[s][n],p=Math.floor(u.length*(o+c)/(t*a));return r(u.length?l(u[p]):{text:"",className:"empty"})}))),t[s].data.map((e=>r({className:`axis y ${e.key}`,text:e.value}))))))),c(a[0].data.length,(e=>n(u,((t,n)=>c(t,(()=>r({className:`axis x ${a[n].data[e].key}`,text:a[n].data[e].value})))),t[0].data.map((()=>r({className:"axis xy",text:""})))))))},a.merge=function(e,a=!0,n=!0){let c;t(e,((s,l)=>{t(s,((t,r)=>{n&&l&&(c=e[l-1][r])&&c.text===t.text&&c.className===t.className&&c.colSpan===t.colSpan?(c.rowSpan+=t.rowSpan,s.splice(r,1)):a&&r&&(c=s[r-1])&&c.text===t.text&&c.className===t.className&&c.rowSpan===t.rowSpan&&(c.colSpan+=t.colSpan,s.splice(r,1))}))}))}})(),landscape=e})(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.merge = exports.split = void 0; | ||
function split(cube, xAxis, yAxis, getKey, onX) { | ||
const counts = cube.map(row => row.map(cell => cell.length || 1)); | ||
const xSplits = counts[0].map((_, index) => onX ? counts.map(row => row[index]).reduce(leastCommonMultiple) : 1); | ||
const ySplits = counts.map(row => onX ? 1 : row.reduce(leastCommonMultiple)); | ||
return ySplits.reduce((result, ySplit, yIndex) => [...result, ...generate(ySplit, nyi => xSplits.reduce((result, xSplit, xIndex) => [...result, ...generate(xSplit, nxi => { | ||
const table = cube[yIndex][xIndex]; | ||
const index = Math.floor(table.length * (nyi + nxi) / (xSplit * ySplit)); | ||
return cell(table.length ? getKey(table[index]) : { text: '', className: 'empty' }); | ||
})], yAxis[yIndex].data.map(pair => cell({ className: `axis y ${pair.key}`, text: pair.value }))))], generate(xAxis[0].data.length, row => xAxis.reduce((res, measure, index) => [...res, ...generate(xSplits[index], () => cell({ className: `axis x ${measure.data[row].key}`, text: measure.data[row].value }))], yAxis[0].data.map(() => cell({ className: 'axis xy', text: '' }))))); | ||
} | ||
exports.split = split; | ||
exports.merge = exports.table = void 0; | ||
/** | ||
* Creates a cell within a table | ||
* @hidden | ||
* Generates a table from a cube and its axis. | ||
* @param cube The source cube. | ||
* @param xAxis The x axis. | ||
* @param yAxis The y axis. | ||
* @param getKey A callback to generate a key containing the text and className used in the table from the source records, | ||
* @param onX A flag to indicate if cells in cube containing multiple values should be split on the x axis (if not, the y axis will be used). | ||
*/ | ||
function cell(key) { | ||
return Object.assign(Object.assign({}, key), { rowSpan: 1, colSpan: 1 }); | ||
function table(cube, xAxis, yAxis, getKey, onX) { | ||
// for each row and column, determine how many sub rows and columns we need to split it into; this is the LCM of the counts of items in that row or column | ||
const xSplits = generate(xAxis.length, index => onX ? cube.map(row => row[index].length || 1).reduce(leastCommonMultiple) : 1); | ||
const ySplits = cube.map(row => row.map(table => onX ? 1 : table.length || 1).reduce(leastCommonMultiple)); | ||
// generate the table from the cube, split cell with more than one value by row or column based on the splits calculated | ||
return expand(ySplits, (ySplit, yIndex) => generate(ySplit, nyi => expand(xSplits, (xSplit, xIndex) => generate(xSplit, nxi => { | ||
const table = cube[yIndex][xIndex]; | ||
const index = Math.floor(table.length * (nyi + nxi) / (xSplit * ySplit)); | ||
return cell(table.length ? getKey(table[index]) : { text: '', className: 'empty' }); | ||
}), yAxis[yIndex].data.map(pair => cell({ className: `axis y ${pair.key}`, text: pair.value })))), generate(xAxis[0].data.length, row => expand(xSplits, (xSplit, xIndex) => generate(xSplit, () => cell({ className: `axis x ${xAxis[xIndex].data[row].key}`, text: xAxis[xIndex].data[row].value })), yAxis[0].data.map(() => cell({ className: 'axis xy', text: '' }))))); | ||
} | ||
exports.table = table; | ||
/** | ||
@@ -30,30 +32,34 @@ * Merge adjacent cells in a split table on the y and/or x axes. | ||
let next; | ||
for (let iY = table.length; iY--;) { | ||
for (let iX = table[iY].length; iX--;) { | ||
const cell = table[iY][iX]; | ||
forReverse(table, (row, iY) => { | ||
forReverse(row, (cell, iX) => { | ||
if (onY && iY && (next = table[iY - 1][iX]) && next.text === cell.text && next.className === cell.className && next.colSpan === cell.colSpan) { | ||
next.rowSpan += cell.rowSpan; | ||
table[iY].splice(iX, 1); | ||
row.splice(iX, 1); | ||
} | ||
else if (onX && iX && (next = table[iY][iX - 1]) && next.text === cell.text && next.className === cell.className && next.rowSpan === cell.rowSpan) { | ||
else if (onX && iX && (next = row[iX - 1]) && next.text === cell.text && next.className === cell.className && next.rowSpan === cell.rowSpan) { | ||
next.colSpan += cell.colSpan; | ||
table[iY].splice(iX, 1); | ||
row.splice(iX, 1); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
exports.merge = merge; | ||
/** | ||
* Returns the least common multiple of two integers | ||
* Reverse for loop. | ||
* @hidden | ||
*/ | ||
function leastCommonMultiple(a, b) { | ||
return (a * b) / greatestCommonFactor(a, b); | ||
function forReverse(source, f) { | ||
// let index = source.length; | ||
// while(index--) { | ||
for (let index = source.length; index--;) { | ||
f(source[index], index); | ||
} | ||
} | ||
/** | ||
* Returns the greatest common factor of two numbers | ||
* Expand one array into another. | ||
* @hidden | ||
*/ | ||
function greatestCommonFactor(a, b) { | ||
return b ? greatestCommonFactor(b, a % b) : a; | ||
function expand(source, f, result) { | ||
source.forEach((value, index) => result.push(...f(value, index))); | ||
return result; | ||
} | ||
@@ -71,1 +77,22 @@ /** | ||
} | ||
/** | ||
* Returns the least common multiple of two integers | ||
* @hidden | ||
*/ | ||
function leastCommonMultiple(a, b) { | ||
return (a * b) / greatestCommonFactor(a, b); | ||
} | ||
/** | ||
* Returns the greatest common factor of two numbers | ||
* @hidden | ||
*/ | ||
function greatestCommonFactor(a, b) { | ||
return b ? greatestCommonFactor(b, a % b) : a; | ||
} | ||
/** | ||
* Creates a cell within a table, augmenting a key with row and column span detail | ||
* @hidden | ||
*/ | ||
function cell(key) { | ||
return Object.assign(Object.assign({}, key), { rowSpan: 1, colSpan: 1 }); | ||
} |
@@ -1,1 +0,1 @@ | ||
var landscape;(()=>{"use strict";var e={};(()=>{var a=e;function t(e){return Object.assign(Object.assign({},e),{rowSpan:1,colSpan:1})}function n(e,a){return e*a/s(e,a)}function s(e,a){return a?s(a,e%a):e}function c(e,a){const t=[];for(let n=0;n<e;n++)t.push(a(n));return t}Object.defineProperty(a,"__esModule",{value:!0}),a.merge=a.split=void 0,a.split=function(e,a,s,l,r){const o=e.map((e=>e.map((e=>e.length||1)))),p=o[0].map(((e,a)=>r?o.map((e=>e[a])).reduce(n):1));return o.map((e=>r?1:e.reduce(n))).reduce(((a,n,r)=>[...a,...c(n,(a=>p.reduce(((s,o,p)=>[...s,...c(o,(s=>{const c=e[r][p],u=Math.floor(c.length*(a+s)/(o*n));return t(c.length?l(c[u]):{text:"",className:"empty"})}))]),s[r].data.map((e=>t({className:`axis y ${e.key}`,text:e.value}))))))]),c(a[0].data.length,(e=>a.reduce(((a,n,s)=>[...a,...c(p[s],(()=>t({className:`axis x ${n.data[e].key}`,text:n.data[e].value})))]),s[0].data.map((()=>t({className:"axis xy",text:""})))))))},a.merge=function(e,a=!0,t=!0){let n;for(let s=e.length;s--;)for(let c=e[s].length;c--;){const l=e[s][c];t&&s&&(n=e[s-1][c])&&n.text===l.text&&n.className===l.className&&n.colSpan===l.colSpan?(n.rowSpan+=l.rowSpan,e[s].splice(c,1)):a&&c&&(n=e[s][c-1])&&n.text===l.text&&n.className===l.className&&n.rowSpan===l.rowSpan&&(n.colSpan+=l.colSpan,e[s].splice(c,1))}}})(),landscape=e})(); | ||
var landscape;(()=>{"use strict";var e={};(()=>{var a=e;function t(e,a){for(let t=e.length;t--;)a(e[t],t)}function n(e,a,t){return e.forEach(((e,n)=>t.push(...a(e,n)))),t}function c(e,a){const t=[];for(let n=0;n<e;n++)t.push(a(n));return t}function s(e,a){return e*a/l(e,a)}function l(e,a){return a?l(a,e%a):e}function r(e){return Object.assign(Object.assign({},e),{rowSpan:1,colSpan:1})}Object.defineProperty(a,"__esModule",{value:!0}),a.merge=a.table=void 0,a.table=function(e,a,t,l,o){const u=c(a.length,(a=>o?e.map((e=>e[a].length||1)).reduce(s):1));return n(e.map((e=>e.map((e=>o?1:e.length||1)).reduce(s))),((a,s)=>c(a,(o=>n(u,((t,n)=>c(t,(c=>{const u=e[s][n],p=Math.floor(u.length*(o+c)/(t*a));return r(u.length?l(u[p]):{text:"",className:"empty"})}))),t[s].data.map((e=>r({className:`axis y ${e.key}`,text:e.value}))))))),c(a[0].data.length,(e=>n(u,((t,n)=>c(t,(()=>r({className:`axis x ${a[n].data[e].key}`,text:a[n].data[e].value})))),t[0].data.map((()=>r({className:"axis xy",text:""})))))))},a.merge=function(e,a=!0,n=!0){let c;t(e,((s,l)=>{t(s,((t,r)=>{n&&l&&(c=e[l-1][r])&&c.text===t.text&&c.className===t.className&&c.colSpan===t.colSpan?(c.rowSpan+=t.rowSpan,s.splice(r,1)):a&&r&&(c=s[r-1])&&c.text===t.text&&c.className===t.className&&c.rowSpan===t.rowSpan&&(c.colSpan+=t.colSpan,s.splice(r,1))}))}))}})(),landscape=e})(); |
{ | ||
"name": "@steelbreeze/landscape", | ||
"version": "3.0.0-rc.1", | ||
"version": "3.0.0-rc.2", | ||
"description": "Landscape map viewpoint visualisation", | ||
@@ -5,0 +5,0 @@ "main": "lib/node/index.js", |
// @steelbreeze/landscape | ||
// Copyright (c) 2019-21 David Mesquita-Morris | ||
import { Cube, Dimension, Func1, Row } from '@steelbreeze/pivot'; | ||
import { Cube, Dimension, Func1, Func2, Row } from '@steelbreeze/pivot'; | ||
/** | ||
* The final text and class name to use when rendering cells in a table. | ||
*/ | ||
/** The final text and class name to use when rendering cells in a table. */ | ||
export interface Key { | ||
@@ -16,5 +14,3 @@ /** The text to use in the final table rendering. */ | ||
/** | ||
* An extension of key, adding the number of rows and columns the key will occupy in the final table rendering. | ||
*/ | ||
/** An extension of key, adding the number of rows and columns the key will occupy in the final table rendering. */ | ||
export interface Cell extends Key { | ||
@@ -28,22 +24,25 @@ /** The number of rows to occupy. */ | ||
export function split<TRow extends Row>(cube: Cube<TRow>, xAxis: Dimension<TRow>, yAxis: Dimension<TRow>, getKey: Func1<TRow, Key>, onX: boolean): Cell[][] { | ||
const counts = cube.map(row => row.map(cell => cell.length || 1)); | ||
const xSplits = counts[0].map((_, index) => onX ? counts.map(row => row[index]).reduce(leastCommonMultiple) : 1); | ||
const ySplits = counts.map(row => onX ? 1 : row.reduce(leastCommonMultiple)); | ||
/** | ||
* Generates a table from a cube and its axis. | ||
* @param cube The source cube. | ||
* @param xAxis The x axis. | ||
* @param yAxis The y axis. | ||
* @param getKey A callback to generate a key containing the text and className used in the table from the source records, | ||
* @param onX A flag to indicate if cells in cube containing multiple values should be split on the x axis (if not, the y axis will be used). | ||
*/ | ||
export function table<TRow extends Row>(cube: Cube<TRow>, xAxis: Dimension<TRow>, yAxis: Dimension<TRow>, getKey: Func1<TRow, Key>, onX: boolean): Array<Array<Cell>> { | ||
// for each row and column, determine how many sub rows and columns we need to split it into; this is the LCM of the counts of items in that row or column | ||
const xSplits = generate(xAxis.length, index => onX ? cube.map(row => row[index].length || 1).reduce(leastCommonMultiple) : 1); | ||
const ySplits = cube.map(row => row.map(table => onX ? 1 : table.length || 1).reduce(leastCommonMultiple)); | ||
return ySplits.reduce<Cell[][]>((result, ySplit, yIndex) => [...result, ...generate(ySplit, nyi => xSplits.reduce<Cell[]>((result, xSplit, xIndex) => [...result, ...generate(xSplit, nxi => { | ||
// generate the table from the cube, split cell with more than one value by row or column based on the splits calculated | ||
return expand(ySplits, (ySplit, yIndex) => generate(ySplit, nyi => expand(xSplits, (xSplit, xIndex) => generate(xSplit, nxi => { | ||
const table = cube[yIndex][xIndex]; | ||
const index = Math.floor(table.length * (nyi + nxi) / (xSplit * ySplit)); | ||
return cell(table.length ? getKey(table[index]) : { text: '', className: 'empty' }); | ||
})], yAxis[yIndex].data.map(pair => cell({ className: `axis y ${pair.key}`, text: pair.value }))))], generate(xAxis[0].data.length, row => xAxis.reduce<Cell[]>((res, measure, index) => [...res, ...generate(xSplits[index], () => cell({ className: `axis x ${measure.data[row].key}`, text: measure.data[row].value }))], yAxis[0].data.map(() => cell({ className: 'axis xy', text: '' }))))); | ||
}), yAxis[yIndex].data.map(pair => cell({ className: `axis y ${pair.key}`, text: pair.value })))), generate(xAxis[0].data.length, row => expand(xSplits, (xSplit, xIndex) => generate(xSplit, () => cell({ className: `axis x ${xAxis[xIndex].data[row].key}`, text: xAxis[xIndex].data[row].value })), yAxis[0].data.map(() => cell({ className: 'axis xy', text: '' }))))); | ||
} | ||
/** | ||
* Creates a cell within a table | ||
* @hidden | ||
*/ | ||
function cell(key: Key): Cell { | ||
return { ...key, rowSpan: 1, colSpan: 1 }; | ||
} | ||
/** | ||
* Merge adjacent cells in a split table on the y and/or x axes. | ||
@@ -57,16 +56,24 @@ * @param table A table of Cells created by a previous call to splitX or splitY. | ||
for (let iY = table.length; iY--;) { | ||
for (let iX = table[iY].length; iX--;) { | ||
const cell = table[iY][iX]; | ||
forReverse(table, (row, iY) => { | ||
forReverse(row, (cell, iX) => { | ||
if (onY && iY && (next = table[iY - 1][iX]) && next.text === cell.text && next.className === cell.className && next.colSpan === cell.colSpan) { | ||
next.rowSpan += cell.rowSpan; | ||
table[iY].splice(iX, 1); | ||
} else if (onX && iX && (next = table[iY][iX - 1]) && next.text === cell.text && next.className === cell.className && next.rowSpan === cell.rowSpan) { | ||
row.splice(iX, 1); | ||
} else if (onX && iX && (next = row[iX - 1]) && next.text === cell.text && next.className === cell.className && next.rowSpan === cell.rowSpan) { | ||
next.colSpan += cell.colSpan; | ||
table[iY].splice(iX, 1); | ||
row.splice(iX, 1); | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
/** | ||
* Reverse for loop. | ||
* @hidden | ||
*/ | ||
function forReverse<TSource>(source: Array<TSource>, f: Func2<TSource, number, void>): void { | ||
for (let index = source.length; index--;) { | ||
f(source[index], index); | ||
} | ||
@@ -76,2 +83,26 @@ } | ||
/** | ||
* Expand one array into another. | ||
* @hidden | ||
*/ | ||
function expand<TSource, TResult>(source: Array<TSource>, f: Func2<TSource, number, Array<TResult>>, result: Array<TResult>): Array<TResult> { | ||
source.forEach((value, index) => result.push(...f(value, index))); | ||
return result; | ||
} | ||
/** | ||
* Create any array of numbers from 0 to n | ||
* @hidden | ||
*/ | ||
function generate<TResult>(length: number, generator: Func1<number, TResult>): Array<TResult> { | ||
const result = []; | ||
for (let i = 0; i < length; i++) { | ||
result.push(generator(i)); | ||
} | ||
return result; | ||
} | ||
/** | ||
* Returns the least common multiple of two integers | ||
@@ -93,13 +124,7 @@ * @hidden | ||
/** | ||
* Create any array of numbers from 0 to n | ||
* Creates a cell within a table, augmenting a key with row and column span detail | ||
* @hidden | ||
*/ | ||
function generate<TResult>(length: number, generator: Func1<number, TResult>): Array<TResult> { | ||
const result = []; | ||
for (let i = 0; i < length; i++) { | ||
result.push(generator(i)); | ||
} | ||
return result; | ||
function cell(key: Key): Cell { | ||
return { ...key, rowSpan: 1, colSpan: 1 }; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
431157
3994