@nivo/core
Version:
<a href="https://nivo.rocks"><img alt="nivo" src="https://raw.githubusercontent.com/plouc/nivo/master/nivo.png" width="216" height="68"/></a>
648 lines (587 loc) • 17.6 kB
TypeScript
import * as React from 'react'
import { Interpolation, SpringConfig } from '@react-spring/web'
import { CurveFactory } from 'd3-shape'
import { ComponentType } from 'react'
export type DatumValue = string | number | Date
export interface Dimensions {
height: number
width: number
}
export interface Point {
x: number
y: number
}
export interface AlignBox extends Dimensions, Point {}
export type Margin = {
bottom: number
left: number
right: number
top: number
}
export type Padding = Margin
export type Box = Partial<Margin>
export type BoxAlign =
| 'center'
| 'top-left'
| 'top'
| 'top-right'
| 'right'
| 'bottom-right'
| 'bottom'
| 'bottom-left'
| 'left'
export const boxAlignments: readonly BoxAlign[]
export function alignBox(box: AlignBox, container: AlignBox, alignment: BoxAlign): [number, number]
export type GetColor<T> = (datum: T) => string
export type Colors = readonly string[] | string
export interface ColorProps<T> {
colors?: Colors
colorBy?: string | GetColor<T>
}
/**
* Required text properties + optional ones.
*/
export type TextStyle = {
fontFamily: Exclude<React.CSSProperties['fontFamily'], undefined>
fontSize: Exclude<React.CSSProperties['fontSize'], undefined>
fill: string
outlineWidth: number
outlineColor: string
outlineOpacity: number
} & Partial<React.CSSProperties>
export function sanitizeSvgTextStyle(style: TextStyle): any
export type CompleteTheme = {
background: string
text: TextStyle
axis: {
domain: {
line: Partial<React.CSSProperties>
}
ticks: {
line: Partial<React.CSSProperties>
text: TextStyle
}
legend: {
text: TextStyle
}
}
grid: {
line: Partial<React.CSSProperties>
}
crosshair: {
line: {
stroke: string
strokeWidth: number
strokeOpacity: number
strokeDasharray: string
}
}
legends: {
hidden: {
symbol: Partial<{
fill: string
opacity: number
}>
text: TextStyle
}
title: {
text: TextStyle
}
text: TextStyle
ticks: {
line: Partial<React.CSSProperties>
text: TextStyle
}
}
labels: {
text: TextStyle
}
markers: {
lineColor: string
lineStrokeWidth: number
textColor: string
fontSize: string | 0
text: TextStyle
}
dots: {
text: TextStyle
}
tooltip: {
wrapper: Partial<React.CSSProperties>
container: Partial<React.CSSProperties>
basic: Partial<React.CSSProperties>
chip: Partial<React.CSSProperties>
table: Partial<React.CSSProperties>
tableCell: Partial<React.CSSProperties>
tableCellValue: Partial<React.CSSProperties>
}
annotations: {
text: {
fill: string
outlineWidth: number
outlineColor: string
outlineOpacity: number
} & Partial<Omit<React.CSSProperties, 'fill'>>
link: {
stroke: string
strokeWidth: number
outlineWidth: number
outlineColor: string
outlineOpacity: number
} & Partial<Omit<React.CSSProperties, 'stroke' | 'strokeWidth'>>
outline: {
stroke: string
strokeWidth: number
outlineWidth: number
outlineColor: string
outlineOpacity: number
} & Partial<Omit<React.CSSProperties, 'stroke' | 'strokeWidth'>>
symbol: {
fill: string
outlineWidth: number
outlineColor: string
outlineOpacity: number
} & Partial<Omit<React.CSSProperties, 'fill'>>
}
}
/**
* Required properties without inheritance.
*
* The theme supports defining styles at the top level
* (for text for example), which are then used to populate
* similar nested properties.
*
* For example `text` will be merged with `axis.ticks.text`,
* we use this approach so that it's simpler to define global styles.
*/
export type ThemeWithoutInheritance = {
background: CompleteTheme['background']
text: CompleteTheme['text']
axis: {
domain: {
line: CompleteTheme['axis']['domain']['line']
}
ticks: {
line: CompleteTheme['axis']['ticks']['line']
text: Partial<CompleteTheme['axis']['ticks']['text']>
}
legend: Partial<{
text: Partial<CompleteTheme['axis']['legend']['text']>
}>
}
grid: {
line: CompleteTheme['grid']['line']
}
crosshair: {
line: CompleteTheme['crosshair']['line']
}
legends: {
hidden: {
symbol: CompleteTheme['legends']['hidden']['symbol']
text: Partial<CompleteTheme['legends']['hidden']['text']>
}
title: {
text: Partial<CompleteTheme['legends']['title']['text']>
}
text: Partial<CompleteTheme['legends']['text']>
ticks: {
line: CompleteTheme['legends']['ticks']['line']
text: Partial<CompleteTheme['legends']['ticks']['text']>
}
}
labels: {
text: Partial<CompleteTheme['labels']['text']>
}
markers: Partial<CompleteTheme['markers']>
dots: {
text: Partial<CompleteTheme['dots']['text']>
}
tooltip: CompleteTheme['tooltip']
annotations: {
text: Partial<CompleteTheme['annotations']['text']>
link: CompleteTheme['annotations']['link']
outline: CompleteTheme['annotations']['outline']
symbol: CompleteTheme['annotations']['symbol']
}
}
export type Theme = Partial<{
background: CompleteTheme['background']
text: Partial<CompleteTheme['text']>
axis: Partial<{
domain: Partial<{
line: Partial<CompleteTheme['axis']['domain']['line']>
}>
ticks: Partial<{
line: Partial<CompleteTheme['axis']['ticks']['line']>
text: Partial<CompleteTheme['axis']['ticks']['text']>
}>
legend: Partial<{
text: Partial<CompleteTheme['axis']['legend']['text']>
}>
}>
grid: Partial<{
line: Partial<CompleteTheme['grid']['line']>
}>
crosshair: Partial<{
line: Partial<CompleteTheme['crosshair']['line']>
}>
legends: Partial<{
hidden: Partial<{
symbol: CompleteTheme['legends']['hidden']['symbol']
text: CompleteTheme['legends']['hidden']['text']
}>
title: Partial<{
text: Partial<CompleteTheme['legends']['title']['text']>
}>
text: Partial<CompleteTheme['legends']['text']>
ticks: Partial<{
line: Partial<CompleteTheme['legends']['ticks']['line']>
text: Partial<CompleteTheme['legends']['ticks']['text']>
}>
}>
labels: Partial<{
text: Partial<CompleteTheme['labels']['text']>
}>
markers: Partial<CompleteTheme['markers']>
dots: Partial<{
text: Partial<CompleteTheme['dots']['text']>
}>
tooltip: Partial<CompleteTheme['tooltip']>
annotations: Partial<{
text: Partial<CompleteTheme['annotations']['text']>
link: Partial<CompleteTheme['annotations']['link']>
outline: Partial<CompleteTheme['annotations']['outline']>
symbol: Partial<CompleteTheme['annotations']['symbol']>
}>
}>
export function useTheme(): CompleteTheme
export function usePartialTheme(theme?: Theme): CompleteTheme
export function extendDefaultTheme(
defaultTheme: ThemeWithoutInheritance,
customTheme: Theme
): CompleteTheme
export type MotionProps = Partial<{
animate: boolean
motionConfig: string | SpringConfig
}>
export function useMotionConfig(): {
animate: boolean
config: SpringConfig
}
export type SvgFillMatcher<T> = (datum: T) => boolean
export interface SvgDefsAndFill<T> {
defs?: readonly {
id: string
[key: string]: any
}[]
fill?: readonly { id: string; match: Record<string, unknown> | SvgFillMatcher<T> | '*' }[]
}
export type CssMixBlendMode =
| 'normal'
| 'multiply'
| 'screen'
| 'overlay'
| 'darken'
| 'lighten'
| 'color-dodge'
| 'color-burn'
| 'hard-light'
| 'soft-light'
| 'difference'
| 'exclusion'
| 'hue'
| 'saturation'
| 'color'
| 'luminosity'
export type StackOrder = 'ascending' | 'descending' | 'insideOut' | 'none' | 'reverse'
export type StackOffset = 'expand' | 'diverging' | 'none' | 'silhouette' | 'wiggle'
export type AreaCurve =
| 'basis'
| 'cardinal'
| 'catmullRom'
| 'linear'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'
export function useAnimatedPath(path: string): Interpolation<string>
// ------------------------------------------------------------------------
// Patterns & Gradients
// ------------------------------------------------------------------------
export type GradientColor = {
offset: number
color: string
opacity?: number
}
export function linearGradientDef(
id: string,
colors: GradientColor[],
options?: React.SVGProps<SVGLinearGradientElement>
): {
id: string
type: 'linearGradient'
colors: GradientColor[]
} & React.SVGProps<SVGLinearGradientElement>
export type LinearGradientDef = {
id: string
type: 'linearGradient'
colors: {
offset: number
color: string
opacity?: number
}[]
gradientTransform?: string
}
export type PatternDotsDef = {
id: string
type: 'patternDots'
color?: string
background?: string
size?: number
padding?: number
stagger?: boolean
}
export function patternDotsDef(
id: string,
options?: Omit<PatternDotsDef, 'id' | 'type'>
): PatternDotsDef
export function PatternDots(props: Omit<PatternDotsDef, 'type'>): JSX.Element
export type PatternSquaresDef = Omit<PatternDotsDef, 'type'> & {
type: 'patternSquares'
}
export function patternSquaresDef(
id: string,
options?: Omit<PatternSquaresDef, 'id' | 'type'>
): PatternSquaresDef
export function PatternSquares(props: Omit<PatternSquaresDef, 'type'>): JSX.Element
export type PatternLinesDef = {
id: string
type: 'patternLines'
spacing?: number
rotation?: number
background?: string
color?: string
lineWidth?: number
}
export function patternLinesDef(
id: string,
options?: Omit<PatternLinesDef, 'id' | 'type'>
): PatternLinesDef
export function PatternLines(props: Omit<PatternLinesDef, 'type'>): JSX.Element
export type Def = LinearGradientDef | PatternDotsDef | PatternSquaresDef | PatternLinesDef
export type DefsProps = {
defs: readonly Def[]
}
export function Defs(props: DefsProps): JSX.Element
// ------------------------------------------------------------------------
// Motion
// ------------------------------------------------------------------------
export const defaultAnimate = true
type MotionDefaultProps = {
animate: true
config: 'default'
}
export const motionDefaultProps: MotionDefaultProps
type DefaultMargin = {
top: 0
right: 0
bottom: 0
left: 0
}
export const defaultMargin: DefaultMargin
export function degreesToRadians(degrees: number): number
export function radiansToDegrees(radians: number): number
export function absoluteAngleDegrees(degrees: number): number
export function normalizeAngle(degrees: number): number
export function clampArc(startAngle: number, endAngle: number, length?: number): [number, number]
type Accessor<T extends keyof U, U> = T extends string ? U[T] : never
export type DatumPropertyAccessor<RawDatum, T> = (datum: RawDatum) => T
export function useDimensions(
width: number,
height: number,
margin?: Box
): {
margin: Margin
innerWidth: number
innerHeight: number
outerWidth: number
outerHeight: number
}
export function useMeasure(): [
React.RefObject<HTMLDivElement>,
{ left: number; top: number; width: number; height: number }
]
type SvgWrapperType = (
props: React.PropsWithChildren<{
width: number
height: number
margin: Margin
defs?: any
role?: string
ariaLabel?: React.AriaAttributes['aria-label']
ariaLabelledBy?: React.AriaAttributes['aria-labelledby']
ariaDescribedBy?: React.AriaAttributes['aria-describedby']
isFocusable?: boolean
}>
) => JSX.Element
export const SvgWrapper: SvgWrapperType
interface ContainerProps {
theme?: Theme
renderWrapper?: boolean
isInteractive?: boolean
animate?: boolean
motionConfig?: string | SpringConfig
}
type ContainerType = (props: React.PropsWithChildren<ContainerProps>) => JSX.Element
export const Container: ContainerType
type ResponsiveWrapperType = (props: {
children: (dimensions: { width: number; height: number }) => JSX.Element
}) => JSX.Element
export const ResponsiveWrapper: ResponsiveWrapperType
interface ThemeProviderProps {
theme?: Theme
}
type ThemeProviderType = (props: React.PropsWithChildren<ThemeProviderProps>) => JSX.Element
export const ThemeProvider: ThemeProviderType
export function getDistance(x1: number, y1: number, x2: number, y2: number): number
export function getAngle(x1: number, y1: number, x2: number, y2: number): number
export function positionFromAngle(
angle: number,
distance: number
): {
x: number
y: number
}
export type ValueFormat<Value, Context = void> =
| string // d3 formatter
// explicit formatting function
| (Context extends void ? (value: Value) => string : (value: Value, context: Context) => string)
export function getValueFormatter<Value, Context = void>(
format?: ValueFormat<Value, Context>
): Context extends void ? (value: Value) => string : (value: Value, context: Context) => string
export function useValueFormatter<Value, Context = void>(
format?: ValueFormat<Value, Context>
): Context extends void ? (value: Value) => string : (value: Value, context: Context) => string
export type PropertyAccessor<Datum, Value> =
// path to use with `lodash.get()`
| string
// explicit accessor function
| ((datum: Datum) => Value)
export function getPropertyAccessor<Datum, Value>(
accessor: PropertyAccessor<Datum, Value>
): (datum: Datum) => Value
export function usePropertyAccessor<Datum, Value>(
accessor: PropertyAccessor<Datum, Value>
): (datum: Datum) => Value
export function getRelativeCursor(
element: Element,
event: React.MouseEvent | React.TouchEvent
): [number, number]
export function isCursorInRect(
x: number,
y: number,
width: number,
height: number,
cursorX: number,
cursorY: number
): boolean
export interface CartesianMarkerProps<V extends DatumValue = DatumValue> {
axis: 'x' | 'y'
value: V
legend?: string
legendOrientation?: 'horizontal' | 'vertical'
legendPosition?: BoxAlign
lineStyle?: Partial<React.CSSProperties>
textStyle?: Partial<React.CSSProperties>
}
interface CartesianMarkersProps<
X extends DatumValue = DatumValue,
Y extends DatumValue = DatumValue
> {
width: number
height: number
xScale: (value: X) => number
yScale: (value: Y) => number
markers: readonly CartesianMarkerProps<X | Y>[]
}
type CartesianMarkersType = <X extends DatumValue = DatumValue, Y extends DatumValue = DatumValue>(
props: CartesianMarkersProps<X, Y>
) => JSX.Element
export const CartesianMarkers: CartesianMarkersType
export type CurveFactoryId =
| 'basis'
| 'basisClosed'
| 'basisOpen'
| 'bundle'
| 'cardinal'
| 'cardinalClosed'
| 'cardinalOpen'
| 'catmullRom'
| 'catmullRomClosed'
| 'catmullRomOpen'
| 'linear'
| 'linearClosed'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'
// Curve factories compatible d3 line shape generator
export type LineCurveFactoryId =
| 'basis'
| 'cardinal'
| 'catmullRom'
| 'linear'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'
// Curve factories compatible d3 area shape generator
export type AreaCurveFactoryId =
| 'basis'
| 'cardinal'
| 'catmullRom'
| 'linear'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'
export type ClosedCurveFactoryId =
| 'basisClosed'
| 'cardinalClosed'
| 'catmullRomClosed'
| 'linearClosed'
export const closedCurvePropKeys: readonly ClosedCurveFactoryId[]
export const curveFromProp: (interpolation: CurveFactoryId) => CurveFactory
export const useCurveInterpolation: (interpolation: CurveFactoryId) => CurveFactory
export interface DotsItemSymbolProps {
size: number
color: string
borderWidth: number
borderColor: string
}
export type DotsItemSymbolComponent = React.FunctionComponent<DotsItemSymbolProps>
export interface DotsItemProps<D = any> {
datum: D
x: number
y: number
size: number
color: string
borderWidth: number
borderColor: string
label?: string | number
labelTextAnchor?: 'start' | 'middle' | 'end'
labelYOffset?: number
symbol?: DotsItemSymbolComponent
}
export const DotsItem: React.FunctionComponent<DotsItemProps>
export type ExtractProps<TComponent> = TComponent extends ComponentType<infer TProps>
? TProps
: never