Skip to content

Commit

Permalink
feat(scatterplot): improve Mesh support for SVG implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored and Raphaël Benitte committed Jun 8, 2019
1 parent ac012ba commit 91f66dc
Show file tree
Hide file tree
Showing 22 changed files with 623 additions and 332 deletions.
2 changes: 1 addition & 1 deletion examples/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@types/node": "^10.12.0",
"@types/react": "^16.8.9",
"@types/react-dom": "^16.8.3",
"typescript": "^3.3.4000"
"typescript": "^3.5.1"
},
"scripts": {
"start": "react-scripts-ts start",
Expand Down
8 changes: 4 additions & 4 deletions examples/typescript/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7209,10 +7209,10 @@ typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"

typescript@^3.3.4000:
version "3.3.4000"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.4000.tgz#76b0f89cfdbf97827e1112d64f283f1151d6adf0"
integrity sha512-jjOcCZvpkl2+z7JFn0yBOoLQyLoIkNZAs/fYJkUG6VKy6zLPHJGfQJYFHzibB6GJaF/8QrcECtlQ5cpvRHSMEA==
typescript@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202"
integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==

ua-parser-js@^0.7.18:
version "0.7.18"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"rollup-plugin-typescript2": "^0.21.0",
"serve": "^10.1.2",
"tslint": "^5.16.0",
"typescript": "^3.3.4000"
"typescript": "^3.5.1"
},
"resolutions": {
"upath": "1.1.0",
Expand Down
37 changes: 10 additions & 27 deletions packages/core/src/components/cartesian/markers/CartesianMarkers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,18 @@ import React, { memo } from 'react'
import PropTypes from 'prop-types'
import CartesianMarkersItem from './CartesianMarkersItem'

const CartesianMarkers = ({ markers, width, height, xScale, yScale, theme }) => {
const CartesianMarkers = ({ markers, width, height, xScale, yScale }) => {
if (!markers || markers.length === 0) return null

return (
<g>
{markers.map((marker, i) => (
<CartesianMarkersItem
key={i}
{...marker}
width={width}
height={height}
scale={marker.axis === 'y' ? yScale : xScale}
theme={theme}
/>
))}
</g>
)
return markers.map((marker, i) => (
<CartesianMarkersItem
key={i}
{...marker}
width={width}
height={height}
scale={marker.axis === 'y' ? yScale : xScale}
/>
))
}

CartesianMarkers.propTypes = {
Expand All @@ -36,18 +31,6 @@ CartesianMarkers.propTypes = {
xScale: PropTypes.func.isRequired,
yScale: PropTypes.func.isRequired,

theme: PropTypes.shape({
markers: PropTypes.shape({
lineColor: PropTypes.string.isRequired,
lineStrokeWidth: PropTypes.number.isRequired,
text: PropTypes.shape({
fill: PropTypes.string.isRequired,
fontFamily: PropTypes.string.isRequired,
fontSize: PropTypes.number.isRequired,
}).isRequired,
}).isRequired,
}).isRequired,

markers: PropTypes.arrayOf(
PropTypes.shape({
axis: PropTypes.oneOf(['x', 'y']).isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
import React, { memo } from 'react'
import PropTypes from 'prop-types'
import { useTheme } from '../../../theming'

/**
*
Expand Down Expand Up @@ -167,7 +168,6 @@ const CartesianMarkersItem = ({
axis,
scale,
value,
theme,
lineStyle,
textStyle,
legend,
Expand All @@ -176,6 +176,8 @@ const CartesianMarkersItem = ({
legendOffsetY,
legendOrientation,
}) => {
const theme = useTheme()

let x = 0
let x2 = 0
let y = 0
Expand Down Expand Up @@ -254,13 +256,6 @@ CartesianMarkersItem.propTypes = {
legendOffsetX: PropTypes.number.isRequired,
legendOffsetY: PropTypes.number.isRequired,
legendOrientation: PropTypes.oneOf(['horizontal', 'vertical']).isRequired,

theme: PropTypes.shape({
markers: PropTypes.shape({
textColor: PropTypes.string.isRequired,
fontSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
}).isRequired,
}).isRequired,
}
CartesianMarkersItem.defaultProps = {
legendPosition: 'top-right',
Expand Down
20 changes: 12 additions & 8 deletions packages/line/src/Line.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { Fragment, useState } from 'react'
import React, { Fragment, useState, useMemo } from 'react'
import { withContainer, useDimensions, useTheme, SvgWrapper, CartesianMarkers } from '@nivo/core'
import { useInheritedColor } from '@nivo/colors'
import { Axes, Grid } from '@nivo/axes'
Expand Down Expand Up @@ -115,13 +115,17 @@ const Line = props => {
const [currentPoint, setCurrentPoint] = useState(null)
const [currentSlice, setCurrentSlice] = useState(null)

const legendData = series
.map(line => ({
id: line.id,
label: line.id,
color: line.color,
}))
.reverse()
const legendData = useMemo(
() =>
series
.map(line => ({
id: line.id,
label: line.id,
color: line.color,
}))
.reverse(),
[series]
)

const layerById = {
grid: (
Expand Down
33 changes: 31 additions & 2 deletions packages/scatterplot/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { LegendProps } from '@nivo/legends'
import { AxisProps } from '@nivo/axes'
import { Scale } from '@nivo/scales'

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

declare module '@nivo/scatterplot' {
export type Value = number | string | Date
export type ValueFormatter = (value: Value) => string | number
Expand Down Expand Up @@ -83,6 +85,33 @@ declare module '@nivo/scatterplot' {

export type CustomTooltip = ({ node: Node }) => React.ReactNode

type Scale = (value: Value) => number

export interface ScatterPlotComputedProps {
xScale: Scale
yScale: Scale
nodes: Node[]
innerWidth: number
innerHeight: number
outerWidth: number
outerHeight: number
}

export interface CustomSvgLayerProps
extends Omit<ScatterPlotSvgProps, 'xScale' | 'yScale'>,
ScatterPlotComputedProps {}
export interface CustomCanvasLayerProps
extends Omit<ScatterPlotCanvasProps, 'xScale' | 'yScale'>,
ScatterPlotComputedProps {}

export type CustomSvgLayer = (props: CustomSvgLayerProps) => React.ReactNode
export type CustomCanvasLayer = (
ctx: CanvasRenderingContext2D,
props: CustomCanvasLayerProps
) => void

export type CustomLayerId = 'grid' | 'axes' | 'nodes' | 'markers' | 'mesh' | 'legends'

export interface ScatterPlotProps {
data: Serie[]

Expand All @@ -93,8 +122,6 @@ declare module '@nivo/scatterplot' {

margin?: Box

layers: any[]

theme?: Theme
colors?: OrdinalColorsInstruction
blendMode?: CssMixBlendMode
Expand All @@ -121,6 +148,7 @@ declare module '@nivo/scatterplot' {
}

export interface ScatterPlotSvgProps extends ScatterPlotProps, MotionProps {
layers?: Array<CustomLayerId | CustomSvgLayer>
renderNode?: NodeComponent
markers?: CartesianMarkerProps[]
}
Expand All @@ -130,6 +158,7 @@ declare module '@nivo/scatterplot' {

export interface ScatterPlotCanvasProps extends ScatterPlotProps {
pixelRatio?: number
layers?: Array<CustomLayerId | CustomCanvasLayer>
renderNode?: NodeCanvasComponent
}

Expand Down
70 changes: 70 additions & 0 deletions packages/scatterplot/src/Mesh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file is part of the nivo project.
*
* Copyright 2016-present, Raphaël Benitte.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo, useCallback } from 'react'
import PropTypes from 'prop-types'
import { useTooltip } from '@nivo/tooltip'
import { Mesh as BaseMesh } from '@nivo/voronoi'
import { NodePropType } from './props'

const Mesh = ({ nodes, width, height, onMouseEnter, onMouseMove, onClick, tooltip, debug }) => {
const { showTooltipFromEvent, hideTooltip } = useTooltip()

const handleMouseEnter = useCallback(
(node, event) => {
showTooltipFromEvent(React.createElement(tooltip, { node }), event)
onMouseEnter && onMouseEnter(node, event)
},
[showTooltipFromEvent, tooltip, onMouseEnter]
)

const handleMouseMove = useCallback(
(node, event) => {
showTooltipFromEvent(React.createElement(tooltip, { node }), event)
onMouseMove && onMouseMove(node, event)
},
[showTooltipFromEvent, tooltip, onMouseMove]
)

const handleMouseLeave = useCallback(() => {
hideTooltip()
}, [hideTooltip])

const handleClick = useCallback(
(node, event) => {
onClick && onClick(node, event)
},
[onClick]
)

return (
<BaseMesh
nodes={nodes}
width={width}
height={height}
onMouseEnter={handleMouseEnter}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
debug={debug}
/>
)
}

Mesh.propTypes = {
nodes: PropTypes.arrayOf(NodePropType).isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
onMouseEnter: PropTypes.func,
onMouseMove: PropTypes.func,
onClick: PropTypes.func,
tooltip: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,
debug: PropTypes.bool.isRequired,
}

export default memo(Mesh)
15 changes: 1 addition & 14 deletions packages/scatterplot/src/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,7 @@ const Node = ({
)

Node.propTypes = {
node: PropTypes.shape({
data: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
x: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.instanceOf(Date)])
.isRequired,
y: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.instanceOf(Date)])
.isRequired,
serie: PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
}).isRequired,
}).isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
}).isRequired,
node: PropTypes.object.isRequired,

x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
Expand Down
1 change: 1 addition & 0 deletions packages/scatterplot/src/NodeWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const NodeWrapper = ({

NodeWrapper.propTypes = {
node: NodePropType.isRequired,
renderNode: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,

x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
Expand Down
Loading

0 comments on commit 91f66dc

Please sign in to comment.