update arquero library to v4+ & fix layout alignment (#15)
* fix footer layout * update arquero and components using it * fix get values from column at index with new arquero * fix selecting an item on search * creates loader when searching * removed unused file change * fix lint & .gitignore * use updated ts & updates example files * fix useDebounce onChange and onSearch * fix packages * fix types & webpack * removed general import of arquero
This commit is contained in:
Родитель
094bbc9dce
Коммит
35315242bd
|
@ -27,3 +27,5 @@ yarn-error.log*
|
|||
!.yarn/plugins
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
public/data/msft*
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-d3-scale-npm-2.2.6-d18cd56795-ba4bd7e099.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-d3-scale-npm-2.2.6-d18cd56795-ba4bd7e099.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-d3-selection-npm-2.0.1-81a3e6c54d-23a337564e.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-d3-selection-npm-2.0.1-81a3e6c54d-23a337564e.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-flatbuffers-npm-1.10.0-0aae837bc1-f6665700a8.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-flatbuffers-npm-1.10.0-0aae837bc1-f6665700a8.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-node-npm-12.20.37-9ce6eac5c0-8c8b12f802.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-node-npm-12.20.37-9ce6eac5c0-8c8b12f802.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-node-npm-14.18.0-090dae09d8-b120c26fe5.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-node-npm-14.18.0-090dae09d8-b120c26fe5.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-react-dom-npm-16.9.14-758ab4d1e1-68a4ee88f7.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-react-dom-npm-16.9.14-758ab4d1e1-68a4ee88f7.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-react-npm-16.14.21-7ae562f957-9660ea0a2c.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-react-npm-16.14.21-7ae562f957-9660ea0a2c.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/@types-text-encoding-utf-8-npm-1.0.2-d39a8dfdeb-a7199bb5c0.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/@types-text-encoding-utf-8-npm-1.0.2-d39a8dfdeb-a7199bb5c0.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/apache-arrow-npm-3.0.0-e45ffe1a93-2ebd5e76d7.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/apache-arrow-npm-3.0.0-e45ffe1a93-2ebd5e76d7.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/command-line-args-npm-5.0.2-6a7d7bfe5d-fc239cc262.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/command-line-args-npm-5.0.2-6a7d7bfe5d-fc239cc262.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/command-line-usage-npm-5.0.5-29cebea723-d636200649.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/command-line-usage-npm-5.0.5-29cebea723-d636200649.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/find-replace-npm-2.0.1-3aaa403567-8eaa35d2a1.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/find-replace-npm-2.0.1-3aaa403567-8eaa35d2a1.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/flatbuffers-npm-1.11.0-b1e0cd4a49-1248894094.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/flatbuffers-npm-1.11.0-b1e0cd4a49-1248894094.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/json-bignum-npm-0.0.3-2b08f05834-e64b69089f.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/json-bignum-npm-0.0.3-2b08f05834-e64b69089f.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/lodash.camelcase-npm-4.3.0-bf268e3bf0-cb9227612f.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/lodash.camelcase-npm-4.3.0-bf268e3bf0-cb9227612f.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/lodash.padend-npm-4.6.1-6a28392d72-c2e6e789de.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/lodash.padend-npm-4.6.1-6a28392d72-c2e6e789de.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/re-resizable-npm-6.9.1-79ca365a45-b164f6b956.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/re-resizable-npm-6.9.1-79ca365a45-b164f6b956.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/reduce-flatten-npm-1.0.1-63b2c5a753-5e5a450500.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/reduce-flatten-npm-1.0.1-63b2c5a753-5e5a450500.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/table-layout-npm-0.4.5-1ffc9a985b-9642b67d1b.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/table-layout-npm-0.4.5-1ffc9a985b-9642b67d1b.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/text-encoding-utf-8-npm-1.0.2-d3a9fb552b-ec4c15d50e.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/text-encoding-utf-8-npm-1.0.2-d3a9fb552b-ec4c15d50e.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
.yarn/cache/webidl-conversions-npm-3.0.1-60310f6a2b-c92a0a6ab9.zip
поставляемый
Normal file
Двоичные данные
.yarn/cache/webidl-conversions-npm-3.0.1-60310f6a2b-c92a0a6ab9.zip
поставляемый
Normal file
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -51,7 +51,7 @@
|
|||
"@types/react-rnd": "^8.0.0",
|
||||
"@yarnpkg/pnpify": "^2.4.0",
|
||||
"ahooks": "^2.10.6",
|
||||
"arquero": "^0.13.3",
|
||||
"arquero": "^4.8.4",
|
||||
"core-js": "^3.12.0",
|
||||
"d3-array": "^2.8.0",
|
||||
"d3-brush": "2",
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -3,7 +3,8 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { extension } from './util'
|
||||
import { fromCSV, table } from 'arquero'
|
||||
import { fromCSV } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
const identity = (d: any) => d
|
||||
|
||||
|
@ -23,12 +24,12 @@ const fns = {
|
|||
target: identity,
|
||||
}
|
||||
|
||||
export async function fetchDSVTable(url: string) {
|
||||
export async function fetchDSVTable(url: string): Promise<ColumnTable> {
|
||||
const content = await fetch(url).then(res => res.text())
|
||||
return parseDSVTable(url, content)
|
||||
}
|
||||
|
||||
export function parseDSVTable(filename: string, content: string): table {
|
||||
export function parseDSVTable(filename: string, content: string): ColumnTable {
|
||||
const ext = extension(filename)
|
||||
const table = fromCSV(content, {
|
||||
header: true,
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
*/
|
||||
import { fetchDSVTable } from './dsv'
|
||||
import { extension } from './util'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
/**
|
||||
* Fetch a file visible to the application in csv or tsv format,
|
||||
* such as from the public folder or any other no-auth url
|
||||
* @param url
|
||||
*/
|
||||
export async function fetchUrl(url: string) {
|
||||
export async function fetchUrl(url: string): Promise<ColumnTable> {
|
||||
const ext = extension(url)
|
||||
switch (ext) {
|
||||
case 'csv':
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
export interface ArqueroTableProps {
|
||||
table: table
|
||||
table: ColumnTable
|
||||
/**
|
||||
* Direct pass-through to Arquero table options
|
||||
*/
|
||||
|
@ -36,7 +36,8 @@ export const ArqueroTable: React.FC<ArqueroTableProps> = ({
|
|||
thead: 'display:none;',
|
||||
}
|
||||
}
|
||||
return table.toHTML(opts)
|
||||
|
||||
return table.toHTML()
|
||||
}, [table, options, hideHeaders])
|
||||
return <div style={style} dangerouslySetInnerHTML={{ __html: html }} />
|
||||
}
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { Community, Edge, ItemType, Node, TableBackedItem } from '../types'
|
||||
import { table as createTable, table } from 'arquero'
|
||||
//importing as aqtable because there's already a param named table in this file
|
||||
import { table as aqtable } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { TableData } from 'arquero/dist/types/table/table'
|
||||
|
||||
class TableItemFacade implements TableBackedItem {
|
||||
private _table: table
|
||||
private _table: ColumnTable
|
||||
private _index: number
|
||||
private _id: string
|
||||
constructor(table: table, index: number, prefix: ItemType) {
|
||||
constructor(table: ColumnTable, index: number, prefix: ItemType) {
|
||||
this._table = table
|
||||
this._index = index
|
||||
this._id = `${prefix}.id`
|
||||
|
@ -21,7 +24,7 @@ class TableItemFacade implements TableBackedItem {
|
|||
return this._table.columnNames()
|
||||
}
|
||||
get(col: string) {
|
||||
return this._table.get(col, this._index)
|
||||
return this._table.column(col)?.get(this._index)
|
||||
}
|
||||
get id() {
|
||||
return this.get(this._id)
|
||||
|
@ -29,7 +32,7 @@ class TableItemFacade implements TableBackedItem {
|
|||
}
|
||||
|
||||
class NodeFacade extends TableItemFacade implements Node {
|
||||
constructor(table: table, index: number) {
|
||||
constructor(table: ColumnTable, index: number) {
|
||||
super(table, index, 'node')
|
||||
}
|
||||
get x() {
|
||||
|
@ -44,7 +47,7 @@ class NodeFacade extends TableItemFacade implements Node {
|
|||
}
|
||||
|
||||
class CommunityFacade extends TableItemFacade implements Community {
|
||||
constructor(table: table, index: number) {
|
||||
constructor(table: ColumnTable, index: number) {
|
||||
super(table, index, 'community')
|
||||
}
|
||||
get pid() {
|
||||
|
@ -59,7 +62,7 @@ class CommunityFacade extends TableItemFacade implements Community {
|
|||
}
|
||||
|
||||
class EdgeFacade extends TableItemFacade implements Edge {
|
||||
constructor(table: table, index: number) {
|
||||
constructor(table: ColumnTable, index: number) {
|
||||
super(table, index, 'edge')
|
||||
}
|
||||
get source() {
|
||||
|
@ -76,11 +79,15 @@ class EdgeFacade extends TableItemFacade implements Edge {
|
|||
type Callback<T> = (item: T, index: number) => any
|
||||
|
||||
export class TableCollection<T> {
|
||||
private _table: table = createTable()
|
||||
private _table: ColumnTable = aqtable({})
|
||||
private _prefix: string
|
||||
private _Ctor: any
|
||||
private _indices: Uint32Array | undefined
|
||||
constructor(table: table | undefined, prefix: string, indices?: Uint32Array) {
|
||||
private _indices: number[] | undefined
|
||||
constructor(
|
||||
table: ColumnTable | undefined,
|
||||
prefix: string,
|
||||
indices?: number[],
|
||||
) {
|
||||
if (table) {
|
||||
this._table = table
|
||||
}
|
||||
|
@ -102,7 +109,7 @@ export class TableCollection<T> {
|
|||
this._indices = indices
|
||||
}
|
||||
}
|
||||
get table(): table {
|
||||
get table(): ColumnTable {
|
||||
return this._table
|
||||
}
|
||||
get size(): number {
|
||||
|
@ -124,19 +131,21 @@ export class TableCollection<T> {
|
|||
const output: T[] = []
|
||||
this.scan(idx => {
|
||||
const n = new this._Ctor(this._table, idx, this._prefix)
|
||||
if (idx === undefined) return
|
||||
output.push(callback(n, idx))
|
||||
}, ordered)
|
||||
return output
|
||||
}
|
||||
forEach(callback: Callback<T>, ordered = false) {
|
||||
this.scan((idx: number) => {
|
||||
this.scan((idx: number | undefined) => {
|
||||
const n = new this._Ctor(this._table, idx)
|
||||
if (idx === undefined) return
|
||||
callback(n, idx)
|
||||
}, ordered)
|
||||
}
|
||||
toMap(): Map<string, T> {
|
||||
const map = new Map<string, T>()
|
||||
this.scan((idx: number) => {
|
||||
this.scan((idx: number | undefined) => {
|
||||
const n = new this._Ctor(this._table, idx)
|
||||
const id = n.id
|
||||
map.set(id, n)
|
||||
|
@ -145,7 +154,7 @@ export class TableCollection<T> {
|
|||
}
|
||||
toSet(): Set<T> {
|
||||
const set = new Set<T>()
|
||||
this.scan((idx: number) => {
|
||||
this.scan((idx: number | undefined) => {
|
||||
const n = new this._Ctor(this._table, idx)
|
||||
set.add(n)
|
||||
})
|
||||
|
@ -153,7 +162,7 @@ export class TableCollection<T> {
|
|||
}
|
||||
toArray(ordered = false): T[] {
|
||||
const arr: T[] = []
|
||||
this.scan((idx: number) => {
|
||||
this.scan((idx: number | undefined) => {
|
||||
arr.push(new this._Ctor(this._table, idx))
|
||||
}, ordered)
|
||||
return arr
|
||||
|
@ -175,8 +184,8 @@ export class TableCollection<T> {
|
|||
sample(proportion: number): T[] {
|
||||
const arr: T[] = []
|
||||
const ratio = Math.floor(1 / proportion)
|
||||
this.scan((idx: number) => {
|
||||
if (idx % ratio === 0) {
|
||||
this.scan((idx: number | undefined) => {
|
||||
if (idx !== undefined && idx % ratio === 0) {
|
||||
arr.push(new this._Ctor(this._table, idx))
|
||||
}
|
||||
})
|
||||
|
@ -192,7 +201,11 @@ export class TableCollection<T> {
|
|||
* @param ordered
|
||||
*/
|
||||
scan(
|
||||
callback: (row: number, data: any, stop: () => void) => void,
|
||||
callback: (
|
||||
row?: number | undefined,
|
||||
data?: TableData | any[] | undefined,
|
||||
stop?: (() => void) | undefined,
|
||||
) => void,
|
||||
ordered = false,
|
||||
) {
|
||||
// note that we assume provided indices are already ordered
|
||||
|
@ -211,19 +224,19 @@ export class TableCollection<T> {
|
|||
}
|
||||
|
||||
export class CommunityCollection extends TableCollection<Community> {
|
||||
constructor(table?: table, indices?: Uint32Array) {
|
||||
constructor(table?: ColumnTable, indices?: number[]) {
|
||||
super(table, 'community', indices)
|
||||
}
|
||||
}
|
||||
|
||||
export class NodeCollection extends TableCollection<Node> {
|
||||
constructor(table?: table, indices?: Uint32Array) {
|
||||
constructor(table?: ColumnTable, indices?: number[]) {
|
||||
super(table, 'node', indices)
|
||||
}
|
||||
}
|
||||
|
||||
export class EdgeCollection extends TableCollection<Edge> {
|
||||
constructor(table?: table, indices?: Uint32Array) {
|
||||
constructor(table?: ColumnTable, indices?: number[]) {
|
||||
super(table, 'edge', indices)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import { NodeCollection } from './TableCollection'
|
||||
import { findGroupIndices } from './table'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
/**
|
||||
* Gets a table of just the nodes for a matching community.
|
||||
|
@ -20,11 +21,11 @@ import { table } from 'arquero'
|
|||
*/
|
||||
export function findNodesTableForCommunity(
|
||||
cid: string | undefined,
|
||||
byParent: table,
|
||||
byCommunity: table,
|
||||
byParent: ColumnTable,
|
||||
byCommunity: ColumnTable,
|
||||
) {
|
||||
if (!cid) {
|
||||
return table()
|
||||
return table({})
|
||||
}
|
||||
|
||||
const pidx = findGroupIndices(byParent, 'community.pid', cid)
|
||||
|
@ -39,8 +40,8 @@ export function findNodesTableForCommunity(
|
|||
// this is duplicative of findNodesTableForCommunity, but retaining the indices allows us to avoid reify
|
||||
export function findNodesCollectionForCommunity(
|
||||
cid: string | undefined,
|
||||
byParent: table,
|
||||
byCommunity: table,
|
||||
byParent: ColumnTable,
|
||||
byCommunity: ColumnTable,
|
||||
) {
|
||||
if (!cid) {
|
||||
return new NodeCollection()
|
||||
|
@ -60,7 +61,7 @@ export function findNodesCollectionForCommunity(
|
|||
* @param pid
|
||||
* @param byParent
|
||||
*/
|
||||
export function findNodesTableForParent(pid: string, byParent: table) {
|
||||
export function findNodesTableForParent(pid: string, byParent: ColumnTable) {
|
||||
const pidx = findGroupIndices(byParent, 'community.pid', pid)
|
||||
return byParent.reify(pidx)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
*/
|
||||
import { NodeCollection } from './TableCollection'
|
||||
import { table, op, desc } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
export function getEdgesFromTableByID(
|
||||
selectedId: string,
|
||||
nodeTable: table,
|
||||
edges: table,
|
||||
nodeTable: ColumnTable,
|
||||
edges: ColumnTable,
|
||||
) {
|
||||
if (selectedId) {
|
||||
console.log('selected id', selectedId)
|
||||
|
@ -19,9 +20,12 @@ export function getEdgesFromTableByID(
|
|||
}
|
||||
|
||||
// joins the community ids for edge source/target into the edge table
|
||||
function joinNodeCommunities(edges: table, nodes: table): table {
|
||||
function joinNodeCommunities(
|
||||
edges: ColumnTable,
|
||||
nodes: ColumnTable,
|
||||
): ColumnTable {
|
||||
if (edges.numRows() === 0) {
|
||||
return table()
|
||||
return table({})
|
||||
}
|
||||
|
||||
const derived = edges
|
||||
|
@ -36,7 +40,7 @@ function joinNodeCommunities(edges: table, nodes: table): table {
|
|||
return derived
|
||||
}
|
||||
|
||||
function hashNodeField(nodes: table, field: string) {
|
||||
function hashNodeField(nodes: ColumnTable, field: string) {
|
||||
const hash: any = {}
|
||||
const id = nodes.getter('node.id')
|
||||
const cid = nodes.getter(field)
|
||||
|
@ -45,9 +49,13 @@ function hashNodeField(nodes: table, field: string) {
|
|||
}
|
||||
|
||||
// for a given community, finds all the connected sibling counts via edges
|
||||
function getNeighbors(selectedId: string, joined: table, nodes: table): table {
|
||||
function getNeighbors(
|
||||
selectedId: string,
|
||||
joined: ColumnTable,
|
||||
nodes: ColumnTable,
|
||||
): ColumnTable {
|
||||
if (joined.numRows() === 0 && nodes.numRows() === 0) {
|
||||
return table()
|
||||
return table({})
|
||||
}
|
||||
|
||||
const cFiltered = joined
|
||||
|
@ -86,7 +94,10 @@ function getNeighbors(selectedId: string, joined: table, nodes: table): table {
|
|||
* @param edges
|
||||
* @param nodes
|
||||
*/
|
||||
export function filterEdgesToNodes(edges: table, nodes: NodeCollection): table {
|
||||
export function filterEdgesToNodes(
|
||||
edges: ColumnTable,
|
||||
nodes: NodeCollection,
|
||||
): ColumnTable {
|
||||
if (edges.numRows() === 0) {
|
||||
return edges
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
} from './table'
|
||||
import { PositionMap } from '@graspologic/graph'
|
||||
import { not, table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import {
|
||||
useHoveredCommunity,
|
||||
|
@ -76,7 +77,7 @@ export function useArqueroAddTable() {
|
|||
const setBigTable = useSetArqueroBigTable()
|
||||
const setEdgeTable = useSetArqueroEdgeTable()
|
||||
return useCallback(
|
||||
(newTable: table, type: string) => {
|
||||
(newTable: ColumnTable, type: string) => {
|
||||
console.log('adding table/columns', type)
|
||||
newTable.print()
|
||||
let updated = bigTable
|
||||
|
@ -153,11 +154,11 @@ export function useEdgeCount() {
|
|||
return edges.numRows()
|
||||
}
|
||||
|
||||
export function useColumnStats(table: table, field?: string) {
|
||||
export function useColumnStats(table: ColumnTable, field?: string) {
|
||||
return useCachedColumnStats(table, field)
|
||||
}
|
||||
|
||||
export function useColumnHistogram(table: table, field?: string) {
|
||||
export function useColumnHistogram(table: ColumnTable, field?: string) {
|
||||
return useCachedColumnHistogram(table, field)
|
||||
}
|
||||
|
||||
|
@ -186,7 +187,7 @@ export function useArqueroVisibleCommunities() {
|
|||
.ungroup()
|
||||
return filtered
|
||||
}
|
||||
return table()
|
||||
return table({})
|
||||
}, [pid, communities])
|
||||
return useMemo(() => new CommunityCollection(tbl), [tbl])
|
||||
}
|
||||
|
@ -259,7 +260,7 @@ export function useTableColumnsByType(dataType: string) {
|
|||
const valueTable = bigTable.select(columns)
|
||||
return valueTable
|
||||
}
|
||||
return table()
|
||||
return table({})
|
||||
}
|
||||
|
||||
// for a list of communities, get a map of [cid]: nodepositions[]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
|
||||
export * from './communities'
|
||||
export * from './hooks'
|
||||
export * from './TableCollection'
|
||||
|
|
|
@ -3,26 +3,27 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { PositionMap } from '@graspologic/graph'
|
||||
import { desc, table } from 'arquero'
|
||||
import { desc } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
// TODO: we may want to provide fallback checks for
|
||||
// position columns, in the case that arbitrary non-layout data was
|
||||
// loaded by the user
|
||||
|
||||
function getters(table: table) {
|
||||
function getters(table: ColumnTable) {
|
||||
return {
|
||||
id: table.getter('node.id'),
|
||||
x: table.getter('node.x'),
|
||||
y: table.getter('node.y'),
|
||||
}
|
||||
}
|
||||
export function deriveLayoutPositions(table: table): PositionMap {
|
||||
export function deriveLayoutPositions(table: ColumnTable): PositionMap {
|
||||
const positions = {} as PositionMap
|
||||
if (table.numRows() === 0) {
|
||||
return positions
|
||||
}
|
||||
const { id, x, y } = getters(table)
|
||||
table.scan((idx: number) => {
|
||||
table.scan((idx: number | undefined) => {
|
||||
positions[id(idx)] = {
|
||||
x: x(idx),
|
||||
y: y(idx),
|
||||
|
@ -31,7 +32,7 @@ export function deriveLayoutPositions(table: table): PositionMap {
|
|||
return positions
|
||||
}
|
||||
|
||||
export function deriveSmallMultiplePositions(table: table): PositionMap {
|
||||
export function deriveSmallMultiplePositions(table: ColumnTable): PositionMap {
|
||||
const positions: PositionMap = {}
|
||||
if (table.numRows() === 0) {
|
||||
return positions
|
||||
|
@ -46,7 +47,8 @@ export function deriveSmallMultiplePositions(table: table): PositionMap {
|
|||
grouped
|
||||
.count()
|
||||
.orderby(desc('count'))
|
||||
.scan((idx: number) => {
|
||||
.scan((idx: number | undefined) => {
|
||||
if (idx === undefined) return
|
||||
const indices = partitions[idx]
|
||||
indices.forEach((index: number) => {
|
||||
positions[id(index)] = layout(cell, x(index), y(index))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// eslint-disable-next-line
|
||||
import { op, table } from 'arquero'
|
||||
import { op } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
export interface ArqueroNode {
|
||||
['node.id']: string
|
||||
|
@ -12,7 +13,7 @@ export interface ArqueroNode {
|
|||
* @param table assumed pre-grouped table (e.g., by parent id)
|
||||
* @param quantile
|
||||
*/
|
||||
export function getNodeStats(table: table, quantile = 1) {
|
||||
export function getNodeStats(table: ColumnTable, quantile = 1) {
|
||||
if (!table || table.numRows() === 0 || quantile === 1) {
|
||||
return [
|
||||
{
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
*/
|
||||
import { ROOT_COMMUNITY_ID } from '../constants'
|
||||
import { ColumnDef } from '../types'
|
||||
import { all, not, op, table } from 'arquero'
|
||||
import { all, not, op } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
/**
|
||||
* Extracts the objects from a single-row table.
|
||||
|
@ -14,7 +15,7 @@ import { all, not, op, table } from 'arquero'
|
|||
*/
|
||||
// TODO: this is pretty basic, but the intent would be to provide optional
|
||||
// transformers per column or as a whole
|
||||
export function one(table: table): { [key: string]: any } {
|
||||
export function one(table: ColumnTable): { [key: string]: any } {
|
||||
return table.objects()[0]
|
||||
}
|
||||
|
||||
|
@ -24,7 +25,7 @@ export function one(table: table): { [key: string]: any } {
|
|||
* @param prefix prefix to add to column names
|
||||
* @param exclude exclusion list if you want to retain some original columns
|
||||
*/
|
||||
export function rename(table: table, prefix: string, exclude?: string[]) {
|
||||
export function rename(table: ColumnTable, prefix: string, exclude?: string[]) {
|
||||
const ex = new Set(exclude)
|
||||
return table.columnNames().reduce((obj: any, name: string) => {
|
||||
if (ex.has(name) || name.startsWith(prefix)) {
|
||||
|
@ -36,11 +37,11 @@ export function rename(table: table, prefix: string, exclude?: string[]) {
|
|||
}, {})
|
||||
}
|
||||
|
||||
export function hasColumn(table: table, column: string) {
|
||||
export function hasColumn(table: ColumnTable, column: string) {
|
||||
return table.columnNames().some(name => name === column)
|
||||
}
|
||||
|
||||
export function columnTypes(table: table) {
|
||||
export function columnTypes(table: ColumnTable) {
|
||||
if (table.numRows() === 0) {
|
||||
return []
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ export function columnTypes(table: table) {
|
|||
}))
|
||||
}
|
||||
|
||||
export function recomputeCommunityStats(table: table, force?: boolean) {
|
||||
export function recomputeCommunityStats(table: ColumnTable, force?: boolean) {
|
||||
const selected = force
|
||||
? table.select(not(['community.nodeCount', 'community.childCount']))
|
||||
: table
|
||||
|
@ -70,10 +71,10 @@ export function recomputeCommunityStats(table: table, force?: boolean) {
|
|||
* @param fallback
|
||||
*/
|
||||
function ensureColumn(
|
||||
table: table,
|
||||
table: ColumnTable,
|
||||
name: string,
|
||||
variants: string[],
|
||||
fallback: (table: table) => table,
|
||||
fallback: (table: ColumnTable) => ColumnTable,
|
||||
) {
|
||||
if (hasColumn(table, name)) {
|
||||
return table
|
||||
|
@ -97,7 +98,7 @@ function ensureColumn(
|
|||
* In the worst case, we select the first column.
|
||||
* @param table
|
||||
*/
|
||||
function ensureNodeId(table: table) {
|
||||
function ensureNodeId(table: ColumnTable) {
|
||||
return ensureColumn(table, 'node.id', ['id', 'ID', 'nodeId'], table => {
|
||||
// just pick the first - this is risky, but sometimes we don't have a header at all
|
||||
const column = table.columnNames()[0]
|
||||
|
@ -113,7 +114,7 @@ function ensureNodeId(table: table) {
|
|||
* present we just default to '0' as an id
|
||||
* @param table
|
||||
*/
|
||||
function ensureCommunityId(table: table) {
|
||||
function ensureCommunityId(table: ColumnTable) {
|
||||
return ensureColumn(
|
||||
table,
|
||||
'community.id',
|
||||
|
@ -126,7 +127,7 @@ function ensureCommunityId(table: table) {
|
|||
)
|
||||
}
|
||||
|
||||
function ensureParentCommunityId(table: table) {
|
||||
function ensureParentCommunityId(table: ColumnTable) {
|
||||
return ensureColumn(
|
||||
table,
|
||||
'community.pid',
|
||||
|
@ -146,7 +147,7 @@ function ensureParentCommunityId(table: table) {
|
|||
// TEMP: make sure there are no empties, which some csvs have
|
||||
// use our -1 default.
|
||||
// TODO: use empty as default instead of -1, which need broader refactor
|
||||
function fixPid(table: table) {
|
||||
function fixPid(table: ColumnTable) {
|
||||
return table
|
||||
.params({
|
||||
pid: ROOT_COMMUNITY_ID,
|
||||
|
@ -156,7 +157,7 @@ function fixPid(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureX(table: table) {
|
||||
function ensureX(table: ColumnTable) {
|
||||
return ensureColumn(table, 'node.x', ['x', 'X'], table => {
|
||||
return table.derive({
|
||||
'node.x': () => Math.random(),
|
||||
|
@ -164,7 +165,7 @@ function ensureX(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureY(table: table) {
|
||||
function ensureY(table: ColumnTable) {
|
||||
return ensureColumn(table, 'node.y', ['y', 'Y'], table => {
|
||||
return table.derive({
|
||||
'node.y': () => Math.random(),
|
||||
|
@ -172,7 +173,7 @@ function ensureY(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureD(table: table) {
|
||||
function ensureD(table: ColumnTable) {
|
||||
return ensureColumn(table, 'node.d', ['d', 'D', 'size', 'weight'], table => {
|
||||
return table.derive({
|
||||
'node.d': () => 1,
|
||||
|
@ -180,7 +181,7 @@ function ensureD(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureNodeLabel(table: table) {
|
||||
function ensureNodeLabel(table: ColumnTable) {
|
||||
return ensureColumn(table, 'node.label', ['label', 'name'], table => {
|
||||
return table.derive({
|
||||
'node.label': (d: any) => d['node.id'],
|
||||
|
@ -188,7 +189,7 @@ function ensureNodeLabel(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureEdgeSource(table: table) {
|
||||
function ensureEdgeSource(table: ColumnTable) {
|
||||
return ensureColumn(table, 'edge.source', ['source', 'src'], table => {
|
||||
return table.derive({
|
||||
'edge.source': () => '0',
|
||||
|
@ -196,7 +197,7 @@ function ensureEdgeSource(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureEdgeTarget(table: table) {
|
||||
function ensureEdgeTarget(table: ColumnTable) {
|
||||
return ensureColumn(table, 'edge.target', ['target', 'tgt'], table => {
|
||||
return table.derive({
|
||||
'edge.target': () => '1',
|
||||
|
@ -204,7 +205,7 @@ function ensureEdgeTarget(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureEdgeWeight(table: table) {
|
||||
function ensureEdgeWeight(table: ColumnTable) {
|
||||
return ensureColumn(table, 'edge.weight', ['weight', 'value'], table => {
|
||||
return table.derive({
|
||||
'edge.weight': () => 1,
|
||||
|
@ -212,7 +213,7 @@ function ensureEdgeWeight(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function ensureEdgeId(table: table) {
|
||||
function ensureEdgeId(table: ColumnTable) {
|
||||
return ensureColumn(table, 'edge.id', ['id', 'edgeId'], table => {
|
||||
return table.derive({
|
||||
'edge.id': (d: any) => `${d['edge.source']}-${d['edge.target']}`,
|
||||
|
@ -221,7 +222,7 @@ function ensureEdgeId(table: table) {
|
|||
}
|
||||
|
||||
// normalizes x and y in a single operation because we need to maintain aspect ratio
|
||||
export function normalizeXY(table: table) {
|
||||
export function normalizeXY(table: ColumnTable) {
|
||||
const bounds = table.rollup({
|
||||
xMin: op.min('node.x'),
|
||||
xMax: op.max('node.x'),
|
||||
|
@ -246,7 +247,7 @@ export function normalizeXY(table: table) {
|
|||
})
|
||||
}
|
||||
|
||||
function normalizeD(table: table) {
|
||||
function normalizeD(table: ColumnTable) {
|
||||
// for the node size, the range should always be positive
|
||||
// we usually specify a minimum of 5 in the files - we do
|
||||
// not want those going to 0 once normalized, so here we
|
||||
|
@ -271,7 +272,7 @@ const prefixes = {
|
|||
// our current "data model" expects every column to have a type prefix
|
||||
// used for filtering views, etc.
|
||||
// this will find any unprefixed columns and add the specified one to them
|
||||
function prefixRemaining(table: table, prefix: string) {
|
||||
function prefixRemaining(table: ColumnTable, prefix: string) {
|
||||
const columns = table.columnNames(name => {
|
||||
const pref = name.split('.')[0]
|
||||
return !prefixes[pref]
|
||||
|
@ -289,7 +290,10 @@ function prefixRemaining(table: table, prefix: string) {
|
|||
* @param table
|
||||
* @param functions
|
||||
*/
|
||||
export function chain(table: table, functions: ((table: table) => table)[]) {
|
||||
export function chain(
|
||||
table: ColumnTable,
|
||||
functions: ((table: ColumnTable) => ColumnTable)[],
|
||||
) {
|
||||
return functions.reduce((acc, cur) => cur(acc), table)
|
||||
}
|
||||
|
||||
|
@ -298,7 +302,7 @@ export function chain(table: table, functions: ((table: table) => table)[]) {
|
|||
* @param table
|
||||
* @param type
|
||||
*/
|
||||
export function initializeNodeTable(table: table, fromEdges = false) {
|
||||
export function initializeNodeTable(table: ColumnTable, fromEdges = false) {
|
||||
const starter = fromEdges
|
||||
? table
|
||||
.fold(['source', 'target'])
|
||||
|
@ -323,11 +327,11 @@ export function initializeNodeTable(table: table, fromEdges = false) {
|
|||
])
|
||||
}
|
||||
|
||||
export function initializeJoinTable(table: table) {
|
||||
export function initializeJoinTable(table: ColumnTable) {
|
||||
return chain(table, [ensureNodeId, ensureCommunityId])
|
||||
}
|
||||
|
||||
export function initializeEdgeTable(table: table) {
|
||||
export function initializeEdgeTable(table: ColumnTable) {
|
||||
return chain(table, [
|
||||
ensureEdgeSource,
|
||||
ensureEdgeTarget,
|
||||
|
@ -337,14 +341,17 @@ export function initializeEdgeTable(table: table) {
|
|||
])
|
||||
}
|
||||
|
||||
export function initializeCommunityTable(table: table) {
|
||||
export function initializeCommunityTable(table: ColumnTable) {
|
||||
return chain(table, [
|
||||
ensureCommunityId,
|
||||
table => prefixRemaining(table, 'community'),
|
||||
])
|
||||
}
|
||||
|
||||
export function joinNodeCommunityTables(nodes: table, communities: table) {
|
||||
export function joinNodeCommunityTables(
|
||||
nodes: ColumnTable,
|
||||
communities: ColumnTable,
|
||||
) {
|
||||
const leftKey = 'node.id'
|
||||
const rightKey = 'node.id'
|
||||
|
||||
|
@ -379,8 +386,8 @@ export function joinNodeCommunityTables(nodes: table, communities: table) {
|
|||
* @param rightKey
|
||||
*/
|
||||
export function joinWithReplace(
|
||||
left: table,
|
||||
right: table,
|
||||
left: ColumnTable,
|
||||
right: ColumnTable,
|
||||
joinDefinition: any,
|
||||
) {
|
||||
return left.join(right, joinDefinition, [not(right.columnNames()), all()])
|
||||
|
@ -397,8 +404,8 @@ export function joinWithReplace(
|
|||
* @param rightKey optional explicit right key, otherwise it will use 'id'
|
||||
*/
|
||||
export function joinDataTables(
|
||||
left: table,
|
||||
right: table,
|
||||
left: ColumnTable,
|
||||
right: ColumnTable,
|
||||
type: string,
|
||||
leftKey?: string,
|
||||
rightKey = 'id',
|
||||
|
@ -420,8 +427,8 @@ export function joinDataTables(
|
|||
// and (b) auto-generate an incremental id if none appears present
|
||||
const toMerge = right
|
||||
// rename all new columns with their prefix except the id
|
||||
.select((table: table) => rename(table, `${type}.`, [rightKey]))
|
||||
.select((table: table) => table.columnNames(filter))
|
||||
.select((table: ColumnTable) => rename(table, `${type}.`, [rightKey]))
|
||||
.select((table: ColumnTable) => table.columnNames(filter))
|
||||
return left.join(toMerge, [joinKey, rightKey], [all(), not(rightKey)])
|
||||
}
|
||||
|
||||
|
@ -430,7 +437,7 @@ export function joinDataTables(
|
|||
* @param main current fully-populated table with joined communities
|
||||
* @param communities flat community list to rollup childCount
|
||||
*/
|
||||
export function checkAndAddChildCount(main: table) {
|
||||
export function checkAndAddChildCount(main: ColumnTable) {
|
||||
if (hasColumn(main, 'community.childCount')) {
|
||||
return main
|
||||
}
|
||||
|
@ -458,7 +465,7 @@ export function checkAndAddChildCount(main: table) {
|
|||
* This checks the main table for a community.nodeCount column and computes if missing
|
||||
* @param main current fully-populated table with joined communities
|
||||
*/
|
||||
export function checkAndAddNodeCount(main: table) {
|
||||
export function checkAndAddNodeCount(main: ColumnTable) {
|
||||
if (hasColumn(main, 'community.nodeCount')) {
|
||||
return main
|
||||
}
|
||||
|
@ -477,7 +484,7 @@ export function checkAndAddNodeCount(main: table) {
|
|||
* @param readOnlyNames
|
||||
*/
|
||||
export function listColumnDefs(
|
||||
table: table,
|
||||
table: ColumnTable,
|
||||
readOnlyNames?: Set<string>,
|
||||
): ColumnDef[] {
|
||||
if (table.numRows() === 0) {
|
||||
|
@ -491,12 +498,16 @@ export function listColumnDefs(
|
|||
}))
|
||||
}
|
||||
|
||||
export function listColumnNames(table: table): string[] {
|
||||
export function listColumnNames(table: ColumnTable): string[] {
|
||||
const defs = listColumnDefs(table)
|
||||
return defs.map(d => d.name)
|
||||
}
|
||||
|
||||
export function findGroupIndices(table: table, field: string, value: any) {
|
||||
export function findGroupIndices(
|
||||
table: ColumnTable,
|
||||
field: string,
|
||||
value: any,
|
||||
) {
|
||||
if (table.numRows() > 0) {
|
||||
const groups = table.groups()
|
||||
const index = groups.rows.findIndex(
|
||||
|
|
|
@ -7,10 +7,11 @@ import { TableCollection } from './TableCollection'
|
|||
import { one } from './table'
|
||||
import { histogram, Histogram } from '@essex-js-toolkit/toolbox'
|
||||
// eslint-disable-next-line
|
||||
import { op, table } from 'arquero'
|
||||
import { op } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { precisionFixed } from 'd3-format'
|
||||
|
||||
export function getColumnStats(table: table, name?: string): ColumnStats {
|
||||
export function getColumnStats(table: ColumnTable, name?: string): ColumnStats {
|
||||
if (!table || table.numRows() === 0 || table.numCols() === 0 || !name) {
|
||||
return {
|
||||
dataType: '',
|
||||
|
@ -32,7 +33,7 @@ export function getColumnStats(table: table, name?: string): ColumnStats {
|
|||
q05: op.quantile(name, 0.05),
|
||||
q95: op.quantile(name, 0.95),
|
||||
q99: op.quantile(name, 0.99),
|
||||
unique: op.unique(name),
|
||||
unique: op.array_agg_distinct(name),
|
||||
}),
|
||||
)
|
||||
|
||||
|
@ -62,7 +63,10 @@ function checkWhole(numbers?: number[]): boolean {
|
|||
return numbers.every(n => Number.isInteger(n))
|
||||
}
|
||||
|
||||
export function getColumnHistogram(table: table, name?: string): Histogram {
|
||||
export function getColumnHistogram(
|
||||
table: ColumnTable,
|
||||
name?: string,
|
||||
): Histogram {
|
||||
if (!table || table.numRows() === 0 || !name) {
|
||||
return []
|
||||
}
|
||||
|
@ -83,7 +87,7 @@ export function getColumnHistogram(table: table, name?: string): Histogram {
|
|||
* @param table
|
||||
* @param column
|
||||
*/
|
||||
export function binTableColumn(table: table, column: string): any[] {
|
||||
export function binTableColumn(table: ColumnTable, column: string): any[] {
|
||||
const quantileOps = new Array(100).fill(1).reduce((acc, cur, idx) => {
|
||||
acc[idx] = op.quantile(column, idx / 100)
|
||||
return acc
|
||||
|
@ -113,7 +117,7 @@ export function binTableColumn(table: table, column: string): any[] {
|
|||
})
|
||||
|
||||
// fill the bins
|
||||
table.scan((idx: number) => {
|
||||
table.scan((idx: number | undefined) => {
|
||||
const value = table.get(column, idx)
|
||||
const binIndex = bins.findIndex(bin => value >= bin.x0 && value < bin.x1)
|
||||
// bin maxes are exclusive except for the last bin
|
||||
|
|
|
@ -50,5 +50,4 @@ const Main = styled.div`
|
|||
height: 100%;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
`
|
||||
|
|
|
@ -41,14 +41,6 @@ export function useTestFiles(bundle: FileBundle) {
|
|||
|
||||
const files: FileBundle = {}
|
||||
|
||||
const [nodesTable, joinTable, communitiesTable, edgesTable] =
|
||||
await Promise.all([
|
||||
nodesFile?.url && fetchUrl(nodesFile.url),
|
||||
joinFile?.url && fetchUrl(joinFile.url),
|
||||
communitiesFile?.url && fetchUrl(communitiesFile.url),
|
||||
edgesFile?.url && fetchUrl(edgesFile.url),
|
||||
])
|
||||
|
||||
let nodes
|
||||
let edges
|
||||
|
||||
|
@ -57,6 +49,7 @@ export function useTestFiles(bundle: FileBundle) {
|
|||
// note that the order of nodes -> join -> communities -> edges is *required* to layer properly
|
||||
if (nodesFile) {
|
||||
console.log('loading nodes file from url', nodesFile.url)
|
||||
const nodesTable = await fetchUrl(nodesFile.url)
|
||||
console.time('nodes')
|
||||
nodes = initializeNodeTable(nodesTable)
|
||||
files.nodes = {
|
||||
|
@ -68,6 +61,7 @@ export function useTestFiles(bundle: FileBundle) {
|
|||
}
|
||||
if (joinFile) {
|
||||
console.log('loading join file from url', joinFile.url)
|
||||
const joinTable = await fetchUrl(joinFile.url)
|
||||
console.time('join')
|
||||
const join = initializeJoinTable(joinTable)
|
||||
files.join = {
|
||||
|
@ -82,6 +76,7 @@ export function useTestFiles(bundle: FileBundle) {
|
|||
}
|
||||
if (communitiesFile) {
|
||||
console.log('loading communities file from url', communitiesFile.url)
|
||||
const communitiesTable = await fetchUrl(communitiesFile.url)
|
||||
console.time('communities')
|
||||
files.communities = {
|
||||
...communitiesFile,
|
||||
|
@ -95,6 +90,7 @@ export function useTestFiles(bundle: FileBundle) {
|
|||
}
|
||||
if (edgesFile) {
|
||||
console.log('loading edges file from url', edgesFile.url)
|
||||
const edgesTable = await fetchUrl(edgesFile.url)
|
||||
console.time('edges')
|
||||
edges = initializeEdgeTable(edgesTable)
|
||||
files.edges = {
|
||||
|
|
|
@ -99,7 +99,7 @@ export const LeftSidePanel: React.FC<LeftSidePanelProps> = memo(
|
|||
</Text>
|
||||
</HeaderLabel>
|
||||
<CommunityPanelContainer tabIndex={0} style={communityPanelStyle}>
|
||||
{<CommunityPanel />}
|
||||
<CommunityPanel />
|
||||
</CommunityPanelContainer>
|
||||
</CommunityContainer>
|
||||
{miniMap}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
*/
|
||||
import { UmapLayout } from './UmapLayout'
|
||||
import { DefaultButton, Spinner, Toggle } from '@fluentui/react'
|
||||
import { all, not, table } from 'arquero'
|
||||
import { all, not } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { memo, useCallback, useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import {
|
||||
|
@ -27,7 +28,7 @@ export const Layout: React.FC = memo(function Layout() {
|
|||
const performLayout = useCallback(
|
||||
(type: LayoutType) => {
|
||||
console.log('performing layout', type)
|
||||
const finalize = (table: table) => {
|
||||
const finalize = (table: ColumnTable) => {
|
||||
console.log('layout complete', type)
|
||||
table.print()
|
||||
const merged = nodes.join(
|
||||
|
|
|
@ -70,22 +70,27 @@ export const SearchItems: React.FC<SearchItemsProps> = ({
|
|||
setSelectedCommunity('-1')
|
||||
} else {
|
||||
if (searchNodeTable) {
|
||||
const key = searchNodeTable.getter('node.id')
|
||||
let found
|
||||
const cols = listColumnDefs(searchNodeTable.table)
|
||||
searchNodeTable.scan((idx: number, data: any, stop: () => void) => {
|
||||
const id = key(idx)
|
||||
if (nodeid === id && !found) {
|
||||
const obj = cols.reduce((acc, col) => {
|
||||
const accessor = searchNodeTable.getter(col.name)
|
||||
const val = accessor(idx)
|
||||
acc[col.name] = val
|
||||
return acc
|
||||
}, {})
|
||||
found = obj
|
||||
stop()
|
||||
}
|
||||
}, true)
|
||||
searchNodeTable.scan(
|
||||
(
|
||||
idx: number | undefined,
|
||||
data: any,
|
||||
stop: (() => void) | undefined,
|
||||
) => {
|
||||
const id = data['node.id'].get(idx)
|
||||
if (nodeid === id && !found) {
|
||||
const obj = cols.reduce((acc, col) => {
|
||||
const val = data[col.name].get(idx)
|
||||
acc[col.name] = val
|
||||
return acc
|
||||
}, {})
|
||||
found = obj
|
||||
stop && stop()
|
||||
}
|
||||
},
|
||||
true,
|
||||
)
|
||||
if (found) {
|
||||
const commId = found['community.id']
|
||||
if (commId) {
|
||||
|
|
|
@ -16,7 +16,8 @@ import {
|
|||
import { SearchItems } from './SearchItems'
|
||||
import { SearchPanelHeader } from './SearchPanelHeader'
|
||||
import { CollapsiblePanel } from '@essex-js-toolkit/themed-components'
|
||||
import { op, table } from 'arquero'
|
||||
import { useDebounceFn } from 'ahooks'
|
||||
import { op } from 'arquero'
|
||||
import { useCallback, useState, useMemo } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
|
@ -37,6 +38,7 @@ export const SearchPanel: React.FC = () => {
|
|||
const [isExpanded, setIsExpanded] = useState<boolean>(false)
|
||||
const [errorMsg, setErrorMsg] = useState<string | undefined>()
|
||||
const [isInFocus, setIsInFocus] = useState<boolean>(false)
|
||||
const [isSearching, setIsSearching] = useState<boolean>(false)
|
||||
const setSelectedNode = useSetSelectedNodes()
|
||||
const modifiedTable = useTableColumnsByType('string')
|
||||
const columns = listColumnNames(modifiedTable)
|
||||
|
@ -60,24 +62,27 @@ export const SearchPanel: React.FC = () => {
|
|||
const setSelectedCommunity = useSetSelectedCommunity()
|
||||
|
||||
const getColumnByRow = useCallback(
|
||||
(col, row): [string, boolean] => {
|
||||
(col, row, searchValue): [string, boolean] => {
|
||||
const stringValue = modifiedTable.get(col, row)
|
||||
let isInSearch = false
|
||||
if (stringValue.indexOf(searchText) > -1) {
|
||||
if (stringValue.indexOf(searchValue) > -1) {
|
||||
isInSearch = true
|
||||
}
|
||||
return [stringValue, isInSearch]
|
||||
},
|
||||
[modifiedTable, searchText],
|
||||
[modifiedTable],
|
||||
)
|
||||
|
||||
const getMatchingValuesByRow = useCallback(
|
||||
(columns: string[]): [table, table] => {
|
||||
(
|
||||
columns: string[],
|
||||
searchValue: string,
|
||||
): [CommunityCollection, NodeCollection] => {
|
||||
const matches: SearchByIndex[] = []
|
||||
modifiedTable.scan(row => {
|
||||
const o = columns.reduce(
|
||||
(acc, col) => {
|
||||
const [value, isInSearch] = getColumnByRow(col, row)
|
||||
const [value, isInSearch] = getColumnByRow(col, row, searchValue)
|
||||
if (isInSearch) {
|
||||
acc.isInSearch = true
|
||||
acc.matchColumns.push(col)
|
||||
|
@ -114,15 +119,15 @@ export const SearchPanel: React.FC = () => {
|
|||
)
|
||||
const matchTable = communities
|
||||
.params({ match: communityIds })
|
||||
.filter((d: any, $: any) => op.includes($.match, d['community.id']))
|
||||
.filter((d: any, $: any) => op.includes($.match, d['community.id'], 0))
|
||||
.ungroup()
|
||||
|
||||
const nodeMatchTable = modifiedTable
|
||||
.params({ match: Array.from(nodeids), commIds: nodeCommIds })
|
||||
.filter(
|
||||
(d: any, $: any) =>
|
||||
op.includes($.match, d['node.id']) &&
|
||||
op.includes($.commIds, d['community.id']),
|
||||
op.includes($.match, d['node.id'], 0) &&
|
||||
op.includes($.commIds, d['community.id'], 0),
|
||||
)
|
||||
.ungroup()
|
||||
const ccTable = new CommunityCollection(matchTable)
|
||||
|
@ -151,36 +156,70 @@ export const SearchPanel: React.FC = () => {
|
|||
setIsExpanded,
|
||||
])
|
||||
|
||||
const onSearch = useCallback(() => {
|
||||
if (!searchText) {
|
||||
onClear()
|
||||
} else {
|
||||
setErrorMsg(undefined)
|
||||
if (columns.length > 0) {
|
||||
// filter out community.pid, need to figure out properly display if we choose to include it
|
||||
const cols = columns.filter(d => d !== 'community.pid')
|
||||
const [matchTable, matchingValues] = getMatchingValuesByRow(cols)
|
||||
if (matchingValues.size < 1) {
|
||||
setErrorMsg(`No results found for ${searchText}`)
|
||||
}
|
||||
setIsExpanded(true)
|
||||
setSearchTable(matchTable)
|
||||
setSearchNodeTable(matchingValues)
|
||||
const useSearchDebounce = useDebounceFn(
|
||||
(searchValue: string) => {
|
||||
searchByText(searchValue)
|
||||
},
|
||||
{
|
||||
wait: 10, //wait to search to show spinner
|
||||
},
|
||||
)
|
||||
|
||||
const searchByText = useCallback(
|
||||
(searchValue: string) => {
|
||||
// filter out community.pid, need to figure out properly display if we choose to include it
|
||||
const cols = columns.filter(d => d !== 'community.pid')
|
||||
const [matchTable, matchingValues] = getMatchingValuesByRow(
|
||||
cols,
|
||||
searchValue,
|
||||
)
|
||||
if (matchingValues.size < 1) {
|
||||
setErrorMsg(`No results found for ${searchText}`)
|
||||
}
|
||||
}
|
||||
}, [
|
||||
searchText,
|
||||
columns,
|
||||
setSearchNodeTable,
|
||||
onClear,
|
||||
getMatchingValuesByRow,
|
||||
setSearchTable,
|
||||
setErrorMsg,
|
||||
setIsExpanded,
|
||||
])
|
||||
setIsExpanded(true)
|
||||
setSearchTable(matchTable)
|
||||
setSearchNodeTable(matchingValues)
|
||||
setIsSearching(false)
|
||||
},
|
||||
[
|
||||
searchText,
|
||||
columns,
|
||||
setSearchNodeTable,
|
||||
getMatchingValuesByRow,
|
||||
setSearchTable,
|
||||
setErrorMsg,
|
||||
setIsExpanded,
|
||||
setIsSearching,
|
||||
],
|
||||
)
|
||||
|
||||
const onSearch = useCallback(
|
||||
(searchValue?: string) => {
|
||||
if (!searchText && !searchValue) {
|
||||
onClear()
|
||||
} else {
|
||||
if (!searchValue) {
|
||||
searchValue = searchText as string
|
||||
}
|
||||
setErrorMsg(undefined)
|
||||
if (columns.length > 0) {
|
||||
setIsSearching(true)
|
||||
useSearchDebounce.run(searchValue)
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
searchText,
|
||||
columns,
|
||||
onClear,
|
||||
setErrorMsg,
|
||||
setIsSearching,
|
||||
useSearchDebounce,
|
||||
],
|
||||
)
|
||||
|
||||
const onChange = useCallback(
|
||||
(event?: React.ChangeEvent<HTMLInputElement>, newValue?: string): any => {
|
||||
(newValue: string): any => {
|
||||
setSearchText(newValue)
|
||||
},
|
||||
[setSearchText],
|
||||
|
@ -196,9 +235,10 @@ export const SearchPanel: React.FC = () => {
|
|||
onSearch={onSearch}
|
||||
onClear={onClear}
|
||||
onFocusChange={onFocusChange}
|
||||
isSearching={isSearching}
|
||||
/>
|
||||
),
|
||||
[disabled, onClear, onChange, onSearch, onFocusChange],
|
||||
[disabled, onClear, onChange, onSearch, onFocusChange, isSearching],
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { SearchBox, IconButton } from '@fluentui/react'
|
||||
import { SearchBox, IconButton, Spinner, SpinnerSize } from '@fluentui/react'
|
||||
import { useDebounceFn } from 'ahooks'
|
||||
import { useCallback } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
@ -21,13 +21,11 @@ const searchIcon = { iconName: 'Search' }
|
|||
|
||||
interface SearchPanelHeaderProps {
|
||||
disabled: boolean
|
||||
onChange: (
|
||||
event?: React.ChangeEvent<HTMLInputElement>,
|
||||
newValue?: string,
|
||||
) => any
|
||||
onChange: (newValue: string) => any
|
||||
onClear: () => void
|
||||
onSearch: () => void
|
||||
onSearch: (searchValue?: string) => void
|
||||
onFocusChange: (state: boolean) => void
|
||||
isSearching: boolean
|
||||
}
|
||||
export const SearchPanelHeader = ({
|
||||
disabled,
|
||||
|
@ -35,13 +33,14 @@ export const SearchPanelHeader = ({
|
|||
onSearch,
|
||||
onClear,
|
||||
onFocusChange,
|
||||
isSearching,
|
||||
}: SearchPanelHeaderProps) => {
|
||||
const focusCallback = useCallback(() => onFocusChange(true), [onFocusChange])
|
||||
const blurCallback = useCallback(() => onFocusChange(false), [onFocusChange])
|
||||
|
||||
const useDebounce = useDebounceFn(
|
||||
(event, newValue) => {
|
||||
onChange(event, newValue)
|
||||
newValue => {
|
||||
onChange(newValue)
|
||||
},
|
||||
{
|
||||
wait: 500,
|
||||
|
@ -55,23 +54,24 @@ export const SearchPanelHeader = ({
|
|||
styles={searchBoxStyle}
|
||||
disabled={disabled}
|
||||
onChange={(
|
||||
event?: React.ChangeEvent<HTMLInputElement>,
|
||||
_?: React.ChangeEvent<HTMLInputElement>,
|
||||
newValue?: string,
|
||||
) => useDebounce.run(event, newValue)}
|
||||
) => useDebounce.run(newValue)}
|
||||
onClear={onClear}
|
||||
onSearch={onSearch}
|
||||
onSearch={(value: string) => onSearch(value)}
|
||||
onFocus={focusCallback}
|
||||
onBlur={blurCallback}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
iconProps={searchIcon}
|
||||
iconProps={!isSearching ? searchIcon : {}}
|
||||
styles={searchButtonStyle}
|
||||
title="Search"
|
||||
ariaLabel={'Search'}
|
||||
disabled={disabled}
|
||||
onClick={onSearch}
|
||||
/>
|
||||
onClick={() => onSearch()}
|
||||
>
|
||||
{isSearching && <Spinner size={SpinnerSize.xSmall} />}
|
||||
</IconButton>
|
||||
</Label>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ export const FileList: React.FC = () => {
|
|||
<DefaultButton text="Clear all" onClick={handleResetClick} />
|
||||
) : null}
|
||||
</Reset>
|
||||
{selectedFile ? (
|
||||
{selectedFile && selectedFile.table ? (
|
||||
<Viewer>
|
||||
<h3>{selectedFile.url}</h3>
|
||||
<ArqueroTable table={selectedFile?.table} options={{ limit: 10 }} />
|
||||
|
|
|
@ -9,17 +9,19 @@ import styled from 'styled-components'
|
|||
export const Footer: FC = memo(function Footer() {
|
||||
return (
|
||||
<FooterEl>
|
||||
<Link href={constants.privacyUrl}>Privacy</Link>
|
||||
{' | '}
|
||||
<Link id={'managecookies'} onClick={manageConsent}>
|
||||
Cookies
|
||||
</Link>
|
||||
{' | '}
|
||||
<Link href={constants.termsOfUseUrl}>Terms of Use</Link>
|
||||
{' | '}
|
||||
<Link href={constants.trademarksUrl}>Trademarks</Link>
|
||||
{' | '}
|
||||
<Link href={constants.microsoft}>{constants.copyright}</Link>
|
||||
<Container>
|
||||
<Link href={constants.privacyUrl}>Privacy</Link>
|
||||
{' | '}
|
||||
<Link id={'managecookies'} onClick={manageConsent}>
|
||||
Cookies
|
||||
</Link>
|
||||
{' | '}
|
||||
<Link href={constants.termsOfUseUrl}>Terms of Use</Link>
|
||||
{' | '}
|
||||
<Link href={constants.trademarksUrl}>Trademarks</Link>
|
||||
{' | '}
|
||||
<Link href={constants.microsoft}>{constants.copyright}</Link>
|
||||
</Container>
|
||||
</FooterEl>
|
||||
)
|
||||
})
|
||||
|
@ -50,6 +52,10 @@ const Link: FC<{
|
|||
})
|
||||
|
||||
const FooterEl = styled.footer`
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
const Container = styled.div`
|
||||
width: 500px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
|
@ -58,6 +64,7 @@ const FooterEl = styled.footer`
|
|||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
margin: auto;
|
||||
`
|
||||
|
||||
const constants = {
|
||||
|
|
|
@ -12,7 +12,8 @@ import {
|
|||
IHierarchyDataResponse,
|
||||
IHierarchyNeighborResponse,
|
||||
} from '@essex-js-toolkit/hierarchy-browser'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { TableData } from 'arquero/dist/types/table/table'
|
||||
import { useMemo } from 'react'
|
||||
import {
|
||||
findNodesCollectionForCommunity,
|
||||
|
@ -79,13 +80,13 @@ function nodeColumns(
|
|||
|
||||
export function useEntityCallback(): (
|
||||
loadParams: ILoadParams,
|
||||
byParent: table,
|
||||
byCommunity: table,
|
||||
byParent: ColumnTable,
|
||||
byCommunity: ColumnTable,
|
||||
) => Promise<IHierarchyDataResponse> {
|
||||
async function handleEntityCallback(
|
||||
loadParams: ILoadParams,
|
||||
byParent: table,
|
||||
byCommunity: table,
|
||||
byParent: ColumnTable,
|
||||
byCommunity: ColumnTable,
|
||||
): Promise<IHierarchyDataResponse> {
|
||||
const cid = loadParams.communityId
|
||||
const selectedNeighbor = findNodesCollectionForCommunity(
|
||||
|
@ -101,13 +102,13 @@ export function useEntityCallback(): (
|
|||
|
||||
export function useNeighborCallback(): (
|
||||
params: ILoadParams,
|
||||
nodeTable: table,
|
||||
edges: table,
|
||||
nodeTable: ColumnTable,
|
||||
edges: ColumnTable,
|
||||
) => Promise<IHierarchyNeighborResponse> {
|
||||
const handleNeighborCallback = async function (
|
||||
params: ILoadParams,
|
||||
nodeTable: table,
|
||||
edges: table,
|
||||
nodeTable: ColumnTable,
|
||||
edges: ColumnTable,
|
||||
): Promise<IHierarchyNeighborResponse> {
|
||||
const neighborTable = getEdgesFromTableByID(
|
||||
params.communityId,
|
||||
|
@ -132,7 +133,7 @@ export function useNeighborCallback(): (
|
|||
return handleNeighborCallback
|
||||
}
|
||||
|
||||
function getNeighborIds(counts: table, communityId: string) {
|
||||
function getNeighborIds(counts: ColumnTable, communityId: string) {
|
||||
if (counts.numRows() > 0) {
|
||||
// scan the edge counts table to create a few table rows
|
||||
const max = Math.min(100, counts.numRows())
|
||||
|
@ -140,22 +141,29 @@ function getNeighborIds(counts: table, communityId: string) {
|
|||
const key = counts.getter('key')
|
||||
const count = counts.getter('count')
|
||||
const membership = counts.getter('members')
|
||||
counts.scan((idx: number, data: any, stop: () => void) => {
|
||||
const k = key(idx)
|
||||
const c = count(idx)
|
||||
const size = membership(idx)
|
||||
if (communityId !== k) {
|
||||
output.push({
|
||||
communityId: k,
|
||||
connections: c,
|
||||
edgeCommunityId: communityId,
|
||||
size,
|
||||
} as INeighborCommunityDetail)
|
||||
}
|
||||
if (output.length > max) {
|
||||
stop()
|
||||
}
|
||||
}, true)
|
||||
counts.scan(
|
||||
(
|
||||
idx?: number | undefined,
|
||||
data?: TableData | any[] | undefined,
|
||||
stop?: (() => void) | undefined,
|
||||
) => {
|
||||
const k = key(idx)
|
||||
const c = count(idx)
|
||||
const size = membership(idx)
|
||||
if (communityId !== k) {
|
||||
output.push({
|
||||
communityId: k,
|
||||
connections: c,
|
||||
edgeCommunityId: communityId,
|
||||
size,
|
||||
} as INeighborCommunityDetail)
|
||||
}
|
||||
if (output.length > max) {
|
||||
stop && stop()
|
||||
}
|
||||
},
|
||||
true,
|
||||
)
|
||||
return output
|
||||
}
|
||||
return []
|
||||
|
|
|
@ -8,7 +8,7 @@ import { NumericDomainEditor } from '../NumericDomainEditor'
|
|||
import { ColorSelectorProps } from './types'
|
||||
import { Dropdown } from '@fluentui/react'
|
||||
import { ScaleDropdown } from '@thematic/fluent'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
|
@ -72,7 +72,7 @@ export const ScaledPicker: React.FC<ColorSelectorProps> = ({
|
|||
)
|
||||
}
|
||||
|
||||
function useFieldDropdownOptions(table: table) {
|
||||
function useFieldDropdownOptions(table: ColumnTable) {
|
||||
return useMemo(() => {
|
||||
return table.columnNames().map(key => ({
|
||||
key,
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { ColorEncoding } from '../../types'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
export interface ColorSelectorProps {
|
||||
/**
|
||||
* table the encoding will be binding to, so we can lookup stats
|
||||
* or column names as needed
|
||||
*/
|
||||
table: table
|
||||
table: ColumnTable
|
||||
encoding: ColorEncoding
|
||||
onChange: (encoding: Partial<ColorEncoding>) => void
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { DomainBrush } from '../DomainBrush'
|
|||
import { Label } from '@fluentui/react'
|
||||
import { ScaleType } from '@thematic/core'
|
||||
import { ScaleTypeChoiceGroup } from '@thematic/fluent'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { format } from 'd3-format'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
@ -18,7 +18,7 @@ export interface NumericDomainEditorProps {
|
|||
* table the encoding will be binding to, so we can lookup stats
|
||||
* or column names as needed
|
||||
*/
|
||||
table: table
|
||||
table: ColumnTable
|
||||
encoding: Encoding
|
||||
onChange: (encoding: Partial<Encoding>) => void
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { NumericDomainEditor } from '../NumericDomainEditor'
|
|||
import { NumericRangeEditor } from '../NumericRangeEditor'
|
||||
import { NumericSelectorProps } from './types'
|
||||
import { Dropdown } from '@fluentui/react'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { columnTypes } from '~/arquero'
|
||||
|
@ -63,7 +63,7 @@ export const ScaledPicker: React.FC<NumericSelectorProps> = ({
|
|||
}
|
||||
|
||||
// for opacity, we can only allow numeric bindings
|
||||
function useFieldDropdownOptions(table: table) {
|
||||
function useFieldDropdownOptions(table: ColumnTable) {
|
||||
return useMemo(() => {
|
||||
const types = columnTypes(table)
|
||||
return types
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { NumericEncoding } from '../../types'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
export interface NumericSelectorProps {
|
||||
/**
|
||||
* table the encoding will be binding to, so we can lookup stats
|
||||
* or column names as needed
|
||||
*/
|
||||
table: table
|
||||
table: ColumnTable
|
||||
encoding: NumericEncoding
|
||||
onChange: (encoding: Partial<NumericEncoding>) => void
|
||||
label?: string
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
*/
|
||||
import { GraphContainer } from '@graspologic/graph'
|
||||
import { LayoutWorkerManager } from '@graspologic/layout-core'
|
||||
import { from, table } from 'arquero'
|
||||
import { from } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { ArqueroNode, normalizeXY } from '~/arquero'
|
||||
|
||||
function getFa2Worker() {
|
||||
|
@ -13,7 +14,7 @@ function getFa2Worker() {
|
|||
}
|
||||
|
||||
// this gets the nodes + edges ready for the graspologic layout worker
|
||||
function prepGraph(edgeTable: table, nodeTable?: table) {
|
||||
function prepGraph(edgeTable: ColumnTable, nodeTable?: ColumnTable) {
|
||||
// edgeTable should just be source + target cols, plus optional weight
|
||||
// derive a weight if needed, and then extract individual nodes
|
||||
const edges: any = []
|
||||
|
@ -82,7 +83,11 @@ function postProcessLayout(graph: GraphContainer) {
|
|||
* @param nodes - optional, will be derived from edge list if necessary
|
||||
* @param options - addl layout worker options
|
||||
*/
|
||||
export async function layoutFa2(edges: table, nodes?: table, options?: any) {
|
||||
export async function layoutFa2(
|
||||
edges: ColumnTable,
|
||||
nodes?: ColumnTable,
|
||||
options?: any,
|
||||
) {
|
||||
console.time('layout-fa2')
|
||||
|
||||
const graph = prepGraph(edges, nodes)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { table, op } from 'arquero'
|
||||
import { op } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { normalizeXY } from '~/arquero'
|
||||
|
||||
/**
|
||||
|
@ -11,7 +12,7 @@ import { normalizeXY } from '~/arquero'
|
|||
* as it will consolidate blocks of color in strips.
|
||||
* @param nodes
|
||||
*/
|
||||
export async function layoutGrid(nodes: table): Promise<table> {
|
||||
export async function layoutGrid(nodes: ColumnTable): Promise<ColumnTable> {
|
||||
return new Promise(resolve => {
|
||||
const ranked = nodes
|
||||
.params({
|
||||
|
|
|
@ -7,7 +7,7 @@ import { layoutGrid } from './grid'
|
|||
import { layoutRandom } from './random'
|
||||
import { Layout } from './types'
|
||||
import { layoutUmap } from './umap'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
export * from './fa2'
|
||||
export * from './grid'
|
||||
|
@ -25,18 +25,18 @@ export * from './types'
|
|||
*/
|
||||
export async function executeLayout(
|
||||
type: Layout,
|
||||
nodes?: table,
|
||||
edges?: table,
|
||||
nodes?: ColumnTable,
|
||||
edges?: ColumnTable,
|
||||
options?: any,
|
||||
) {
|
||||
switch (type) {
|
||||
case Layout.Random:
|
||||
return layoutRandom(nodes)
|
||||
return nodes && layoutRandom(nodes)
|
||||
case Layout.Grid:
|
||||
return layoutGrid(nodes)
|
||||
return nodes && layoutGrid(nodes)
|
||||
case Layout.FA2:
|
||||
return layoutFa2(edges, nodes, options)
|
||||
return edges && layoutFa2(edges, nodes, options)
|
||||
case Layout.UMAP:
|
||||
return layoutUmap(edges)
|
||||
return edges && layoutUmap(edges)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
/**
|
||||
* Randomly assign x/y positions to a table of nodes
|
||||
* @param table
|
||||
*/
|
||||
export async function layoutRandom(nodes: table): Promise<table> {
|
||||
export async function layoutRandom(nodes: ColumnTable): Promise<ColumnTable> {
|
||||
return new Promise(resolve => {
|
||||
resolve(
|
||||
nodes.derive({
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
*/
|
||||
import { umapLayout } from '../api'
|
||||
import { EdgeCollection, normalizeXY } from '../arquero'
|
||||
import { from, table } from 'arquero'
|
||||
import { from } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
/**
|
||||
* Runs our autolayout umap - note that this mostly just thunks over to the web service.
|
||||
* @param edges
|
||||
*/
|
||||
export async function layoutUmap(edges: table) {
|
||||
export async function layoutUmap(edges: ColumnTable) {
|
||||
const positions = await umapLayout(new EdgeCollection(edges))
|
||||
const transformed = positions.map(n => ({
|
||||
'node.id': n.id,
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
import { Theme } from '@thematic/core'
|
||||
import 'styled-components'
|
||||
|
||||
declare module 'styled-components' {
|
||||
export interface DefaultTheme extends Theme {}
|
||||
}
|
||||
|
||||
declare module 'arquero' {
|
||||
interface GroupBySpecification {
|
||||
names: string[]
|
||||
get: any[]
|
||||
rows: number[]
|
||||
size: number
|
||||
keys: Uint32Array
|
||||
}
|
||||
|
||||
interface table {
|
||||
// table meta
|
||||
numCols: () => number
|
||||
numRows: () => number
|
||||
totalRows: () => number
|
||||
isFiltered: () => boolean
|
||||
isGrouped: () => boolean
|
||||
isOrdered: () => boolean
|
||||
groups: () => GroupBySpecification
|
||||
params: (params?: any) => table | any
|
||||
// table columns
|
||||
columnNames: (filter?: any) => string[]
|
||||
// verbs
|
||||
// https://uwdata.github.io/arquero/api/verbs
|
||||
derive: (values: any) => table
|
||||
filter: (criteria: any) => table
|
||||
groupby: (keys: any) => table
|
||||
ungroup: () => table
|
||||
orderby: (keys: any) => table
|
||||
unorder: () => table
|
||||
rollup: (values: any) => table
|
||||
count: (options?: any) => table
|
||||
sample: (size: number, options?: any) => table
|
||||
select: (...values: any) => table
|
||||
reify: (indices?: number[]) => table
|
||||
// join verbs
|
||||
join: (other: table, on?: any, values?: any, options?: any) => table
|
||||
join_left: (other: table, on?: any, values?: any, options?: any) => table
|
||||
join_right: (other: table, on?: any, values?: any, options?: any) => table
|
||||
lookup: (other: table, on?: any, values?: any) => table
|
||||
semijoin: (other: table, on?: any) => table
|
||||
concat: (other: table | table[]) => table
|
||||
// reshape verbs
|
||||
fold: (values: any, options?: any) => table
|
||||
pivot: (keys: any, values?: any, options?: any) => table
|
||||
unroll: (values: any, options?: any) => table
|
||||
// set verbs
|
||||
dedupe: (values: any) => table
|
||||
// table values
|
||||
data: () => any
|
||||
get: (name: string, row: number) => any
|
||||
getter: (name: string) => any
|
||||
indices: (order?: boolean) => Uint32Array
|
||||
partitions: (order?: boolean) => Uint32Array[]
|
||||
scan: (
|
||||
callback: (row: number, data: any, stop: () => void) => void,
|
||||
order?: boolean,
|
||||
) => void
|
||||
// output
|
||||
objects(options?: any): any[]
|
||||
print(options?: any): void
|
||||
}
|
||||
|
||||
function table(): table
|
||||
function from(objects: any): table
|
||||
function fromCSV(text: string, options?: any): table
|
||||
|
||||
function not(args?: any): any
|
||||
function all(args?: any): any
|
||||
function desc(args?: any): any
|
||||
|
||||
const op = {
|
||||
count: () => any,
|
||||
min: (field: string) => any,
|
||||
max: (field: string) => any,
|
||||
quantile: (field: string, p: number) => any,
|
||||
values: (field: string) => any,
|
||||
unique: (field: string) => any,
|
||||
sum: (value: any) => any,
|
||||
any: (field: string) => any,
|
||||
has: (obj: any, property: string) => any,
|
||||
// window functions
|
||||
ntile: (num: number) => any,
|
||||
rank: () => any,
|
||||
row_number: () => any,
|
||||
cume_dist: () => any,
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import { settingsState } from './settings'
|
|||
import { communityNodesTableState, edgeTableState } from './tables'
|
||||
import { edgesVisibleState } from './vis'
|
||||
import { GraphContainer } from '@graspologic/graph'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import { useEffect } from 'react'
|
||||
import {
|
||||
atom,
|
||||
|
@ -125,7 +125,7 @@ export function useVisibleNodeMap(cid: string) {
|
|||
// generate a unique key for storing cached values related to a table
|
||||
// warning: this isn't entirely guaranteed to be unique, but should
|
||||
// cover any expected scenarios we encounter (right?)
|
||||
function tableKey(table: table) {
|
||||
function tableKey(table: ColumnTable) {
|
||||
return `${table.columnNames().join('-')}-${table.numRows()}`
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ const cachedColumnStatsState = atomFamily<ColumnStats | undefined, string>({
|
|||
default: undefined,
|
||||
})
|
||||
|
||||
export function useCachedColumnStats(table: table, field?: string) {
|
||||
export function useCachedColumnStats(table: ColumnTable, field?: string) {
|
||||
const key = `${tableKey(table)}-${field}`
|
||||
const [cached, setCached] = useRecoilState(cachedColumnStatsState(key))
|
||||
useEffect(() => {
|
||||
|
@ -151,7 +151,7 @@ const cachedColumnHistogramState = atomFamily<any[] | undefined, string>({
|
|||
default: undefined,
|
||||
})
|
||||
|
||||
export function useCachedColumnHistogram(table: table, field?: string) {
|
||||
export function useCachedColumnHistogram(table: ColumnTable, field?: string) {
|
||||
const key = `${tableKey(table)}-${field}`
|
||||
const [cached, setCached] = useRecoilState(cachedColumnHistogramState(key))
|
||||
useEffect(() => {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
import {
|
||||
atom,
|
||||
selector,
|
||||
|
@ -13,9 +14,9 @@ import {
|
|||
} from 'recoil'
|
||||
import { findNodesTableForCommunity, getNodeStats } from '~/arquero'
|
||||
|
||||
export const bigTableState = atom<table>({
|
||||
export const bigTableState = atom<ColumnTable>({
|
||||
key: 'big-table',
|
||||
default: table(),
|
||||
default: table({}),
|
||||
// this is required so that arquero can update indexes under the hood
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
@ -33,14 +34,14 @@ export function useResetBigTable() {
|
|||
}
|
||||
// keep ahold of a pre-grouped copy of the big table,
|
||||
// because all of our interactions are based around communities
|
||||
const groupedCommunitiesTableState = selector<table>({
|
||||
const groupedCommunitiesTableState = selector<ColumnTable>({
|
||||
key: 'grouped-community-table',
|
||||
dangerouslyAllowMutability: true,
|
||||
get: ({ get }) => {
|
||||
console.log('deriving pre-grouped community table')
|
||||
const bigTable = get(bigTableState)
|
||||
if (bigTable.numRows() === 0) {
|
||||
return table()
|
||||
return table({})
|
||||
}
|
||||
console.time('groupby community state')
|
||||
const grouped = bigTable.groupby('community.id')
|
||||
|
@ -53,14 +54,14 @@ export function useGroupedByCommunityTable() {
|
|||
return useRecoilValue(groupedCommunitiesTableState)
|
||||
}
|
||||
|
||||
export const groupedParentsTableState = selector<table>({
|
||||
export const groupedParentsTableState = selector<ColumnTable>({
|
||||
key: 'grouped-parent-community-table',
|
||||
dangerouslyAllowMutability: true,
|
||||
get: ({ get }) => {
|
||||
console.log('deriving pre-grouped parent community table')
|
||||
const bigTable = get(bigTableState)
|
||||
if (bigTable.numRows() === 0) {
|
||||
return table()
|
||||
return table({})
|
||||
}
|
||||
console.time('groupby parent state')
|
||||
const grouped = bigTable.groupby('community.pid')
|
||||
|
@ -74,7 +75,7 @@ export function useGroupedByParentTable() {
|
|||
}
|
||||
|
||||
// returns a table representing only the nodes for the selected community
|
||||
export const communityNodesTableState = selectorFamily<table, string>({
|
||||
export const communityNodesTableState = selectorFamily<ColumnTable, string>({
|
||||
key: 'community-nodes-table',
|
||||
get:
|
||||
cid =>
|
||||
|
@ -91,13 +92,13 @@ export function useCommunityNodesTable(cid: string) {
|
|||
}
|
||||
|
||||
// creates a single row per community in the app (just grabbing the first from each group in the big table)
|
||||
const communitiesTableState = selector<table>({
|
||||
const communitiesTableState = selector<ColumnTable>({
|
||||
key: 'communities-table',
|
||||
get: ({ get }) => {
|
||||
const byCommunity = get(groupedCommunitiesTableState)
|
||||
console.time('communities state')
|
||||
const groups = byCommunity.groups()
|
||||
const tbl = groups ? byCommunity.reify(groups.rows) : table()
|
||||
const tbl = groups ? byCommunity.reify(groups.rows) : table({})
|
||||
console.timeEnd('communities state')
|
||||
return tbl
|
||||
},
|
||||
|
@ -129,9 +130,9 @@ export function useNodeStatsByCommunity(cid: string, quantile: number) {
|
|||
// standalone edge table
|
||||
// we don't want to join that with the node/community table,
|
||||
// as it would be massive and not useful
|
||||
export const edgeTableState = atom<table>({
|
||||
export const edgeTableState = atom<ColumnTable>({
|
||||
key: 'edge-table',
|
||||
default: table(),
|
||||
default: table({}),
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { ScaleType } from '@thematic/core'
|
||||
import { table } from 'arquero'
|
||||
import ColumnTable from 'arquero/dist/types/table/column-table'
|
||||
|
||||
export interface TableBackedItem {
|
||||
id: string
|
||||
|
@ -43,7 +43,7 @@ export interface Edge extends TableBackedItem {
|
|||
export type ItemType = 'node' | 'community' | 'edge' | 'join'
|
||||
|
||||
export interface TableDef {
|
||||
table: table
|
||||
table: ColumnTable
|
||||
// NOTE: these are the supported types of aggregation
|
||||
// however, there is no reason this can't allow completely arbitrary "types"
|
||||
type: ItemType
|
||||
|
@ -82,7 +82,7 @@ export interface DataFile {
|
|||
* If the user has indicated whether this is nodes, edges, etc.
|
||||
*/
|
||||
tableType?: ItemType
|
||||
table?: table
|
||||
table?: ColumnTable
|
||||
rows?: number
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,12 @@ const lineupRules = [
|
|||
mimetype: 'image/svg+xml',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
|
||||
loader: 'file-loader',
|
||||
|
@ -30,7 +36,8 @@ base.module.rules = [...base.module.rules, ...lineupRules]
|
|||
const aliasFields = base.resolve.aliasFields || []
|
||||
base.resolve = {
|
||||
...base.resolve,
|
||||
|
||||
//.mjs required for apache-arrow
|
||||
extensions: ['.ts', '.mjs', '.js', '.tsx'],
|
||||
// mjolnir.js relies on this functionality
|
||||
// it has a "browser" package.json property that it uses to define which
|
||||
// scripts to load
|
||||
|
|
340
yarn.lock
340
yarn.lock
|
@ -3611,11 +3611,11 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/d3-brush@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "@types/d3-brush@npm:2.1.0"
|
||||
version: 2.1.2
|
||||
resolution: "@types/d3-brush@npm:2.1.2"
|
||||
dependencies:
|
||||
"@types/d3-selection": "*"
|
||||
checksum: 9b524de33dc4f80cdb1e73c4408e48ae17e984ba25eab7525cf71e1be796deae037e542b977cf2378412a333fe8415d3a3eb2f9522e30e83bba27fe034076e4a
|
||||
"@types/d3-selection": ^2
|
||||
checksum: 44bb9f845b03380f626ae422d2b2f7f2710b4a28fd8c4539e82567502a14bfab2150cc30726fa03c802ac063ad36f46407eb64596d09e38f19b8546fee942a37
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -3633,7 +3633,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-scale@npm:^2.1.1, @types/d3-scale@npm:^2.2.4":
|
||||
"@types/d3-scale@npm:^2.1.1":
|
||||
version: 2.2.6
|
||||
resolution: "@types/d3-scale@npm:2.2.6"
|
||||
dependencies:
|
||||
"@types/d3-time": ^1
|
||||
checksum: ba4bd7e09995f8c08b0723b74aae5a165dbdf46178ae06016f6a4c7dd810dba76b8ec4b000bef95424eed204c02b7e7f3d9b8faaaf16255c57e79c4a59e3f18e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-scale@npm:^2.2.4":
|
||||
version: 2.2.4
|
||||
resolution: "@types/d3-scale@npm:2.2.4"
|
||||
dependencies:
|
||||
|
@ -3642,13 +3651,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-selection@npm:*, @types/d3-selection@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "@types/d3-selection@npm:2.0.0"
|
||||
checksum: a4fe69ae9d21c0b12dc60c0e7d7cea70eed9d6db72dce6d9fd6d9ac7bbb8bf3684ae1a123426c7bbfe606c0540e6196b953c279dcb86e5360292f179661528d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-selection@npm:^1, @types/d3-selection@npm:^1.4.3":
|
||||
version: 1.4.3
|
||||
resolution: "@types/d3-selection@npm:1.4.3"
|
||||
|
@ -3656,6 +3658,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-selection@npm:^2":
|
||||
version: 2.0.1
|
||||
resolution: "@types/d3-selection@npm:2.0.1"
|
||||
checksum: 23a337564e4540e1672103ad4d8b8eca1a8c50ec5d3382fbd764a3b93f591b7651441da0ae68119945789a8ba7b8d3ab208088ebf8b6fd1add2134df937bfe15
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-selection@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "@types/d3-selection@npm:2.0.0"
|
||||
checksum: a4fe69ae9d21c0b12dc60c0e7d7cea70eed9d6db72dce6d9fd6d9ac7bbb8bf3684ae1a123426c7bbfe606c0540e6196b953c279dcb86e5360292f179661528d9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/d3-time@npm:^1":
|
||||
version: 1.1.1
|
||||
resolution: "@types/d3-time@npm:1.1.1"
|
||||
|
@ -3762,6 +3778,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/flatbuffers@npm:^1.9.1":
|
||||
version: 1.10.0
|
||||
resolution: "@types/flatbuffers@npm:1.10.0"
|
||||
checksum: f6665700a8aca5129c487650607548fb50f3ae1d2de2b0d1d71ee5275a7b250004f956a21e38f47ab3b26315b29f175a84471f82a4569a09fb6c3dc19640ef9a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/glob-stream@npm:*":
|
||||
version: 6.1.0
|
||||
resolution: "@types/glob-stream@npm:6.1.0"
|
||||
|
@ -3978,6 +4001,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^12.0.4":
|
||||
version: 12.20.37
|
||||
resolution: "@types/node@npm:12.20.37"
|
||||
checksum: 8c8b12f802678b3b87c5344b6c84082be08561dda81dc161d42be8cd327330d1a5227cef039c45a5e63a6d4a01ef5ef215dccc42d06100f59f6a8814b4f91cdd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^13.7.0":
|
||||
version: 13.13.52
|
||||
resolution: "@types/node@npm:13.13.52"
|
||||
|
@ -3986,9 +4016,9 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/node@npm:^14.14.44":
|
||||
version: 14.17.0
|
||||
resolution: "@types/node@npm:14.17.0"
|
||||
checksum: 8e718402537fdfb11a3e59d43d8b0fe46112b1a4799f0d348c01030fc83c0d7c820fd8afa2db1dbe51674b9460a048d111b9caf71bb99342bd32db653effbe94
|
||||
version: 14.18.0
|
||||
resolution: "@types/node@npm:14.18.0"
|
||||
checksum: b120c26fe5f30bc358e861db8d7e401e419d14bd9dd25c022f3c2ea8b0b429d4c9efd77ad5d6d2a8bde61702a6786fb74d409f1b2cbb61c79133e2a65aab4fb1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4065,11 +4095,11 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/react-dom@npm:^16.9.12":
|
||||
version: 16.9.13
|
||||
resolution: "@types/react-dom@npm:16.9.13"
|
||||
version: 16.9.14
|
||||
resolution: "@types/react-dom@npm:16.9.14"
|
||||
dependencies:
|
||||
"@types/react": ^16
|
||||
checksum: 71f0e63e28fe8e4b42a3126599d65c43db1336f82f61970ccdfb32db941c0db217617e3ebfaf65c6b3dd6b27e66e771cecab7b0261db14117fd9e7a433e6ac7f
|
||||
checksum: 68a4ee88f7a56cdbfbca24b1936b9aa5dad8b40ffbf1f047ddf990454aec6e0c9da2a01c9ae87045e95236602061646c90d02f01281533e14f1970687873030f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4124,13 +4154,13 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/react@npm:^16, @types/react@npm:^16.14.6":
|
||||
version: 16.14.6
|
||||
resolution: "@types/react@npm:16.14.6"
|
||||
version: 16.14.21
|
||||
resolution: "@types/react@npm:16.14.21"
|
||||
dependencies:
|
||||
"@types/prop-types": "*"
|
||||
"@types/scheduler": "*"
|
||||
csstype: ^3.0.2
|
||||
checksum: 7aeb670a46ef8dbb516a984e26578bbdc4341b40325ff7928d803a82b11812ebdb4e46ace5e2e643d371c4a8e6486cf5c9608b7f99f645ebe623f274c37ea2c9
|
||||
checksum: 9660ea0a2c7ad364295c1e5abd6b98a05fd372a0f06f97850f60fcc254bcec766d19b101c0acc382746a4e0b71848d88097a1db7124e3fd441c0472fb6b3f849
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -4228,6 +4258,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/text-encoding-utf-8@npm:^1.0.1":
|
||||
version: 1.0.2
|
||||
resolution: "@types/text-encoding-utf-8@npm:1.0.2"
|
||||
checksum: a7199bb5c09448274b0f7f6535d84594bad5b492933cd6423bdcf73724c6fe6cbadb2c49bb526cb4eda3d03538a2e62a7e372dcc7688d1e5f87ac2f5c4c4410a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/through2@npm:^2.0.36":
|
||||
version: 2.0.36
|
||||
resolution: "@types/through2@npm:2.0.36"
|
||||
|
@ -5132,7 +5169,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.2.1":
|
||||
"acorn@npm:^8.1.0, acorn@npm:^8.2.1":
|
||||
version: 8.2.4
|
||||
resolution: "acorn@npm:8.2.4"
|
||||
bin:
|
||||
|
@ -5141,6 +5178,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn@npm:^8.5.0":
|
||||
version: 8.6.0
|
||||
resolution: "acorn@npm:8.6.0"
|
||||
bin:
|
||||
acorn: bin/acorn
|
||||
checksum: 9d0de73b73cb6ea8ccd8263a8144d9e2c4b6af90ea0c429997538af0ebbe83c5addecee814b2a7f91f7f615d0bd1547cc7137b3fa236ce058adc64feccee850b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"agent-base@npm:6":
|
||||
version: 6.0.2
|
||||
resolution: "agent-base@npm:6.0.2"
|
||||
|
@ -5397,6 +5443,26 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"apache-arrow@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "apache-arrow@npm:3.0.0"
|
||||
dependencies:
|
||||
"@types/flatbuffers": ^1.9.1
|
||||
"@types/node": ^12.0.4
|
||||
"@types/text-encoding-utf-8": ^1.0.1
|
||||
command-line-args: 5.0.2
|
||||
command-line-usage: 5.0.5
|
||||
flatbuffers: 1.11.0
|
||||
json-bignum: ^0.0.3
|
||||
pad-left: ^2.1.0
|
||||
text-encoding-utf-8: ^1.0.2
|
||||
tslib: ^1.12.0
|
||||
bin:
|
||||
arrow2csv: bin/arrow2csv.js
|
||||
checksum: 2ebd5e76d716bc122b40e4e923f5b4d390084ecce2a55daabab925d94540789597d726b63bac86d5839ba29497124242ba0b99a9d1f0c788662f5dcc70aacd8f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"append-buffer@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "append-buffer@npm:1.0.2"
|
||||
|
@ -5472,6 +5538,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"argv-tools@npm:^0.1.1":
|
||||
version: 0.1.2
|
||||
resolution: "argv-tools@npm:0.1.2"
|
||||
dependencies:
|
||||
array-back: ^2.0.0
|
||||
find-replace: ^2.0.1
|
||||
checksum: 77f8c7727cdfcbb944a5d3c78a2b85dec7ca2dc85de08a6d3bebb7ca20572740e3916126165fc979f5bc9bc4f12b04679e04f9a6aa6f3d2889e1a3e08ee0d847
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"aria-query@npm:^4.0.2, aria-query@npm:^4.2.2":
|
||||
version: 4.2.2
|
||||
resolution: "aria-query@npm:4.2.2"
|
||||
|
@ -5482,12 +5558,14 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"arquero@npm:^0.13.3":
|
||||
version: 0.13.3
|
||||
resolution: "arquero@npm:0.13.3"
|
||||
"arquero@npm:^4.8.4":
|
||||
version: 4.8.7
|
||||
resolution: "arquero@npm:4.8.7"
|
||||
dependencies:
|
||||
acorn: ^8.0.4
|
||||
checksum: 5952608e2e197c3a29b9c02108692192daae17f1e76e8a1c3a61f8af3cf357cb22b86d92a28f75fa9332395b857d91404c8f24e827dc1b9e8bbecf1d2d170535
|
||||
acorn: ^8.5.0
|
||||
apache-arrow: ^3.0.0
|
||||
node-fetch: ^2.6.2
|
||||
checksum: 63a832e7f0a5d60d70d3b036f6c5714aa4593c6d1d3ba6c4fa9e1bef304bf307de434c3c41de5706e5767ddf77a8397b4bf6f129899adfbdb4b271caf33f3413
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -5547,6 +5625,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-back@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "array-back@npm:2.0.0"
|
||||
dependencies:
|
||||
typical: ^2.6.1
|
||||
checksum: ab36ab3504b25116b47541fb0ac78ff13d1e991f33d98c361edd3aada3ed818a900b619bd67b195dd4e41b9256c27e8cdd6a69ece507e482f1207d07670ed6bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"array-differ@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "array-differ@npm:3.0.0"
|
||||
|
@ -7102,6 +7189,31 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"command-line-args@npm:5.0.2":
|
||||
version: 5.0.2
|
||||
resolution: "command-line-args@npm:5.0.2"
|
||||
dependencies:
|
||||
argv-tools: ^0.1.1
|
||||
array-back: ^2.0.0
|
||||
find-replace: ^2.0.1
|
||||
lodash.camelcase: ^4.3.0
|
||||
typical: ^2.6.1
|
||||
checksum: fc239cc26284e75f21bae0a5a0c716743eaf95ae4deadffbcffe84f9cf94419db3f953afec748a86a2543932733a4e85aa08b8c06e9b6e8fb8c42c27328fd3e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"command-line-usage@npm:5.0.5":
|
||||
version: 5.0.5
|
||||
resolution: "command-line-usage@npm:5.0.5"
|
||||
dependencies:
|
||||
array-back: ^2.0.0
|
||||
chalk: ^2.4.1
|
||||
table-layout: ^0.4.3
|
||||
typical: ^2.6.1
|
||||
checksum: d6362006497598f67aad61308c5ef3445b951501cc6f6d640aa53b81a59bd7f84ba282664819329c67ed9dae78479941c235d03e3aa2711502b7f11881ea3df8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"commander@npm:2, commander@npm:^2.20.0":
|
||||
version: 2.20.3
|
||||
resolution: "commander@npm:2.20.3"
|
||||
|
@ -8098,7 +8210,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"deep-extend@npm:^0.6.0":
|
||||
"deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0":
|
||||
version: 0.6.0
|
||||
resolution: "deep-extend@npm:0.6.0"
|
||||
checksum: 7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7
|
||||
|
@ -9632,6 +9744,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"find-replace@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "find-replace@npm:2.0.1"
|
||||
dependencies:
|
||||
array-back: ^2.0.0
|
||||
test-value: ^3.0.0
|
||||
checksum: 8eaa35d2a1322f063a59f8663404aa89941d7e32d6f470a3e22ae8ec18583c926a5e20953d184718763eceb8a268dffc6e4c2ae5e6192fcdb97fd29aa4760c22
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"find-up@npm:^1.0.0":
|
||||
version: 1.1.2
|
||||
resolution: "find-up@npm:1.1.2"
|
||||
|
@ -9734,6 +9856,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"flatbuffers@npm:1.11.0":
|
||||
version: 1.11.0
|
||||
resolution: "flatbuffers@npm:1.11.0"
|
||||
checksum: 124889409411c57033c7b1e27525357adfa9234eb7e657693338cbbafdb871ce925cc074644696a917e65a95133594e16c5d6a1c871eb16bd6df1eafb7b82fbd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"flatted@npm:^3.1.0":
|
||||
version: 3.1.1
|
||||
resolution: "flatted@npm:3.1.1"
|
||||
|
@ -10447,7 +10576,7 @@ fsevents@^1.2.7:
|
|||
"@typescript-eslint/parser": ^4.23.0
|
||||
"@yarnpkg/pnpify": ^2.4.0
|
||||
ahooks: ^2.10.6
|
||||
arquero: ^0.13.3
|
||||
arquero: ^4.8.4
|
||||
concurrently: ^5.3.0
|
||||
core-js: ^3.12.0
|
||||
d3-array: ^2.8.0
|
||||
|
@ -12621,6 +12750,13 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"json-bignum@npm:^0.0.3":
|
||||
version: 0.0.3
|
||||
resolution: "json-bignum@npm:0.0.3"
|
||||
checksum: e64b69089fa6760ef6373138754fece6467110a769a57991f6c9f0abf203413606540200e0682c8d3b377421aa9584eeccfaef424f7d8253b3b74c6b670b2fab
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"json-buffer@npm:3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "json-buffer@npm:3.0.0"
|
||||
|
@ -13127,6 +13263,13 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.camelcase@npm:^4.3.0":
|
||||
version: 4.3.0
|
||||
resolution: "lodash.camelcase@npm:4.3.0"
|
||||
checksum: cb9227612f71b83e42de93eccf1232feeb25e705bdb19ba26c04f91e885bfd3dd5c517c4a97137658190581d3493ea3973072ca010aab7e301046d90740393d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.clonedeep@npm:^4.5.0":
|
||||
version: 4.5.0
|
||||
resolution: "lodash.clonedeep@npm:4.5.0"
|
||||
|
@ -13183,6 +13326,13 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.padend@npm:^4.6.1":
|
||||
version: 4.6.1
|
||||
resolution: "lodash.padend@npm:4.6.1"
|
||||
checksum: c2e6e789debf83b98f5c085305cdcfff1067e7a31bda2a110fd765d3c11a99edfbeef570d9ef737ab3212006bdb8114e77622e518c18c1fce52b8fdfd9dab685
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lodash.throttle@npm:^4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "lodash.throttle@npm:4.1.1"
|
||||
|
@ -14052,6 +14202,15 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-fetch@npm:^2.6.2":
|
||||
version: 2.6.6
|
||||
resolution: "node-fetch@npm:2.6.6"
|
||||
dependencies:
|
||||
whatwg-url: ^5.0.0
|
||||
checksum: ee8290626bdb73629c59722b75dcf4b9b6a67c1ed7eb9102e368479c4a13b56a48c2bb3ad71571e378e98c8b2c64c820e11f9cd39e4b8557dd138ad571ef9a42
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-forge@npm:^0.10.0":
|
||||
version: 0.10.0
|
||||
resolution: "node-forge@npm:0.10.0"
|
||||
|
@ -14824,6 +14983,15 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pad-left@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "pad-left@npm:2.1.0"
|
||||
dependencies:
|
||||
repeat-string: ^1.5.4
|
||||
checksum: a1605c3cb0ebd9be1a74f7f895524d3bf30f24492db87421c2fda9b8c0fcee17b3b594dacfb5eb1d3189d59c69d2f969677bc04b8280a7ef6303566154dbd078
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pako@npm:~1.0.5":
|
||||
version: 1.0.11
|
||||
resolution: "pako@npm:1.0.11"
|
||||
|
@ -15871,6 +16039,18 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"re-resizable@npm:6.9.1":
|
||||
version: 6.9.1
|
||||
resolution: "re-resizable@npm:6.9.1"
|
||||
dependencies:
|
||||
fast-memoize: ^2.5.1
|
||||
peerDependencies:
|
||||
react: ^16.13.1 || ^17.0.0
|
||||
react-dom: ^16.13.1 || ^17.0.0
|
||||
checksum: b164f6b956dc1f45b6c2603f0f402b04df8306017c59d68a9a71a2c857049a314a01c3fb7aedba66d8c60c4ccf9aa182c345276825eed745e5b847b6f104d78e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-animate-height@npm:^2.0.23":
|
||||
version: 2.0.23
|
||||
resolution: "react-animate-height@npm:2.0.23"
|
||||
|
@ -15945,7 +16125,18 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-rnd@npm:*, react-rnd@npm:^10.2.3":
|
||||
"react-rnd@npm:*":
|
||||
version: 10.3.5
|
||||
resolution: "react-rnd@npm:10.3.5"
|
||||
dependencies:
|
||||
re-resizable: 6.9.1
|
||||
react-draggable: 4.4.3
|
||||
tslib: 2.3.0
|
||||
checksum: 2171e3119acbc7e2778f5e18d84fec66a0cad3984f83f733b06dc174142b4c65c45dc954db69121881e6d36b7fc30b8a6b5e6603f64160135b400b239c184ddd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-rnd@npm:^10.2.3":
|
||||
version: 10.3.0
|
||||
resolution: "react-rnd@npm:10.3.0"
|
||||
dependencies:
|
||||
|
@ -16175,6 +16366,13 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reduce-flatten@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "reduce-flatten@npm:1.0.1"
|
||||
checksum: 5e5a450500ece8dfff95ecd0b34f48941084c00fdc63e6a4413f758334d2d3f8b4d725670896c04853c477c062af03402aeb5e145b948e03abc914ee51bb3b89
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reflect-metadata@npm:^0.1.13":
|
||||
version: 0.1.13
|
||||
resolution: "reflect-metadata@npm:0.1.13"
|
||||
|
@ -16346,7 +16544,7 @@ fsevents@^1.2.7:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"repeat-string@npm:^1.6.1":
|
||||
"repeat-string@npm:^1.5.4, repeat-string@npm:^1.6.1":
|
||||
version: 1.6.1
|
||||
resolution: "repeat-string@npm:1.6.1"
|
||||
checksum: 1b809fc6db97decdc68f5b12c4d1a671c8e3f65ec4a40c238bc5200e44e85bcc52a54f78268ab9c29fcf5fe4f1343e805420056d1f30fa9a9ee4c2d93e3cc6c0
|
||||
|
@ -17988,6 +18186,19 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"table-layout@npm:^0.4.3":
|
||||
version: 0.4.5
|
||||
resolution: "table-layout@npm:0.4.5"
|
||||
dependencies:
|
||||
array-back: ^2.0.0
|
||||
deep-extend: ~0.6.0
|
||||
lodash.padend: ^4.6.1
|
||||
typical: ^2.6.1
|
||||
wordwrapjs: ^3.0.0
|
||||
checksum: 9642b67d1bb3d9ba85f2b95f0a65a12ec7e1186ce842c9be63f1fdf76e36e91be89955b58b7a16358e1b39a12ceb9860c41ed977d8305d792651c19f08e3f8f2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"table@npm:^6.0.4, table@npm:^6.0.9":
|
||||
version: 6.7.1
|
||||
resolution: "table@npm:6.7.1"
|
||||
|
@ -18144,6 +18355,23 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"test-value@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "test-value@npm:3.0.0"
|
||||
dependencies:
|
||||
array-back: ^2.0.0
|
||||
typical: ^2.6.1
|
||||
checksum: 5bac284cbe4b8e2024f987854952424925ba607c22e0af1b88020484e9d77d6b85e301c61f95f8f27f9eda58e4439d99056318f8b649bbc79f43e125f4f63f0b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"text-encoding-utf-8@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "text-encoding-utf-8@npm:1.0.2"
|
||||
checksum: ec4c15d50e738c5dba7327ad432ebf0725ec75d4d69c0bd55609254c5a3bc5341272d7003691084a0a73d60d981c8eb0e87603676fdb6f3fed60f4c9192309f9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"text-extensions@npm:^1.0.0":
|
||||
version: 1.9.0
|
||||
resolution: "text-extensions@npm:1.9.0"
|
||||
|
@ -18402,6 +18630,13 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tr46@npm:~0.0.3":
|
||||
version: 0.0.3
|
||||
resolution: "tr46@npm:0.0.3"
|
||||
checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tree-kill@npm:^1.2.2":
|
||||
version: 1.2.2
|
||||
resolution: "tree-kill@npm:1.2.2"
|
||||
|
@ -18503,7 +18738,14 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tslib@npm:^1.10.0, tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0":
|
||||
"tslib@npm:2.3.0":
|
||||
version: 2.3.0
|
||||
resolution: "tslib@npm:2.3.0"
|
||||
checksum: 8869694c26e4a7b56d449662fd54a4f9ba872c889d991202c74462bd99f10e61d5bd63199566c4284c0f742277736292a969642cc7b590f98727a7cae9529122
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tslib@npm:^1.10.0, tslib@npm:^1.12.0, tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0":
|
||||
version: 1.14.1
|
||||
resolution: "tslib@npm:1.14.1"
|
||||
checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd
|
||||
|
@ -18738,6 +18980,13 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typical@npm:^2.6.1":
|
||||
version: 2.6.1
|
||||
resolution: "typical@npm:2.6.1"
|
||||
checksum: 6af04fefe50d90d3471f058b2cdc0f49b7436bdd605cd00acea7965926ff388a5a7d692ef144f45fccee6f8e896c065702ecc44b69057e2ce88c09e897c7d3a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uglify-js@npm:^3.1.4":
|
||||
version: 3.13.7
|
||||
resolution: "uglify-js@npm:3.13.7"
|
||||
|
@ -19291,6 +19540,13 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webidl-conversions@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "webidl-conversions@npm:3.0.1"
|
||||
checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webidl-conversions@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "webidl-conversions@npm:5.0.0"
|
||||
|
@ -19506,6 +19762,16 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-url@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "whatwg-url@npm:5.0.0"
|
||||
dependencies:
|
||||
tr46: ~0.0.3
|
||||
webidl-conversions: ^3.0.0
|
||||
checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-url@npm:^8.0.0, whatwg-url@npm:^8.5.0":
|
||||
version: 8.5.0
|
||||
resolution: "whatwg-url@npm:8.5.0"
|
||||
|
@ -19605,6 +19871,16 @@ resolve@^2.0.0-next.3:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"wordwrapjs@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "wordwrapjs@npm:3.0.0"
|
||||
dependencies:
|
||||
reduce-flatten: ^1.0.1
|
||||
typical: ^2.6.1
|
||||
checksum: 953322ec8dd8b634a1a07a611760b0473e258073fd3bcab473082c6f0f30cdc48e641310209973d8557b9893bc291e32587f6dce05ea675242e21f8b0b0877bc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"worker-farm@npm:^1.7.0":
|
||||
version: 1.7.0
|
||||
resolution: "worker-farm@npm:1.7.0"
|
||||
|
|
Загрузка…
Ссылка в новой задаче