Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 1 addition & 12 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
export default {
stories: ['../stories/**/*.stories.@(js|jsx|ts|tsx)'],

addons: [
{
name: '@storybook/addon-storysource',
options: {
loaderOptions: {
injectStoryParameters: false,
},
},
},
'@storybook/addon-links',
'@storybook/addon-essentials',
],
addons: ['@storybook/addon-links', '@storybook/addon-docs'],

staticDirs: ['../stories/data'],

Expand Down
3 changes: 3 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ import './stories.css';

export const parameters = {
controls: { expanded: true, hideNoControlsWarning: true },
docs: {
codePanel: true,
},
};
export const tags = ['autodocs'];
25 changes: 9 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
# react-plot

Library of React components to render SVG 2D plots.

Check our exhaustive [documentation here](https://react-plot.zakodium.com/).

<h3 align="center">

<a href="https://www.zakodium.com">
<img src="https://www.zakodium.com/brand/zakodium-logo-white.svg" width="50" alt="Zakodium logo" />
</a>

<p>
Maintained by <a href="https://www.zakodium.com">Zakodium</a>
</p>
</h3>

# react-plot

[![NPM version][npm-image]][npm-url]
[![npm download][download-image]][download-url]
[![NPM version](https://img.shields.io/npm/v/react-plot.svg)](https://www.npmjs.com/package/react-plot)
[![npm download](https://img.shields.io/npm/dm/react-plot.svg)](https://www.npmjs.com/package/react-plot)
[![license](https://img.shields.io/npm/l/react-plot.svg)](https://github.com/zakodium-oss/react-plot/blob/main/LICENSE)

</h3>
Library of React components to render SVG 2D plots.

Check our exhaustive [documentation here](https://react-plot.zakodium.com/).

## [Storybook](https://react-plot.pages.dev/)

Expand Down Expand Up @@ -111,8 +109,3 @@ function Example() {
## License

[MIT](./LICENSE)

[npm-image]: https://img.shields.io/npm/v/react-plot.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/react-plot
[download-image]: https://img.shields.io/npm/dm/react-plot.svg?style=flat-square
[download-url]: https://www.npmjs.com/package/react-plot
22 changes: 14 additions & 8 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { defineConfig, globalIgnores } from 'eslint/config';
import react from 'eslint-config-zakodium/react';
import ts from 'eslint-config-zakodium/ts';
import unicorn from 'eslint-config-zakodium/unicorn';
import storybook from 'eslint-plugin-storybook';

export default [
{
ignores: ['lib', 'node_modules', 'playwright/.cache', 'storybook-static'],
},
...ts,
...react,
...unicorn,
export default defineConfig(
globalIgnores([
'lib',
'node_modules',
'playwright/.cache',
'storybook-static',
]),
ts,
react,
unicorn,
{
rules: {
'@typescript-eslint/no-dynamic-delete': 'off',
Expand All @@ -21,4 +26,5 @@ export default [
'@typescript-eslint/unbound-method': 'off',
},
},
];
...storybook.configs['flat/recommended'],
);
47 changes: 24 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,39 @@
"react": ">=18.0.0"
},
"devDependencies": {
"@playwright/experimental-ct-react": "^1.48.0",
"@playwright/experimental-ct-react": "^1.53.0",
"@simbathesailor/use-what-changed": "^2.0.0",
"@storybook/addon-essentials": "^8.3.5",
"@storybook/addon-links": "^8.3.5",
"@storybook/addon-storysource": "^8.3.5",
"@storybook/react": "^8.3.5",
"@storybook/react-vite": "^8.3.5",
"@storybook/addon-docs": "^9.0.8",
"@storybook/addon-links": "^9.0.8",
"@storybook/react-vite": "^9.0.8",
"@types/d3-array": "^3.2.1",
"@types/d3-scale": "^4.0.8",
"@types/d3-scale-chromatic": "^3.0.3",
"@types/d3-shape": "^3.1.6",
"@types/d3-scale": "^4.0.9",
"@types/d3-scale-chromatic": "^3.1.0",
"@types/d3-shape": "^3.1.7",
"@types/node": "^22.7.5",
"@types/point-in-polygon": "^1.1.5",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"eslint": "^9.12.0",
"eslint-config-zakodium": "^13.0.0",
"isotopic-distribution": "^3.3.2",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@zakodium/tsconfig": "^1.0.1",
"eslint": "^9.28.0",
"eslint-config-zakodium": "^15.0.1",
"eslint-plugin-storybook": "^9.0.8",
"isotopic-distribution": "^3.4.14",
"iv-analysis": "^0.4.0",
"ml-dataset-iris": "^1.2.1",
"ml-directional-distribution": "^0.1.1",
"ml-pca": "^4.1.1",
"ml-regression-simple-linear": "^3.0.1",
"ml-spectra-processing": "^14.6.0",
"ms-spectrum": "^3.6.7",
"ml-spectra-processing": "^14.12.0",
"ms-spectrum": "^3.9.0",
"point-in-polygon": "^1.1.0",
"prettier": "^3.3.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
"prettier": "^3.5.3",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-error-boundary": "^6.0.0",
"rimraf": "^6.0.1",
"typescript": "^5.6.3"
"storybook": "^9.0.8",
"typescript": "^5.8.3"
},
"dependencies": {
"d3-array": "^3.2.4",
Expand All @@ -92,9 +93,9 @@
"d3-shape": "^3.2.0",
"immer": "^10.1.1",
"ml-distance-euclidean": "^2.0.0",
"react-d3-utils": "^2.0.0"
"react-d3-utils": "^3.1.0"
},
"volta": {
"node": "22.9.0"
"node": "22.16.0"
}
}
2 changes: 1 addition & 1 deletion src/components/Annotations/Annotations.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ReactElement, type ReactNode } from 'react';
import type { ReactElement, ReactNode } from 'react';

export interface AnnotationsProps {
children: ReactNode;
Expand Down
3 changes: 2 additions & 1 deletion src/components/Annotations/Group.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { CSSProperties, ReactNode } from 'react';
import { type Align, AlignGroup } from 'react-d3-utils';
import type { Align } from 'react-d3-utils';
import { AlignGroup } from 'react-d3-utils';

import { usePosition } from '../../hooks.js';
import type { ScalarValue } from '../../types.js';
Expand Down
3 changes: 2 additions & 1 deletion src/components/Axis/Axis.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ScaleLinear, ScaleLogarithmic, ScaleTime } from 'd3-scale';
import { type CSSProperties, type ReactNode, useEffect } from 'react';
import type { CSSProperties, ReactNode } from 'react';
import { useEffect } from 'react';

import {
usePlotContext,
Expand Down
4 changes: 3 additions & 1 deletion src/components/Axis/HorizontalAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ export default function HorizontalAxis(props: AxisRendererProps) {
y2: y,
textPosition: textOffset + tickLength,
};
default:
case undefined:
return {
y1: 0,
y: 0,
textPosition: 0,
};
default:
throw new Error(`Invalid tick position ${String(tickPosition)}`);
}
}
const gridLinesElement =
Expand Down
3 changes: 2 additions & 1 deletion src/components/Axis/HorizontalAxisGridLines.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type CSSProperties, type ReactElement, useMemo } from 'react';
import type { CSSProperties, ReactElement } from 'react';
import { useMemo } from 'react';

import type { Position } from '../../types.js';

Expand Down
3 changes: 2 additions & 1 deletion src/components/Axis/HorizontalAxisLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { CSSProperties, ReactNode } from 'react';
import { type Align, AlignGroup } from 'react-d3-utils';
import type { Align } from 'react-d3-utils';
import { AlignGroup } from 'react-d3-utils';

interface HorizontalAxisLabelProps {
plotWidth: number;
Expand Down
11 changes: 8 additions & 3 deletions src/components/Axis/LinearAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ function LinearAxis(props: LinearAxisProps) {
const direction =
position === 'left' || position === 'right' ? 'vertical' : 'horizontal';

const primaryTicks = useLinearPrimaryTicks(scale, direction, axisRef, {
tickFormat: tickLabelFormat,
});
const { ticks: primaryTicks } = useLinearPrimaryTicks(
scale,
direction,
axisRef,
{
tickFormat: tickLabelFormat,
},
);

const AxisComponent =
direction === 'vertical' ? VerticalAxis : HorizontalAxis;
Expand Down
10 changes: 5 additions & 5 deletions src/components/Axis/Ticks.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
type CSSProperties,
type ReactElement,
type ReactNode,
type SVGAttributes,
import type {
CSSProperties,
ReactElement,
ReactNode,
SVGAttributes,
} from 'react';

import type { Scales, TicksType } from './types.js';
Expand Down
2 changes: 1 addition & 1 deletion src/components/Axis/TimeAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function TimeAxis(props: TimeAxisProps) {
const direction =
position === 'left' || position === 'right' ? 'vertical' : 'horizontal';

const primaryTicks = useTimeTicks(scale, direction, axisRef, {
const { ticks: primaryTicks } = useTimeTicks(scale, direction, axisRef, {
tickFormat: tickLabelFormat,
});

Expand Down
4 changes: 3 additions & 1 deletion src/components/Axis/VerticalAxis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,14 @@ export default function VerticalAxis(props: AxisRendererProps) {
x2: x,
textPosition: textOffset + tickLength,
};
default:
case undefined:
return {
x1: 0,
x2: 0,
textPosition: 3,
};
default:
throw new Error(`Invalid tick position ${String(tickPosition)}`);
}
}
const gridLinesElement =
Expand Down
3 changes: 2 additions & 1 deletion src/components/Axis/VerticalAxisGridLines.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type CSSProperties, type ReactElement, useMemo } from 'react';
import type { CSSProperties, ReactElement } from 'react';
import { useMemo } from 'react';

import type { Position } from '../../types.js';

Expand Down
3 changes: 2 additions & 1 deletion src/components/Axis/VerticalAxisLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { CSSProperties, ReactNode } from 'react';
import { type Align, AlignGroup } from 'react-d3-utils';
import type { Align } from 'react-d3-utils';
import { AlignGroup } from 'react-d3-utils';

import VerticalText from '../VerticalText.js';

Expand Down
8 changes: 2 additions & 6 deletions src/components/Axis/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import type { ScaleLinear, ScaleLogarithmic, ScaleTime } from 'd3-scale';
import type { CSSProperties, ReactNode, Ref } from 'react';
import type {
PrimaryLinearTicks,
PrimaryLogTicks,
TimeTicks,
} from 'react-d3-utils';
import type { Tick } from 'react-d3-utils';

import type { Position, TickLabelFormat, TickPosition } from '../../types.js';

Expand Down Expand Up @@ -44,4 +40,4 @@ export interface AxisChildProps<ScaleType> extends AxisCommonProps {
tickLabelFormat?: TickLabelFormat<ScaleType>;
}

export type TicksType = PrimaryLinearTicks | PrimaryLogTicks | TimeTicks;
export type TicksType = Tick<number> | Tick<Date>;
3 changes: 2 additions & 1 deletion src/components/ErrorBars.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type SVGAttributes, useMemo } from 'react';
import type { SVGAttributes } from 'react';
import { useMemo } from 'react';

import { usePlotContext } from '../contexts/plotContext.js';
import type { SeriesPointWithError } from '../types.js';
Expand Down
3 changes: 2 additions & 1 deletion src/components/Heading.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type CSSProperties, useEffect } from 'react';
import type { CSSProperties } from 'react';
import { useEffect } from 'react';
import { AlignGroup, useBBoxObserver } from 'react-d3-utils';

import {
Expand Down
10 changes: 6 additions & 4 deletions src/components/Legend.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable react/no-array-index-key */
import { type CSSProperties, useContext, useEffect, useMemo } from 'react';
import { AlignGroup, type AlignGroupProps } from 'react-d3-utils';
import type { CSSProperties } from 'react';
import { useContext, useEffect, useMemo } from 'react';
import type { AlignGroupProps } from 'react-d3-utils';
import { AlignGroup } from 'react-d3-utils';

import { useLegend } from '../contexts/legendContext.js';
import { legendOffsetContext } from '../contexts/legendOffsetContext.js';
Expand All @@ -13,7 +15,7 @@

import { markersMap } from './Markers.map.js';

type Positions = { [K in Position]?: number };
type Positions = Partial<Record<Position, number>>;

interface ValidatedPosition {
key?: Position;
Expand Down Expand Up @@ -121,7 +123,7 @@
labelStyle?: CSSFuncProps<{ id: string }>;
lineStyle?: CSSFuncProps<{ id: string }>;
showHide?: boolean;
} & { [K in Position]?: number };
} & Partial<Record<Position, number>>;

export function Legend(options: LegendProps) {
const {
Expand Down Expand Up @@ -172,7 +174,7 @@
{ id: value.id },
);
const lineStyle = functionalStyle({}, funcLineStyle, { id: value.id });
// TODO: fix this as it's not guaranteed that `fontSize` can be parsed as a string.

Check warning on line 177 in src/components/Legend.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Unexpected 'todo' comment: 'TODO: fix this as it's not guaranteed...'
const height = Number.parseInt(String(labelStyle.fontSize), 10);
const xPos = 10;
const yPos = index * height + height / 2 + 3;
Expand Down
Loading
Loading