Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@nivo/tree #2582

Merged
merged 36 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
fb854f5
feat(dendogram) init package
plouc May 2, 2024
5ac5a4d
feat(dendogram): add support for custom svg layers
plouc May 2, 2024
7b6cb04
feat(dendogram): add the ability to define links' thickness
plouc May 2, 2024
ac5c4a9
feat(dendogram): add support for links mouse events
plouc May 2, 2024
10bbe2f
feat(dendogram): add support for links tooltips
plouc May 3, 2024
2023d19
feat(dendogram): add icons and reviews and improve the capture script
plouc May 3, 2024
3e95886
feat(dendogram): improve nodes and links colors
plouc May 3, 2024
f10b717
feat(dendogram): add support for a voronoi mesh
plouc May 3, 2024
ed28d78
feat(dendogram): add the ability to highligh ancestor/descendant nodes
plouc May 3, 2024
10ae9e3
feat(voronoi): attempt to simulate enter/leave events
plouc May 3, 2024
5867ca6
feat(dendogram): add the ability to highlight links
plouc May 3, 2024
78852f1
chore(deps): upgrade d3-shape
plouc May 3, 2024
b0cf2e9
fix(line): fix snapshot based tests due to the d3-shape upgrade
plouc May 3, 2024
f8000b8
feat(dendogram): add support for diagonal links
plouc May 3, 2024
4862b36
feat(tree): rename the dendogram package to tree
plouc May 3, 2024
d04994c
feat(tree): fix stories
plouc May 3, 2024
ad37317
feat(tree): init e2e tests
plouc May 4, 2024
24c3933
feat(e2e): upgrade cypress github action
plouc May 4, 2024
d0bb15b
feat(tree): add the ability to customize the links curve generator
plouc May 4, 2024
70db97a
feat(tree): add support for labels
plouc May 5, 2024
adff587
feat(tree): add unit tests
plouc May 5, 2024
522d51f
feat(tree): add the ability to fix the nodes color at a given depth
plouc May 5, 2024
1a05890
feat(tree): improve colors for stories
plouc May 5, 2024
ff1e796
feat(colors): add the tableau10 color scheme
plouc May 5, 2024
ce46163
feat(tree): disable diceRoll in the demo and update the chart preview
plouc May 5, 2024
40d4164
feat(tree): expose the nodes map for custom layers
plouc May 5, 2024
667364b
feat(text): introduce @nivo/text package
plouc May 6, 2024
f16c009
feat(core): remove unused prop types
plouc May 6, 2024
26e19c6
feat(website): add the ability to define some chart property attribut…
plouc May 6, 2024
8c72cf0
feat(tree): add canvas support
plouc May 6, 2024
3b38124
feat(theming): exclude non standard properties from text styles
plouc May 6, 2024
4727348
feat(tree): improve voronoi mesh detection and tooltips
plouc May 7, 2024
5d8a0e8
feat(voronoi): restore touch events support
plouc May 7, 2024
1f5ec63
feat(line): delegate the mesh current element selection to the vorono…
plouc May 7, 2024
c46c128
fet(api): upgrade node version and use npm instead of yarn
plouc May 12, 2024
0a010eb
doc(contributing): add end-to-end tests explanations
plouc May 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
- name: Build nivo packages
run: make pkgs-build
- name: Cypress run
uses: cypress-io/github-action@v5
uses: cypress-io/github-action@v6
with:
install: false
component: true
Expand Down
20 changes: 18 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ the various packages, please execute the following:
make init
```

> please note that it will take a while as this project uses a lot of dependencies…'
> please note that it will take a while as this project uses a lot of dependencies…

### Windows

If you want to build this project on Windows, it is recommended to use either WSL 2, or Git bash + `choco install make`.
If you want to build this project on Windows, it is recommended to use either WSL 2,
or Git bash + `choco install make`.

## Development

Expand Down Expand Up @@ -77,6 +78,13 @@ You can also build the packages without running a watcher, you have two options:

### Testing

#### Unit tests

Unit tests for each package are located in the `packages/<pkg>/tests` folder, we're using jest
as a test running and `react-test-renderer` as a testing library, some tests are still using
`enzyme`, but this lib is not maintained anymore and doesn't support newer versions of React,
so those should eventually be migrated.

To run unit tests on all packages, run the following command:

```
Expand All @@ -92,6 +100,14 @@ make pkg-test-bar

where `bar` is the name of the targeted nivo package.

#### End-to-end tests

Sometimes it's difficult to test certain things in unit tests, from our experience, animations
and interactions can be tricky to test via unit tests only, so we also try to have end-to-end tests.

We're using `cypress` for writing such tests, and those are located in the `cypress/src/components`
folder, as we introduced end-to-end tests later, not all packages have some.

### Formatting

Nivo uses prettier in order to provide a consistent code style.
Expand Down
17 changes: 16 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ fmt: ##@0 global format code using prettier (js, css, md)
"storybook/.storybook/*.{js,ts,tsx}" \
"storybook/stories/**/*.{js,ts,tsx}" \
"cypress/src/**/*.{js,ts,tsx}" \
"scripts/*.{js,mjs}" \
"cypress/src/**/*.{js,tsx}" \
"README.md"

fmt-check: ##@0 global check if files were all formatted using prettier
Expand All @@ -74,6 +76,8 @@ fmt-check: ##@0 global check if files were all formatted using prettier
"storybook/.storybook/*.{js,ts,tsx}" \
"storybook/stories/**/*.{js,ts,tsx}" \
"cypress/src/**/*.{js,ts,tsx}" \
"scripts/*.{js,mjs}" \
"cypress/src/**/*.{js,tsx}" \
"README.md"

test: ##@0 global run all checks/tests (packages, website)
Expand Down Expand Up @@ -203,11 +207,22 @@ pkgs-publish-next: ##@1 packages publish all packages for @next npm tag
@echo "${YELLOW}Publishing packages${RESET}"
@pnpm lerna publish --exact --npm-tag=next

pkg-dev-%: ##@1 packages build package (es flavor) on change, eg. `package-watch-bar`
pkg-dev-%: ##@1 packages build package (es flavor) on change, eg. `pkg-dev-bar`
@echo "${YELLOW}Running build watcher for package ${WHITE}@nivo/${*}${RESET}"
@rm -rf ./packages/${*}/cjs
@export PACKAGE=${*}; NODE_ENV=development BABEL_ENV=development ./node_modules/.bin/rollup -c conf/rollup.config.mjs -w

pkg-icons-%: ##@1 capture packages icons for the website, eg. `pkg-icons-bar`
./scripts/capture.mjs icons --pkg ${*}
@$(MAKE) website-sprites

pkg-previews-%: ##@1 capture packages previews for readmes, eg. `pkg-previews-bar`
./scripts/capture.mjs charts --pkg ${*}

pkg-capture-%: ##@1 capture packages previews and icons, eg. `pkg-capture-bar`
./scripts/capture.mjs all --pkg ${*}
@$(MAKE) website-sprites

########################################################################################################################
#
# 2. WEBSITE
Expand Down
4 changes: 2 additions & 2 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"engineStrict": true,
"engines": {
"node": ">=16"
"node": ">=18"
},
"devDependencies": {
"nodemon": "^2.0.22"
Expand All @@ -39,7 +39,7 @@
"winston": "3.3.3"
},
"scripts": {
"start": "yarn build && node app.js",
"start": "npm run build && node app.js",
"dev": "nodemon app.ts",
"build": "tsc"
},
Expand Down
15 changes: 10 additions & 5 deletions conf/base.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
baseUrl: http://localhost:9000
baseUrl: http://localhost:8000
capture:
pages:
- id: home
Expand Down Expand Up @@ -57,6 +57,10 @@ capture:
chart: bar
flavors: [svg, canvas]

- pkg: bullet
chart: bullet
flavors: [ svg ]

- pkg: calendar
chart: calendar
flavors: [svg]
Expand All @@ -71,10 +75,6 @@ capture:
# html is broken for now
# flavors: [svg, html, canvas]

- pkg: bullet
chart: bullet
flavors: [svg]

- pkg: heatmap
chart: heatmap
flavors: [svg, canvas]
Expand Down Expand Up @@ -121,6 +121,11 @@ capture:
chart: sunburst
flavors: [svg]

- pkg: tree
chart: tree
theme: dark
flavors: [svg]

- pkg: treemap
chart: treemap
flavors: [svg, html, canvas]
Expand Down
10 changes: 6 additions & 4 deletions cypress/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { defineConfig } from 'cypress'
import { defineConfig } from "cypress";

export default defineConfig({
viewportWidth: 600,
viewportHeight: 600,
component: {
devServer: {
framework: 'create-react-app',
bundler: 'webpack',
framework: "create-react-app",
bundler: "webpack",
},
video: false,
},
})
});
7 changes: 4 additions & 3 deletions cypress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@nivo/stream": "workspace:*",
"@nivo/sunburst": "workspace:*",
"@nivo/swarmplot": "workspace:*",
"@nivo/tree": "workspace:*",
"@nivo/treemap": "workspace:*",
"@nivo/voronoi": "workspace:*",
"@nivo/waffle": "workspace:*"
Expand All @@ -45,9 +46,9 @@
"node": ">=18"
},
"devDependencies": {
"cypress": "^12.11.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"cypress": "^13.8.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "^5.0.1",
"typescript": "^4.9.5"
},
Expand Down
174 changes: 174 additions & 0 deletions cypress/src/components/tree/Tree.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import { Tree, TreeSvgProps } from '@nivo/tree'
import { before } from 'lodash'

interface Datum {
id: string
children?: Datum[]
}

const sampleData: Datum = {
id: 'A',
children: [
{ id: '0' },
{
id: '1',
children: [{ id: 'A' }, { id: 'B' }],
},
{ id: '2' },
],
}

const defaultProps: Pick<
TreeSvgProps<Datum>,
| 'data'
| 'width'
| 'height'
| 'margin'
| 'nodeSize'
| 'activeNodeSize'
| 'inactiveNodeSize'
| 'linkThickness'
| 'activeLinkThickness'
| 'inactiveLinkThickness'
| 'animate'
> = {
data: sampleData,
width: 640,
height: 640,
margin: {
top: 20,
right: 20,
bottom: 20,
left: 20,
},
nodeSize: 12,
activeNodeSize: 24,
inactiveNodeSize: 8,
linkThickness: 2,
activeLinkThickness: 12,
inactiveLinkThickness: 1,
animate: false,
}

describe('<Tree />', () => {
beforeEach(() => {
cy.viewport(
defaultProps.margin.left + defaultProps.width + defaultProps.margin.right,
defaultProps.margin.top + defaultProps.height + defaultProps.margin.bottom
)
})

it('should render a tree graph', () => {
cy.mount(<Tree<Datum> {...defaultProps} />)

cy.get('[data-testid="node.A"]').should('exist')
cy.get('[data-testid="node.A.0"]').should('exist')
cy.get('[data-testid="node.A.1"]').should('exist')
cy.get('[data-testid="node.A.1.A"]').should('exist')
cy.get('[data-testid="node.A.1.B"]').should('exist')
cy.get('[data-testid="node.A.2"]').should('exist')
})

it('should highlight ancestor nodes and links', () => {
cy.mount(
<Tree<Datum>
{...defaultProps}
useMesh={false}
highlightAncestorNodes={true}
highlightAncestorLinks={true}
/>
)

const expectations = [
{ uid: 'node.A', nodes: ['node.A'], links: [] },
{ uid: 'node.A.0', nodes: ['node.A', 'node.A.0'], links: ['link.A:A.0'] },
{ uid: 'node.A.1', nodes: ['node.A', 'node.A.1'], links: ['link.A:A.1'] },
{
uid: 'node.A.1.A',
nodes: ['node.A', 'node.A.1', 'node.A.1.A'],
links: ['link.A:A.1', 'link.A.1:A.1.A'],
},
{
uid: 'node.A.1.B',
nodes: ['node.A', 'node.A.1', 'node.A.1.B'],
links: ['link.A:A.1', 'link.A.1:A.1.B'],
},
{ uid: 'node.A.2', nodes: ['node.A', 'node.A.2'], links: ['link.A:A.2'] },
]

for (const expectation of expectations) {
cy.get(`[data-testid="${expectation.uid}"]`).trigger('mouseover')
cy.wait(100)

cy.get('[data-testid^="node."]').each($node => {
cy.wrap($node)
.invoke('attr', 'data-testid')
.then(testId => {
const size = expectation.nodes.includes(testId!)
? defaultProps.activeNodeSize
: defaultProps.inactiveNodeSize
cy.wrap($node)
.invoke('attr', 'r')
.should('equal', `${size / 2}`)
})
})

cy.get('[data-testid^="link."]').each($link => {
cy.wrap($link)
.invoke('attr', 'data-testid')
.then(testId => {
const thickness = expectation.links.includes(testId!)
? defaultProps.activeLinkThickness
: defaultProps.inactiveLinkThickness
cy.wrap($link)
.invoke('attr', 'stroke-width')
.should('equal', `${thickness}`)
})
})
}
})

it('should highlight descendant nodes and links', () => {
cy.mount(
<Tree<Datum>
{...defaultProps}
useMesh={false}
highlightAncestorNodes={false}
highlightAncestorLinks={false}
highlightDescendantNodes={true}
highlightDescendantLinks={true}
/>
)

const expectations = [
{
uid: 'node.A',
nodes: ['node.A', 'node.A.0', 'node.A.1', 'node.A.1.A', 'node.A.1.B', 'node.A.2'],
links: [],
},
{ uid: 'node.A.0', nodes: ['node.A.0'], links: [] },
{ uid: 'node.A.1', nodes: ['node.A.1', 'node.A.1.A', 'node.A.1.B'], links: [] },
{ uid: 'node.A.1.A', nodes: ['node.A.1.A'], links: [] },
{ uid: 'node.A.1.B', nodes: ['node.A.1.B'], links: [] },
{ uid: 'node.A.2', nodes: ['node.A.2'], links: [] },
]

for (const expectation of expectations) {
cy.get(`[data-testid="${expectation.uid}"]`).trigger('mouseover')
cy.wait(100)

cy.get('[data-testid^="node."]').each($node => {
cy.wrap($node)
.invoke('attr', 'data-testid')
.then(testId => {
const size = expectation.nodes.includes(testId!)
? defaultProps.activeNodeSize
: defaultProps.inactiveNodeSize
cy.wrap($node)
.invoke('attr', 'r')
.should('equal', `${size / 2}`)
})
})
}
})
})
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"rollup-plugin-strip-banner": "^3.0.0",
"rollup-plugin-visualizer": "^5.5.2",
"serve": "^13.0.2",
"typescript": "^4.9.5"
"typescript": "^4.9.5",
"yargs": "^17.7.2"
},
"resolutions": {
"@types/react": "^18.2.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/arcs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
"@nivo/colors": "workspace:*",
"@nivo/core": "workspace:*",
"@react-spring/web": "9.4.5 || ^9.7.2",
"@types/d3-shape": "^2.0.0",
"d3-shape": "^1.3.5"
"@types/d3-shape": "^3.1.6",
"d3-shape": "^3.2.0"
},
"peerDependencies": {
"react": ">= 16.14.0 < 19.0.0"
Expand Down