diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 6398c5d7b..d80b31d8a 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -1,6 +1,9 @@
name: Cypress Percy Tests
-on: [push]
+on:
+ push:
+ branches:
+ - main
jobs:
build:
diff --git a/package.json b/package.json
index 7d91ce548..bc298218e 100644
--- a/package.json
+++ b/package.json
@@ -67,8 +67,5 @@
},
"lint-staged": {
"*.{js,ts,jsx,tsx,svelte}": "eslint --quiet --cache --fix"
- },
- "dependencies": {
- "seedrandom": "^3.0.5"
}
}
diff --git a/packages/dev/cypress.config.ts b/packages/dev/cypress.config.ts
index 8d8196fad..fb434cdfc 100644
--- a/packages/dev/cypress.config.ts
+++ b/packages/dev/cypress.config.ts
@@ -1,5 +1,4 @@
import { defineConfig } from 'cypress'
-// import webpackConfig from './webpack.config'
export default defineConfig({
e2e: {
diff --git a/packages/dev/cypress/e2e/unovis.cy.ts b/packages/dev/cypress/e2e/unovis.cy.ts
index 32e4a0c79..af233cf6a 100644
--- a/packages/dev/cypress/e2e/unovis.cy.ts
+++ b/packages/dev/cypress/e2e/unovis.cy.ts
@@ -1,3 +1,5 @@
+const scopeSelector = '.exampleViewer'
+
describe('Unovis Test', () => {
beforeEach(() => {
cy.visit('/')
@@ -10,349 +12,349 @@ describe('Unovis Test', () => {
it('Basic Annotation', () => {
cy.contains('Basic Annotations').click()
cy.wait(3000)
- cy.percySnapshot('Basic Annotation', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Annotation', { scope: scopeSelector })
})
it('Single Container', () => {
cy.contains('Single Container').click()
cy.wait(3000)
- cy.percySnapshot('Single Container', { scope: '.exampleViewer' })
+ cy.percySnapshot('Single Container', { scope: scopeSelector })
})
it('Bullet Shapes', () => {
cy.contains('Bullet Shapes').click()
cy.wait(3000)
- cy.percySnapshot('Bullet Shapes', { scope: '.exampleViewer' })
+ cy.percySnapshot('Bullet Shapes', { scope: scopeSelector })
})
it('Basic Bullet Legend', () => {
cy.contains('Basic Bullet Legend').click()
cy.wait(3000)
- cy.percySnapshot('Basic Bullet Legend', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Bullet Legend', { scope: scopeSelector })
})
it('Line Legend', () => {
cy.contains('Line Legend').click()
cy.wait(3000)
- cy.percySnapshot('Line Legend', { scope: '.exampleViewer' })
+ cy.percySnapshot('Line Legend', { scope: scopeSelector })
})
it('Shape Legend', () => {
cy.contains('Shape Legend').click()
cy.wait(3000)
- cy.percySnapshot('Shape Legend', { scope: '.exampleViewer' })
+ cy.percySnapshot('Shape Legend', { scope: scopeSelector })
})
it('Vertical Legend', () => {
cy.contains('Vertical Legend').click()
cy.wait(3000)
- cy.percySnapshot('Vertical Legend', { scope: '.exampleViewer' })
+ cy.percySnapshot('Vertical Legend', { scope: scopeSelector })
})
it('Scrollable Container Comparison', () => {
cy.contains('Scrollable Container Comparison').click()
cy.wait(3000)
- cy.percySnapshot('Scrollable Container Comparison', { scope: '.exampleViewer' })
+ cy.percySnapshot('Scrollable Container Comparison', { scope: scopeSelector })
})
it('Light and Dark Theme', () => {
cy.contains('Light and Dark Theme').click()
cy.wait(6000)
- cy.percySnapshot('Light and Dark Theme', { scope: '.exampleViewer' })
+ cy.percySnapshot('Light and Dark Theme', { scope: scopeSelector })
})
it('Raster Leaflet Map', () => {
cy.contains('Raster Leaflet Map').click()
cy.wait(3000)
- cy.percySnapshot('Raster Leaflet Map', { scope: '.exampleViewer' })
+ cy.percySnapshot('Raster Leaflet Map', { scope: scopeSelector })
})
it('Vector Map', () => {
cy.contains('Vector Map').click()
cy.wait(3000)
- cy.percySnapshot('Vector Map', { scope: '.exampleViewer' })
+ cy.percySnapshot('Vector Map', { scope: scopeSelector })
})
it('Donut: Empty Segments', () => {
cy.contains('Donut: Empty Segments').click()
cy.wait(3000)
- cy.percySnapshot('Donut: Empty Segments', { scope: '.exampleViewer' })
+ cy.percySnapshot('Donut: Empty Segments', { scope: scopeSelector })
})
it('Donut Data Transitions', () => {
cy.contains('Donut Data Transitions').click()
cy.wait(3000)
- cy.percySnapshot('Donut Data Transitions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Donut Data Transitions', { scope: scopeSelector })
})
it('Basic Nested Donut', () => {
cy.contains('Basic Nested Donut').click()
cy.wait(3000)
- cy.percySnapshot('Basic Nested Donut', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Nested Donut', { scope: scopeSelector })
})
it('Nested Donut Data Transitions', () => {
cy.contains('Nested Donut Data Transitions').click()
cy.wait(3000)
- cy.percySnapshot('Nested Donut Data Transitions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Nested Donut Data Transitions', { scope: scopeSelector })
})
it('Interactive Nested Donut', () => {
cy.contains('Interactive Nested Donut').click()
cy.wait(3000)
- cy.percySnapshot('Interactive Nested Donut', { scope: '.exampleViewer' })
+ cy.percySnapshot('Interactive Nested Donut', { scope: scopeSelector })
})
it('Segment labels', () => {
cy.contains('Segment labels').click()
cy.wait(3000)
- cy.percySnapshot('Segment labels', { scope: '.exampleViewer' })
+ cy.percySnapshot('Segment labels', { scope: scopeSelector })
})
it('Nested Donut Layer Configuration', () => {
cy.contains('Nested Donut Layer Configuration').click()
cy.wait(3000)
- cy.percySnapshot('Nested Donut Layer Configurationt', { scope: '.exampleViewer' })
+ cy.percySnapshot('Nested Donut Layer Configurationt', { scope: scopeSelector })
})
it('Segment values', () => {
cy.contains('Segment values').click()
cy.wait(3000)
- cy.percySnapshot('Segment values', { scope: '.exampleViewer' })
+ cy.percySnapshot('Segment values', { scope: scopeSelector })
})
it('Empty Segments', () => {
cy.contains('Empty Segments').click()
cy.wait(3000)
- cy.percySnapshot('Empty Segments', { scope: '.exampleViewer' })
+ cy.percySnapshot('Empty Segments', { scope: scopeSelector })
})
it('Chord Diagram Hierarchy Nodes', () => {
cy.contains('Chord Diagram Hierarchy').click()
cy.wait(5000)
- cy.percySnapshot('Chord Diagram Hierarchy Nodes', { scope: '.exampleViewer' })
+ cy.percySnapshot('Chord Diagram Hierarchy Nodes', { scope: scopeSelector })
})
it('Node Levels', () => {
cy.contains('Node Levels').click()
cy.wait(3000)
- cy.percySnapshot('Node Levels', { scope: '.exampleViewer' })
+ cy.percySnapshot('Node Levels', { scope: scopeSelector })
})
it('Basic Chord Diagram', () => {
cy.contains('Basic Chord Diagram').click()
cy.wait(5000)
- cy.percySnapshot('Basic Chord Diagram', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Chord Diagram', { scope: scopeSelector })
})
it('Labels and Radius Scale Exponent', () => {
cy.contains('Labels and Radius Scale Exponent').click()
cy.wait(3000)
- cy.percySnapshot('Labels and Radius Scale Exponent', { scope: '.exampleViewer' })
+ cy.percySnapshot('Labels and Radius Scale Exponent', { scope: scopeSelector })
})
it('Chord Diagram Node Selection', () => {
cy.contains('Chord Diagram Node').click()
cy.wait(3000)
- cy.percySnapshot('Chord Diagram Node Selection', { scope: '.exampleViewer' })
+ cy.percySnapshot('Chord Diagram Node Selection', { scope: scopeSelector })
})
it('Graph: Custom Node Fills', () => {
cy.contains('Graph: Custom Node Fills').click()
cy.wait(3000)
- cy.percySnapshot('Graph: Custom Node Fills', { scope: '.exampleViewer' })
+ cy.percySnapshot('Graph: Custom Node Fills', { scope: scopeSelector })
})
it('Graph: SVG Node Icons', () => {
cy.contains('Graph: SVG Node Icons').click()
cy.wait(3000)
- cy.percySnapshot('Graph: SVG Node Icons', { scope: '.exampleViewer' })
+ cy.percySnapshot('Graph: SVG Node Icons', { scope: scopeSelector })
})
it('Dynamic Layout', () => {
cy.contains('Dynamic Layout').click()
cy.wait(3000)
- cy.percySnapshot('Dynamic Layout', { scope: '.exampleViewer' })
+ cy.percySnapshot('Dynamic Layout', { scope: scopeSelector })
})
it('Layout: ELK', () => {
cy.contains('Layout: ELK').click()
cy.wait(3000)
- cy.percySnapshot('Layout: ELK', { scope: '.exampleViewer' })
+ cy.percySnapshot('Layout: ELK', { scope: scopeSelector })
})
it('Link Arrows', () => {
cy.contains('Link Arrows').click()
cy.wait(3000)
- cy.percySnapshot('Link Arrows', { scope: '.exampleViewer' })
+ cy.percySnapshot('Link Arrows', { scope: scopeSelector })
})
it('Node and Link Circle Labels', () => {
cy.contains('Node and Link Circle Labels').click()
cy.wait(3000)
- cy.percySnapshot('Node and Link Circle Labels', { scope: '.exampleViewer' })
+ cy.percySnapshot('Node and Link Circle Labels', { scope: scopeSelector })
})
it('Graph Brushing', () => {
cy.contains('Graph Brushing').click()
cy.wait(3000)
- cy.percySnapshot('Graph Brushing', { scope: '.exampleViewer' })
+ cy.percySnapshot('Graph Brushing', { scope: scopeSelector })
})
it('Node Labels and Sub-labels', () => {
cy.contains('Node Labels and Sub-labels').click()
cy.wait(3000)
- cy.percySnapshot('Node Labels and Sub-labels', { scope: '.exampleViewer' })
+ cy.percySnapshot('Node Labels and Sub-labels', { scope: scopeSelector })
})
it('Graph: Node Positions', () => {
cy.contains('Graph: Node Positions').click()
cy.wait(3000)
- cy.percySnapshot('Graph: Node Positions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Graph: Node Positions', { scope: scopeSelector })
})
it('Graph: Node Selection', () => {
cy.contains('Graph: Node Selection').click()
cy.wait(3000)
- cy.percySnapshot('Graph: Node Selection', { scope: '.exampleViewer' })
+ cy.percySnapshot('Graph: Node Selection', { scope: scopeSelector })
})
it('Sankey Data Transitions', () => {
cy.contains('Sankey Data Transitions').click()
cy.wait(3000)
- cy.percySnapshot('Sankey Data Transitions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Sankey Data Transitions', { scope: scopeSelector })
})
it('API Endpoints Tree', () => {
cy.contains('API Endpoints Tree').click()
cy.wait(3000)
- cy.percySnapshot('API Endpoints Tree', { scope: '.exampleViewer', widths: [1300], minHeight: 2400 })
+ cy.percySnapshot('API Endpoints Tree', { scope: scopeSelector, widths: [1300], minHeight: 2400 })
})
it('Area Chart with Baseline', () => {
cy.contains('Area Chart with Baseline').click()
cy.wait(3000)
- cy.percySnapshot('Area Chart with Baseline', { scope: '.exampleViewer' })
+ cy.percySnapshot('Area Chart with Baseline', { scope: scopeSelector })
})
it('Basic Area Chart', () => {
cy.contains('Basic Area Chart').click()
cy.wait(3000)
- cy.percySnapshot('Basic Area Chart', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Area Chart', { scope: scopeSelector })
})
it('Area Data Transitions', () => {
cy.contains('Area Data Transitions').click()
cy.wait(3000)
- cy.percySnapshot('Area Data Transitions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Area Data Transitions', { scope: scopeSelector })
})
it('Axis with Ticks Rotation', () => {
cy.contains('Axis with Ticks Rotation').click()
cy.wait(3000)
- cy.percySnapshot('Axis with Ticks Rotation', { scope: '.exampleViewer' })
+ cy.percySnapshot('Axis with Ticks Rotation', { scope: scopeSelector })
})
it('Axis', () => {
cy.contains('Axis').click()
cy.wait(3000)
- cy.percySnapshot('Axis', { scope: '.exampleViewer' })
+ cy.percySnapshot('Axis', { scope: scopeSelector })
})
it('Custom Style Brush', () => {
cy.contains('Custom Style Brush').click()
cy.wait(3000)
- cy.percySnapshot('Custom Style Brush', { scope: '.exampleViewer' })
+ cy.percySnapshot('Custom Style Brush', { scope: scopeSelector })
})
it('Stacked vs Non-Stacked', () => {
cy.contains('Stacked vs Non-Stacked').click()
cy.wait(3000)
- cy.percySnapshot('Stacked vs Non-Stacked', { scope: '.exampleViewer' })
+ cy.percySnapshot('Stacked vs Non-Stacked', { scope: scopeSelector })
})
it('Dual Axis Chart', () => {
cy.contains('Dual Axis Chart').click()
cy.wait(3000)
- cy.percySnapshot('Dual Axis Chart', { scope: '.exampleViewer' })
+ cy.percySnapshot('Dual Axis Chart', { scope: scopeSelector })
})
it('Basic Grouped Bar Chart', () => {
cy.contains('Basic Grouped Bar Chart').click()
cy.wait(3000)
- cy.percySnapshot('Basic Grouped Bar Chart', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Grouped Bar Chart', { scope: scopeSelector })
})
it('Grouped Bar Chart', () => {
cy.contains('Grouped Bar Chart').click()
cy.wait(3000)
- cy.percySnapshot('Grouped Bar Chart', { scope: '.exampleViewer' })
+ cy.percySnapshot('Grouped Bar Chart', { scope: scopeSelector })
})
it('Multi Line Chart', () => {
cy.contains('Multi Line Chart').click()
cy.wait(3000)
- cy.percySnapshot('Multi Line Chart', { scope: '.exampleViewer' })
+ cy.percySnapshot('Multi Line Chart', { scope: scopeSelector })
})
it('Points with labels', () => {
cy.contains('Points with labels').click()
cy.wait(3000)
- cy.percySnapshot('Points with labels', { scope: '.exampleViewer' })
+ cy.percySnapshot('Points with labels', { scope: scopeSelector })
})
it('Points with stroke', () => {
cy.contains('Points with stroke').click()
cy.wait(3000)
- cy.percySnapshot('Points with stroke', { scope: '.exampleViewer' })
+ cy.percySnapshot('Points with stroke', { scope: scopeSelector })
})
it('Scatter with Line', () => {
cy.contains('Scatter with Line').click()
cy.wait(3000)
- cy.percySnapshot('Scatter with Line', { scope: '.exampleViewer' })
+ cy.percySnapshot('Scatter with Line', { scope: scopeSelector })
})
it('Basic Stacked Bar Chart', () => {
cy.contains('Basic Stacked Bar Chart').click()
cy.wait(3000)
- cy.percySnapshot('Basic Stacked Bar Chart', { scope: '.exampleViewer' })
+ cy.percySnapshot('Basic Stacked Bar Chart', { scope: scopeSelector })
})
it('Stacked Bar Data Transitions', () => {
cy.contains('Stacked Bar Data Transitions').click()
cy.wait(3000)
- cy.percySnapshot('Stacked Bar Data Transitions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Stacked Bar Data Transitions', { scope: scopeSelector })
})
it('Timeline Data Transitions', () => {
cy.contains('Timeline Data Transitions').click()
cy.wait(3000)
- cy.percySnapshot('Timeline Data Transitions', { scope: '.exampleViewer' })
+ cy.percySnapshot('Timeline Data Transitions', { scope: scopeSelector })
})
it('Timeline: Negative Lengths', () => {
cy.contains('Timeline: Negative Lengths').click()
cy.wait(3000)
- cy.percySnapshot('Timeline: Negative Lengths', { scope: '.exampleViewer' })
+ cy.percySnapshot('Timeline: Negative Lengths', { scope: scopeSelector })
})
it('Tooltip and Scrolling', () => {
cy.contains('Tooltip and Scrolling').click()
cy.wait(3000)
- cy.percySnapshot('Tooltip and Scrolling', { scope: '.exampleViewer' })
+ cy.percySnapshot('Tooltip and Scrolling', { scope: scopeSelector })
})
it('Scale by Domain', () => {
cy.contains('Scale by Domain').click()
cy.wait(3000)
- cy.percySnapshot('Scale by Domain', { scope: '.exampleViewer' })
+ cy.percySnapshot('Scale by Domain', { scope: scopeSelector })
})
it('Stacked Bar with Labels', () => {
cy.contains('Stacked Bar with Labels').click()
cy.wait(3000)
- cy.percySnapshot('Stacked Bar with Labels', { scope: '.exampleViewer' })
+ cy.percySnapshot('Stacked Bar with Labels', { scope: scopeSelector })
})
})
diff --git a/packages/dev/cypress/fixtures/example.json b/packages/dev/cypress/fixtures/example.json
deleted file mode 100644
index 02e425437..000000000
--- a/packages/dev/cypress/fixtures/example.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "Using fixtures to represent data",
- "email": "hello@cypress.io",
- "body": "Fixtures are a great way to mock data for responses to routes"
-}
diff --git a/packages/dev/cypress/support/commands.ts b/packages/dev/cypress/support/commands.ts
deleted file mode 100644
index 95857aea4..000000000
--- a/packages/dev/cypress/support/commands.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-///
-// ***********************************************
-// This example commands.ts shows you how to
-// create various custom commands and overwrite
-// existing commands.
-//
-// For more comprehensive examples of custom
-// commands please read more here:
-// https://on.cypress.io/custom-commands
-// ***********************************************
-//
-//
-// -- This is a parent command --
-// Cypress.Commands.add('login', (email, password) => { ... })
-//
-//
-// -- This is a child command --
-// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
-//
-//
-// -- This is a dual command --
-// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
-//
-//
-// -- This will overwrite an existing command --
-// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
-//
-// declare global {
-// namespace Cypress {
-// interface Chainable {
-// login(email: string, password: string): Chainable
-// drag(subject: string, options?: Partial): Chainable
-// dismiss(subject: string, options?: Partial): Chainable
-// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
-// }
-// }
-// }
diff --git a/packages/dev/package-lock.json b/packages/dev/package-lock.json
index 59f9522cf..e93040f41 100644
--- a/packages/dev/package-lock.json
+++ b/packages/dev/package-lock.json
@@ -14,6 +14,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.5",
+ "seedrandom": "^3.0.5",
"serve": "^14.2.3"
},
"devDependencies": {
@@ -6980,6 +6981,11 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/seedrandom": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
+ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
+ },
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
diff --git a/packages/dev/package.json b/packages/dev/package.json
index 153759339..b5c21c75b 100644
--- a/packages/dev/package.json
+++ b/packages/dev/package.json
@@ -33,6 +33,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.5",
+ "seedrandom": "^3.0.5",
"serve": "^14.2.3"
},
"peerDependencies": {
diff --git a/packages/dev/src/examples/auxiliary/annotations/basic-annotations/index.tsx b/packages/dev/src/examples/auxiliary/annotations/basic-annotations/index.tsx
index f5d317ef9..01b35a9e9 100644
--- a/packages/dev/src/examples/auxiliary/annotations/basic-annotations/index.tsx
+++ b/packages/dev/src/examples/auxiliary/annotations/basic-annotations/index.tsx
@@ -1,7 +1,7 @@
import React, { useEffect, useRef, useState } from 'react'
import { VisXYContainer, VisLine, VisAxis, VisAnnotations, VisLineRef } from '@unovis/react'
import { AnnotationItem } from '@unovis/ts'
-import { rng } from '@src/utils/data'
+import { randomNumberGenerator } from '@src/utils/data'
export const title = 'Basic Annotations'
export const subTitle = 'Dynamic Data Updates'
@@ -11,7 +11,7 @@ export const component = (): JSX.Element => {
const length = 10
const min = 3
const max = 8
- const generateData = (): number[] => Array.from({ length }, () => rng() * (max - min) + min)
+ const generateData = (): number[] => Array.from({ length }, () => randomNumberGenerator() * (max - min) + min)
const ref = useRef>(null)
const [data, setData] = useState(generateData)
diff --git a/packages/dev/src/examples/auxiliary/bullet-legend/legend-stacked-bar-donut/index.tsx b/packages/dev/src/examples/auxiliary/bullet-legend/legend-stacked-bar-donut/index.tsx
index 4e46da4d2..b09248d04 100644
--- a/packages/dev/src/examples/auxiliary/bullet-legend/legend-stacked-bar-donut/index.tsx
+++ b/packages/dev/src/examples/auxiliary/bullet-legend/legend-stacked-bar-donut/index.tsx
@@ -1,7 +1,7 @@
import React from 'react'
import { sum } from 'd3-array'
import { VisBulletLegend, VisSingleContainer, VisDonut, VisXYContainer, VisStackedBar } from '@unovis/react'
-import { rng } from '@src/utils/data'
+import { randomNumberGenerator } from '@src/utils/data'
import s from './styles.module.css'
@@ -17,7 +17,7 @@ export const component = (): JSX.Element => {
const items = Array(6).fill(0).map((_, i) => ({ name: `y${i}` }))
const data = Array(10).fill(0).map((_, i) => ({
x: i,
- ys: items.map(() => rng()),
+ ys: items.map(() => randomNumberGenerator()),
}))
const accessors = items.map((_, i) => (d: DataRecord) => d.ys[i])
diff --git a/packages/dev/src/examples/auxiliary/bullet-legend/vertical-legend/index.tsx b/packages/dev/src/examples/auxiliary/bullet-legend/vertical-legend/index.tsx
index b9a32f47a..0f55a5265 100644
--- a/packages/dev/src/examples/auxiliary/bullet-legend/vertical-legend/index.tsx
+++ b/packages/dev/src/examples/auxiliary/bullet-legend/vertical-legend/index.tsx
@@ -1,7 +1,7 @@
import React from 'react'
import { VisBulletLegend, VisXYContainer, VisAxis, VisStackedBar } from '@unovis/react'
import { BulletLegendOrientation } from '@unovis/ts'
-import { rng } from '@src/utils/data'
+import { randomNumberGenerator } from '@src/utils/data'
import s from './styles.module.css'
@@ -17,7 +17,7 @@ const data = Array.from({ length: 150 }, (_, i) => ({
...seriesLabels
.reduce((acc, label) => ({
...acc,
- [label]: label.length + rng() * 5,
+ [label]: label.length + randomNumberGenerator() * 5,
}), {} as Record),
}))
diff --git a/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-levels/index.tsx b/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-levels/index.tsx
index 2baac142a..29b87a4a9 100644
--- a/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-levels/index.tsx
+++ b/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-levels/index.tsx
@@ -1,5 +1,6 @@
import React from 'react'
import { VisSingleContainer, VisChordDiagram } from '@unovis/react'
+import { randomNumberGenerator } from '@src/utils/data'
export const title = 'Node Levels'
export const subTitle = 'Side by side comparison'
@@ -22,7 +23,7 @@ const data = {
{ source: 'B0', target: 'C1' },
{ source: 'B1', target: 'C2' },
{ source: 'C0', target: 'A2' },
- ].map((l) => ({ ...l, value: Math.random() })),
+ ].map((l) => ({ ...l, value: randomNumberGenerator() })),
}
export const component = (): JSX.Element => {
return (
diff --git a/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-perpendicular-labels/data.ts b/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-perpendicular-labels/data.ts
index 8022e9660..c6b19d22b 100644
--- a/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-perpendicular-labels/data.ts
+++ b/packages/dev/src/examples/networks-and-flows/chord-diagram/chord-diagram-perpendicular-labels/data.ts
@@ -1,3 +1,4 @@
+import { randomNumberGenerator } from '@src/utils/data'
export type NodeDatum = { group: string; color: string; id: string }
export type LinkDatum = { source: string; target: string }
@@ -17,8 +18,8 @@ export function getData (): { nodes: NodeDatum[]; links: LinkDatum[] } {
data.nodes.push(...Array(count).fill(0).map((_, i) => ({ ...n, id: `${n.group}${i}` })))
links.forEach((x, index) => {
data.links.push(...Array(x).fill(0).map(() => ({
- source: `${n.group}${Math.floor(Math.random() * count)}`,
- target: `${groups[index].group}${Math.floor(Math.random() * groups[index].count)}`,
+ source: `${n.group}${Math.floor(randomNumberGenerator() * count)}`,
+ target: `${groups[index].group}${Math.floor(randomNumberGenerator() * groups[index].count)}`,
})))
})
})
diff --git a/packages/dev/src/examples/networks-and-flows/graph/graph-dynamic-layout/index.tsx b/packages/dev/src/examples/networks-and-flows/graph/graph-dynamic-layout/index.tsx
index 98b72cfe4..c05a36238 100644
--- a/packages/dev/src/examples/networks-and-flows/graph/graph-dynamic-layout/index.tsx
+++ b/packages/dev/src/examples/networks-and-flows/graph/graph-dynamic-layout/index.tsx
@@ -1,7 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react'
import { VisSingleContainer, VisGraph } from '@unovis/react'
import { GraphLayoutType } from '@unovis/ts'
-import { generateNodeLinkData, rng } from '@src/utils/data'
+import { generateNodeLinkData, randomNumberGenerator } from '@src/utils/data'
export const title = 'Dynamic Layout'
export const subTitle = 'Select Layout From Dropdown'
@@ -15,12 +15,12 @@ export const component = (): JSX.Element => {
// Generate new data every 2 seconds
useEffect(() => {
setTimeout(() => {
- const newData = generateNodeLinkData(10 + Math.floor(rng() * 50))
+ const newData = generateNodeLinkData(10 + Math.floor(randomNumberGenerator() * 50))
// Adding some random x, y values to the nodes for `GraphLayoutType.Precalculated`
newData.nodes.forEach(n => {
- n.x = rng() * 1000
- n.y = rng() * 1000
+ n.x = randomNumberGenerator() * 1000
+ n.y = randomNumberGenerator() * 1000
})
setData(newData)
diff --git a/packages/dev/src/examples/networks-and-flows/graph/graph-link-label/index.tsx b/packages/dev/src/examples/networks-and-flows/graph/graph-link-label/index.tsx
index cf6797ed1..74e515e89 100644
--- a/packages/dev/src/examples/networks-and-flows/graph/graph-link-label/index.tsx
+++ b/packages/dev/src/examples/networks-and-flows/graph/graph-link-label/index.tsx
@@ -1,6 +1,6 @@
import React from 'react'
import { VisSingleContainer, VisGraph } from '@unovis/react'
-import { generateNodeLinkData, NodeDatum, LinkDatum, rng } from '@src/utils/data'
+import { generateNodeLinkData, NodeDatum, LinkDatum, randomNumberGenerator } from '@src/utils/data'
import { GraphCircleLabel } from '@unovis/ts'
export const title = 'Node and Link Circle Labels'
@@ -9,11 +9,11 @@ export const subTitle = 'with custom configuration'
export const component = (): JSX.Element => {
const data = generateNodeLinkData(15)
const linkLabels: GraphCircleLabel[] = data.links.map((link, i) => {
- const hasCustomAppearance = rng() > 0.8
+ const hasCustomAppearance = randomNumberGenerator() > 0.8
return {
text: hasCustomAppearance ? `${i}${i}${i}` : `${i * 10}`,
fontSize: hasCustomAppearance ? '8px' : undefined,
- radius: hasCustomAppearance ? 0 : 5 + 10 * rng(),
+ radius: hasCustomAppearance ? 0 : 5 + 10 * randomNumberGenerator(),
cursor: 'pointer',
textColor: hasCustomAppearance ? 'blue' : undefined,
}
diff --git a/packages/dev/src/examples/networks-and-flows/graph/graph-node-labels/index.tsx b/packages/dev/src/examples/networks-and-flows/graph/graph-node-labels/index.tsx
index 2a02f307c..9dd08b0b9 100644
--- a/packages/dev/src/examples/networks-and-flows/graph/graph-node-labels/index.tsx
+++ b/packages/dev/src/examples/networks-and-flows/graph/graph-node-labels/index.tsx
@@ -1,7 +1,7 @@
import React from 'react'
import { VisSingleContainer, VisGraph } from '@unovis/react'
import { TrimMode } from '@unovis/ts'
-import { generateNodeLinkData, NodeDatum, LinkDatum, rng } from '@src/utils/data'
+import { generateNodeLinkData, NodeDatum, LinkDatum, randomNumberGenerator } from '@src/utils/data'
import { sample } from '@src/utils/array'
export const title = 'Node Labels and Sub-labels'
@@ -16,12 +16,12 @@ export const component = (): JSX.Element => {
const labels = data.nodes.map((d, i) => ({
label: `${sample(animals)} ${sample(colors)}`,
subLabel: `${sample(regions)} ${sample(colors)} ${sample(animals)}`,
- labelTrim: rng() > 0.2,
+ labelTrim: randomNumberGenerator() > 0.2,
labelTrimMode: sample(trimModes),
- labelTrimLength: Math.round(3 + 12 * rng()),
- subLabelTrim: rng() > 0.2,
+ labelTrimLength: Math.round(3 + 12 * randomNumberGenerator()),
+ subLabelTrim: randomNumberGenerator() > 0.2,
subLabelTrimMode: sample(trimModes),
- subLabelTrimLength: Math.round(3 + 12 * rng()),
+ subLabelTrimLength: Math.round(3 + 12 * randomNumberGenerator()),
}))
return (
diff --git a/packages/dev/src/examples/xy-components/xy-labels/labels-stacked-bar/index.tsx b/packages/dev/src/examples/xy-components/xy-labels/labels-stacked-bar/index.tsx
index e2986338d..1141edffc 100644
--- a/packages/dev/src/examples/xy-components/xy-labels/labels-stacked-bar/index.tsx
+++ b/packages/dev/src/examples/xy-components/xy-labels/labels-stacked-bar/index.tsx
@@ -2,7 +2,7 @@ import React, { useRef } from 'react'
import { XYLabels } from '@unovis/ts'
import { VisXYContainer, VisStackedBar, VisAxis, VisTooltip, VisCrosshair, VisXYLabels } from '@unovis/react'
-import { XYDataRecord, generateXYDataRecords, rng } from '@src/utils/data'
+import { XYDataRecord, generateXYDataRecords, randomNumberGenerator } from '@src/utils/data'
// Style
import s from './style.module.css'
@@ -21,7 +21,7 @@ export const component = (): JSX.Element => {
type AlertDataRecord = { x: number; label: string }
const alerts: AlertDataRecord[] = Array(10).fill(null).map(() => ({
- x: data[Math.floor(rng() * data.length)].x,
+ x: data[Math.floor(randomNumberGenerator() * data.length)].x,
label: '❕',
}))
diff --git a/packages/dev/src/utils/array.ts b/packages/dev/src/utils/array.ts
index 569572fe5..daca0b916 100644
--- a/packages/dev/src/utils/array.ts
+++ b/packages/dev/src/utils/array.ts
@@ -1,4 +1,4 @@
-import { rng } from '@src/utils/data'
+import { randomNumberGenerator } from '@src/utils/data'
export function groupBy> (arr: T[], key: string): Record {
return arr.reduce(
(grouped, v, i, a, k = v[key]) => (((grouped[k] || (grouped[k] = [])).push(v), grouped)),
@@ -6,4 +6,4 @@ export function groupBy> (arr: T[], key: string):
)
}
-export const sample = (arr: T[]): T => arr[Math.floor(rng() * arr.length)]
+export const sample = (arr: T[]): T => arr[Math.floor(randomNumberGenerator() * arr.length)]
diff --git a/packages/dev/src/utils/data.ts b/packages/dev/src/utils/data.ts
index 80012034b..23c2ad4cb 100644
--- a/packages/dev/src/utils/data.ts
+++ b/packages/dev/src/utils/data.ts
@@ -1,8 +1,8 @@
+import * as Seedramdon from 'seedrandom'
import { GenericDataRecord } from '@unovis/ts'
import { sample } from './array'
-/* eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/naming-convention */
-const SeedRandom = require('seedrandom')
-export const rng = new SeedRandom('hello.')
+
+export const randomNumberGenerator = new Seedramdon('unovis')
export type XYDataRecord = {
x: number;
@@ -45,36 +45,36 @@ export type NestedDatum = GenericDataRecord & {
export function generateXYDataRecords (n = 10): XYDataRecord[] {
return Array(n).fill(0).map((_, i) => ({
x: i,
- y: 5 + 5 * rng(),
- y1: 1 + 3 * rng(),
- y2: 2 * rng(),
+ y: 5 + 5 * randomNumberGenerator(),
+ y1: 1 + 3 * randomNumberGenerator(),
+ y2: 2 * randomNumberGenerator(),
}))
}
export function generateStackedDataRecords (n = 10, count = 6): StackedDataRecord[] {
return Array(n).fill(0).map((_, i) => ({
x: i,
- ys: Array(count).fill(0).map((_, i) => (i * count / 3) + (count * rng())),
+ ys: Array(count).fill(0).map((_, i) => (i * count / 3) + (count * randomNumberGenerator())),
}))
}
export function generateTimeSeries (n = 10, types = n, lengthMultiplier = 1): TimeDataRecord[] {
const groups = Array(types).fill(0).map((_, i) => String.fromCharCode(i + 65))
return Array(n).fill(0).map((_, i: number) => ({
- timestamp: Date.now() + i * 1000 * 60 * 60 * 24 + (rng() - 0.5) * 5 * 1000 * 60 * 60 * 24,
+ timestamp: Date.now() + i * 1000 * 60 * 60 * 24 + (randomNumberGenerator() - 0.5) * 5 * 1000 * 60 * 60 * 24,
value: i / 10 + Math.sin(i / 5) + Math.cos(i / 3),
- length: Math.round(lengthMultiplier * 1000 * 60 * 60 * 24) * (0.2 + rng()),
+ length: Math.round(lengthMultiplier * 1000 * 60 * 60 * 24) * (0.2 + randomNumberGenerator()),
type: groups[i % groups.length],
}))
}
export function generateNodeLinkData (n = 10, numNeighbourLinks = () => 1): NodeLinkData {
- const nodes = Array(n).fill(0).map((_, i) => ({ i, id: (i + 1).toString(), value: 100 * rng() }))
+ const nodes = Array(n).fill(0).map((_, i) => ({ i, id: (i + 1).toString(), value: 100 * randomNumberGenerator() }))
const options = [...nodes].slice(1)
const links = nodes.reduce((arr, n) => {
if (options.length) {
- const num = Math.max(1, rng() * options.length)
+ const num = Math.max(1, randomNumberGenerator() * options.length)
for (let i = 0; i < num; i++) {
const targetId = options.shift()?.id
for (let k = 0; k < numNeighbourLinks(); k++) {
@@ -82,7 +82,7 @@ export function generateNodeLinkData (n = 10, numNeighbourLinks = () => 1): Node
id: `${n.id}-${targetId}`,
source: n.id,
target: targetId,
- value: rng(),
+ value: randomNumberGenerator(),
}
arr.push(link)
}
@@ -98,14 +98,14 @@ export function generatePrecalculatedNodeLinkData (n = 10, numNeighbourLinks = (
const nodes = Array(n).fill(0).map((_, i) => ({
i,
id: (i + 1).toString(),
- value: 100 * rng(),
+ value: 100 * randomNumberGenerator(),
x: 50 * i,
y: 50 * i,
}))
const options = [...nodes].slice(1)
const links = nodes.reduce((arr, n) => {
if (options.length) {
- const num = Math.max(1, rng() * options.length)
+ const num = Math.max(1, randomNumberGenerator() * options.length)
for (let i = 0; i < num; i++) {
const targetId = options.shift()?.id
for (let k = 0; k < numNeighbourLinks(); k++) {
@@ -113,7 +113,7 @@ export function generatePrecalculatedNodeLinkData (n = 10, numNeighbourLinks = (
id: `${n.id}-${targetId}`,
source: n.id,
target: targetId,
- value: rng(),
+ value: randomNumberGenerator(),
}
arr.push(link)
}
@@ -142,7 +142,7 @@ export function generateHierarchyData (n: number, levels: Record
const nodes = Array(n).fill(0).map((_, i) => {
const obj: NodeDatum = { id: i.toString(), label: `N${i}` }
Object.keys(levels).forEach(key => {
- obj[key] = `${key}${Math.floor(rng() * levels[key])}`
+ obj[key] = `${key}${Math.floor(randomNumberGenerator() * levels[key])}`
})
return obj
})
@@ -151,7 +151,7 @@ export function generateHierarchyData (n: number, levels: Record
links: Array(n / 2).fill(0).map(() => ({
source: sample(nodes),
target: sample(nodes),
- value: rng(),
+ value: randomNumberGenerator(),
})),
}
}