Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3a9229d
feat(bar): cleanup types
plouc May 18, 2025
a840dbc
feat(controls): introduce @nivo/controls
plouc May 18, 2025
45d6e16
feat(website): add a new scale control
plouc May 18, 2025
8082b4f
feat(website): init a new scales guide
plouc May 18, 2025
ac64225
feat(website): create a new property group for chart dimensions
plouc May 18, 2025
0dff879
feat(controls): fix linting issues
plouc May 18, 2025
24db97b
feat(bar): restrict the type of value scale supported and use better …
plouc May 18, 2025
8feb0b7
feat(website): add the ability to copy the code and data of the charts
plouc May 18, 2025
9a992b0
feat(website): add better support for anchors in guides
plouc May 18, 2025
74a7b62
feat(website): prefix custom attrs with $ for styled-components
plouc May 18, 2025
0c027ad
feat(controls): update README
plouc May 18, 2025
df841b6
feat(website): simplify controls props
plouc May 18, 2025
a47880f
fix(bar): fix unit tests to to the changes on scales defaults
plouc May 18, 2025
212f579
feat(controls): remove the controls package and port improvements in …
plouc May 18, 2025
0b838b2
fix(infrastructure): fix miscategorization of the storybook-test-ci t…
plouc May 18, 2025
ccfae26
feat(bar): move scale properties to the scale config
plouc May 18, 2025
6b9e9ff
feat(website): scale control now support switching type
plouc May 18, 2025
810c1dc
feat(scales): refine scales options, V1 of the scales guide
plouc May 20, 2025
f906bcd
feat(rects): add support for non-uniform border-radius and improve la…
plouc May 23, 2025
4bd869e
feat(website): add chart capture effect
plouc May 23, 2025
1a2f9d8
feat(website): add a new control for non-uniform border-radius
plouc May 23, 2025
51da1a7
feat(colors): add type guards to sequential color scales
plouc May 23, 2025
ef3b5ab
feat(generators): add new helpers to support seeding and generating r…
plouc May 23, 2025
08b3e0b
feat(icicle): fix tests due to rects now being SVG path elements
plouc May 23, 2025
42c3437
fix(lint): fix linting issues
plouc May 23, 2025
3ac535e
feat(scales): update tests due to the changes on scales' defaults
plouc May 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ website-deps-up: ##@2 website interactive upgrade of website's dependencies

website: ##@2 website start website in dev mode
@echo "${YELLOW}Starting website dev server${RESET}"
@cd website && pnpm start
@cd website && pnpm dev

website-build: ##@2 website build website
@echo "${YELLOW}Building website${RESET}"
Expand Down Expand Up @@ -290,7 +290,7 @@ storybook-playwright-install: ##@3 storybook install playwright
@echo "${YELLOW}Installing playwright${RESET}"
@pnpm pnpm exec playwright install chromium

storybook-test-ci: ##@3 start storybook & run playwright tests
storybook-test-ci: ##@3 storybook start storybook & run playwright tests
@echo "${YELLOW}Start storybook and run playwright tests${RESET}"
@npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook/storybook-static --port 6006 --silent" \
Expand Down
4 changes: 3 additions & 1 deletion conf/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ const common = {
|| id.indexOf('d3') === 0
|| id.indexOf('@nivo') === 0
|| id.indexOf('lodash') === 0
|| id.indexOf('@react-spring') === 0,
|| id.indexOf('@react-spring') === 0
|| id.indexOf('styled-components') === 0
|| id.indexOf('dedent-js') === 0
}

const commonPlugins = [
Expand Down
16 changes: 10 additions & 6 deletions cypress/src/components/icicle/Icicle.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,16 @@ const testNode = (expectedNode: ExpectedNode) => {
`translate(${expectedNode.rect.x},${expectedNode.rect.y})`
)

if (expectedNode.rect.width !== undefined) {
node.should('have.attr', 'width', expectedNode.rect.width)
}
if (expectedNode.rect.height !== undefined) {
node.should('have.attr', 'height', expectedNode.rect.height)
}
node.its('0')
.invoke('getBBox')
.then((bbox: DOMRect) => {
if (expectedNode?.rect?.width !== undefined) {
expect(bbox.width).to.equal(expectedNode.rect.width)
}
if (expectedNode?.rect?.height !== undefined) {
expect(bbox.height).to.equal(expectedNode.rect.height)
}
})
}

if (expectedNode.color) {
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@
"yargs": "^17.7.2"
},
"resolutions": {
"@react-spring/core": "^10.0.0",
"@react-spring/web": "^10.0.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
"@types/eslint": "7.29.0",
"cheerio": "1.0.0-rc.10",
"react": "18.3.1",
"react-dom": "18.3.1"
"@types/react": "18.3.20",
"react-dom": "18.3.1",
"@types/react-dom": "18.3.6",
"@react-spring/core": "10.0.0",
"@react-spring/web": "10.0.0",
"styled-components": "6.1.18",
"react-markdown": "10.1.0"
},
"scripts": {
"make:init": "make init",
Expand All @@ -101,7 +103,7 @@
"type": "opencollective",
"url": "https://opencollective.com/nivo"
},
"packageManager": "pnpm@10.10.0",
"packageManager": "pnpm@10.11.0",
"pnpm": {
"onlyBuiltDependencies": [
"@parcel/watcher",
Expand Down
107 changes: 42 additions & 65 deletions packages/bar/src/Bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,26 @@ import { Fragment, ReactNode, createElement, useMemo } from 'react'
import { BarAnnotations } from './BarAnnotations'
import { BarLegends } from './BarLegends'
import { useBar } from './hooks'
import { svgDefaultProps } from './props'
import { svgDefaultProps } from './defaults'
import {
BarComponent,
BarCustomLayerProps,
BarDatum,
BarItemProps,
BarLayer,
BarLayerId,
BarSvgProps,
BarTooltipComponent,
ComputedBarDatumWithValue,
} from './types'
import { BarTotals } from './BarTotals'
import { useComputeLabelLayout } from './compute/common'

type InnerBarProps<RawDatum extends BarDatum> = Omit<
BarSvgProps<RawDatum>,
type InnerBarProps<D extends BarDatum> = Omit<
BarSvgProps<D>,
'animate' | 'motionConfig' | 'renderWrapper' | 'theme'
>

const InnerBar = <RawDatum extends BarDatum>({
const InnerBar = <D extends BarDatum>({
data,
indexBy,
keys,
Expand All @@ -42,9 +43,6 @@ const InnerBar = <RawDatum extends BarDatum>({
height,
groupMode,
layout,
reverse,
minValue,
maxValue,
valueScale,
indexScale,
padding,
Expand All @@ -57,8 +55,8 @@ const InnerBar = <RawDatum extends BarDatum>({
enableGridY = svgDefaultProps.enableGridY,
gridXValues,
gridYValues,
layers = svgDefaultProps.layers as readonly BarLayer<RawDatum>[],
barComponent = svgDefaultProps.barComponent,
layers = svgDefaultProps.layers as BarLayerId[],
barComponent = svgDefaultProps.barComponent as unknown as BarComponent<D>,
enableLabel = svgDefaultProps.enableLabel,
label,
labelSkipWidth = svgDefaultProps.labelSkipWidth,
Expand All @@ -79,7 +77,7 @@ const InnerBar = <RawDatum extends BarDatum>({
tooltipLabel,
valueFormat,
isInteractive = svgDefaultProps.isInteractive,
tooltip = svgDefaultProps.tooltip,
tooltip = svgDefaultProps.tooltip as BarTooltipComponent<D>,
onClick,
onMouseEnter,
onMouseLeave,
Expand All @@ -98,7 +96,7 @@ const InnerBar = <RawDatum extends BarDatum>({
enableTotals = svgDefaultProps.enableTotals,
totalsOffset = svgDefaultProps.totalsOffset,
forwardedRef,
}: InnerBarProps<RawDatum> & {
}: InnerBarProps<D> & {
forwardedRef: Ref<SVGSVGElement>
}) => {
const { animate, config: springConfig } = useMotionConfig()
Expand All @@ -122,7 +120,7 @@ const InnerBar = <RawDatum extends BarDatum>({
legendsWithData,
barTotals,
getColor,
} = useBar<RawDatum>({
} = useBar<D>({
indexBy,
label,
tooltipLabel,
Expand All @@ -133,11 +131,8 @@ const InnerBar = <RawDatum extends BarDatum>({
labelTextColor,
groupMode,
layout,
reverse,
data,
keys,
minValue,
maxValue,
margin,
width: innerWidth,
height: innerHeight,
Expand All @@ -154,10 +149,15 @@ const InnerBar = <RawDatum extends BarDatum>({
totalsOffset,
})

const computeLabelLayout = useComputeLabelLayout(layout, reverse, labelPosition, labelOffset)
const computeLabelLayout = useComputeLabelLayout(
layout,
valueScale?.reverse ?? false,
labelPosition,
labelOffset
)

const transition = useTransition<
ComputedBarDatumWithValue<RawDatum>,
ComputedBarDatumWithValue<D>,
{
borderColor: string
color: string
Expand All @@ -169,7 +169,7 @@ const InnerBar = <RawDatum extends BarDatum>({
opacity: number
transform: string
width: number
textAnchor: BarItemProps<RawDatum>['style']['textAnchor']
textAnchor: BarItemProps<D>['style']['textAnchor']
}
>(barsWithValue, {
keys: bar => bar.key,
Expand Down Expand Up @@ -380,46 +380,25 @@ const InnerBar = <RawDatum extends BarDatum>({
)
}

const layerContext: BarCustomLayerProps<RawDatum> = useMemo(
() => ({
...commonProps,
margin,
width,
height,
innerWidth,
innerHeight,
bars,
legendData: legendsWithData,
enableLabel,
xScale,
yScale,
tooltip,
getTooltipLabel,
onClick,
onMouseEnter,
onMouseLeave,
getColor,
}),
[
commonProps,
margin,
width,
height,
innerWidth,
innerHeight,
bars,
legendsWithData,
enableLabel,
xScale,
yScale,
tooltip,
getTooltipLabel,
onClick,
onMouseEnter,
onMouseLeave,
getColor,
]
)
const layerContext: BarCustomLayerProps<D> = {
...commonProps,
margin,
width,
height,
innerWidth,
innerHeight,
bars,
legendData: legendsWithData,
enableLabel,
xScale,
yScale,
tooltip,
getTooltipLabel,
onClick,
onMouseEnter,
onMouseLeave,
getColor,
}

return (
<SvgWrapper
Expand All @@ -446,15 +425,15 @@ const InnerBar = <RawDatum extends BarDatum>({
}

export const Bar = forwardRef(
<RawDatum extends BarDatum>(
<D extends BarDatum>(
{
isInteractive = svgDefaultProps.isInteractive,
animate = svgDefaultProps.animate,
motionConfig = svgDefaultProps.motionConfig,
theme,
renderWrapper,
...props
}: BarSvgProps<RawDatum>,
}: BarSvgProps<D>,
ref: Ref<SVGSVGElement>
) => (
<Container
Expand All @@ -464,9 +443,7 @@ export const Bar = forwardRef(
renderWrapper={renderWrapper}
theme={theme}
>
<InnerBar<RawDatum> isInteractive={isInteractive} {...props} forwardedRef={ref} />
<InnerBar<D> {...props} isInteractive={isInteractive} forwardedRef={ref} />
</Container>
)
) as <RawDatum extends BarDatum>(
props: WithChartRef<BarSvgProps<RawDatum>, SVGSVGElement>
) => ReactElement
) as <D extends BarDatum>(props: WithChartRef<BarSvgProps<D>, SVGSVGElement>) => ReactElement
7 changes: 5 additions & 2 deletions packages/bar/src/BarAnnotations.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Annotation, useAnnotations } from '@nivo/annotations'
import { BarAnnotationsProps } from './types'
import { BarAnnotationsProps, BarDatum } from './types'

export const BarAnnotations = <RawDatum,>({ bars, annotations }: BarAnnotationsProps<RawDatum>) => {
export const BarAnnotations = <D extends BarDatum>({
bars,
annotations,
}: BarAnnotationsProps<D>) => {
const boundAnnotations = useAnnotations({
data: bars,
annotations,
Expand Down
Loading
Loading