Skip to content

Commit

Permalink
feat(voronoi): improve voronoi (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte authored Dec 4, 2017
1 parent df4ac4e commit e1ae81a
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 131 deletions.
39 changes: 7 additions & 32 deletions src/components/charts/voronoi/ResponsiveVoronoi.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,12 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import React, { Component } from 'react'
import React from 'react'
import ResponsiveWrapper from '../ResponsiveWrapper'
import Voronoi from './Voronoi'
import Measure from 'react-measure'

export default class ResponsiveVoronoi extends Component {
state = {
dimensions: {
width: -1,
height: -1,
},
}

render() {
const { width, height } = this.state.dimensions

const shouldRender = width > 0 && height > 0

return (
<Measure
bounds
onResize={contentRect => {
this.setState({ dimensions: contentRect.bounds })
}}
>
{({ measureRef }) => (
<div ref={measureRef} style={{ width: '100%', height: '100%' }}>
{shouldRender && <Voronoi width={width} height={height} {...this.props} />}
</div>
)}
</Measure>
)
}
}
export default props => (
<ResponsiveWrapper>
{({ width, height }) => <Voronoi width={width} height={height} {...props} />}
</ResponsiveWrapper>
)
176 changes: 77 additions & 99 deletions src/components/charts/voronoi/Voronoi.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,114 +7,92 @@
* file that was distributed with this source code.
*/

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { defaultMargin, defaultColorRange } from '../../../defaults'
import React from 'react'
import { voronoi as VoronoiGenerator } from 'd3-voronoi'
import Container from '../Container'
import SvgWrapper from '../SvgWrapper'
import enhance from './enhance'
import { VoronoiPropTypes } from './props'

class Voronoi extends Component {
render() {
const {
data,
width: _width,
height: _height,
margin: _margin,
x,
y,
enableSites,
enableLinks,
enablePolygons,
borderWidth,
borderColor,
linkWidth,
linkColor,
} = this.props
const Voronoi = ({
data,

const margin = Object.assign({}, defaultMargin, _margin)
const width = _width - margin.left - margin.right
const height = _height - margin.top - margin.bottom
// dimensions
margin,
width,
height,
outerWidth,
outerHeight,

const voronoi = VoronoiGenerator()
.x(d => d[x])
.y(d => d[y])
.extent([[0, 0], [width, height]])
// features
enableSites,
enableLinks,
enablePolygons,

const polygons = voronoi.polygons(data)
const links = voronoi.links(data)
// styling
theme,
borderWidth,
borderColor,
linkWidth,
linkColor,
siteSize,
siteColor,
}) => {
const voronoi = VoronoiGenerator()
.x(d => d.x)
.y(d => d.y)
.extent([[0, 0], [width, height]])

return (
<svg xmlns="http://www.w3.org/2000/svg" width={_width} height={_height}>
<g transform={`translate(${margin.left},${margin.top})`}>
const polygons = voronoi.polygons(data)
const links = voronoi.links(data)

return (
<Container isInteractive={false} theme={theme}>
{({ showTooltip, hideTooltip }) => (
<SvgWrapper width={outerWidth} height={outerHeight} margin={margin}>
{enableLinks &&
links.map((l, i) => {
return (
<line
key={i}
fill="none"
stroke={linkColor}
strokeWidth={linkWidth}
x1={l.source[0]}
y1={l.source[1]}
x2={l.target[0]}
y2={l.target[1]}
/>
)
})}
links.map(l => (
<line
key={`${l.source.id}.${l.target.id}`}
fill="none"
stroke={linkColor}
strokeWidth={linkWidth}
x1={l.source.x}
y1={l.source.y}
x2={l.target.x}
y2={l.target.y}
/>
))}
{enablePolygons &&
polygons.map((p, i) => {
return (
<path
key={i}
fill="none"
stroke={borderColor}
strokeWidth={borderWidth}
d={`M${p.join('L')}Z`}
/>
)
})}
polygons.map(p => (
<path
key={p.data.id}
fill="none"
stroke={borderColor}
strokeWidth={borderWidth}
d={`M${p.join('L')}Z`}
onClick={() => {
console.log(p.data)
}}
/>
))}
{enableSites &&
data.map((d, i) => {
return (
<circle
key={i}
r="2.5"
cx={d[0]}
cy={d[1]}
fill="#F00"
stroke="none"
/>
)
})}
</g>
</svg>
)
}
}

Voronoi.propTypes = {
enableSites: PropTypes.bool.isRequired,
enableLinks: PropTypes.bool.isRequired,
enablePolygons: PropTypes.bool.isRequired,
x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
colors: PropTypes.any.isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.string.isRequired,
linkWidth: PropTypes.number.isRequired,
linkColor: PropTypes.string.isRequired,
data.map(d => (
<circle
key={d.id}
r={siteSize / 2}
cx={d.x}
cy={d.y}
fill={siteColor}
stroke="none"
/>
))}
</SvgWrapper>
)}
</Container>
)
}

Voronoi.defaultProps = {
enableSites: true,
enableLinks: true,
enablePolygons: true,
x: 0,
y: 1,
borderWidth: 1,
borderColor: '#000',
linkWidth: 1,
linkColor: '#bbb',
colors: defaultColorRange,
}
Voronoi.propTypes = VoronoiPropTypes

export default Voronoi
export default enhance(Voronoi)
17 changes: 17 additions & 0 deletions src/components/charts/voronoi/enhance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* 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 from 'react'
import compose from 'recompose/compose'
import defaultProps from 'recompose/defaultProps'
import pure from 'recompose/pure'
import { withTheme, withDimensions } from '../../../hocs'
import { VoronoiDefaultProps } from './props'

export default Component =>
compose(defaultProps(VoronoiDefaultProps), withTheme(), withDimensions(), pure)(Component)
1 change: 1 addition & 0 deletions src/components/charts/voronoi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@

export { default as Voronoi } from './Voronoi'
export { default as ResponsiveVoronoi } from './ResponsiveVoronoi'
export * from './props'
44 changes: 44 additions & 0 deletions src/components/charts/voronoi/props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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 PropTypes from 'prop-types'

export const VoronoiPropTypes = {
data: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
})
).isRequired,
enablePolygons: PropTypes.bool.isRequired,
enableSites: PropTypes.bool.isRequired,
enableLinks: PropTypes.bool.isRequired,
x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.string.isRequired,
linkWidth: PropTypes.number.isRequired,
linkColor: PropTypes.string.isRequired,
siteSize: PropTypes.number.isRequired,
siteColor: PropTypes.string.isRequired,
}

export const VoronoiDefaultProps = {
enablePolygons: true,
enableSites: false,
enableLinks: false,
x: 0,
y: 1,
borderWidth: 2,
borderColor: '#000',
linkWidth: 1,
linkColor: '#bbb',
siteSize: 4,
siteColor: '#666',
}

0 comments on commit e1ae81a

Please sign in to comment.