Skip to content

Commit

Permalink
feat(chord): add labels, stories and cavans variant for Chord component
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte committed Sep 1, 2017
1 parent f13f95b commit 281021b
Show file tree
Hide file tree
Showing 46 changed files with 897 additions and 358 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"husky": "^0.14.3",
"jest": "^20.0.4",
"lint-staged": "^4.0.3",
"nivo-generators": "0.9.0",
"nivo-generators": "0.9.3",
"prettier": "^1.5.3",
"react": "^15.6.1",
"react-dom": "^15.6.1",
Expand Down
6 changes: 3 additions & 3 deletions src/components/axes/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import pure from 'recompose/pure'
import Nivo from '../../Nivo'
import { defaultMotionDamping, defaultMotionStiffness } from '../../defaults'
import GridLines from './GridLines'
import { motionPropTypes } from '../../props'

Expand Down Expand Up @@ -110,8 +110,8 @@ Grid.propTypes = {
Grid.defaultProps = {
// motion
animate: true,
motionStiffness: Nivo.defaults.motionStiffness,
motionDamping: Nivo.defaults.motionDamping,
motionStiffness: defaultMotionStiffness,
motionDamping: defaultMotionDamping,
}

export default pure(Grid)
1 change: 0 additions & 1 deletion src/components/axes/GridLines.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { TransitionMotion, spring } from 'react-motion'
import Nivo from '../../Nivo'
import GridLine from './GridLine'

export default class GridLines extends Component {
Expand Down
4 changes: 2 additions & 2 deletions src/components/charts/bar/BarCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Container from '../Container'
import BasicTooltip from '../../tooltip/BasicTooltip'
import { BarPropTypes } from './props'
import enhance from './enhance'
import { getRelativeCursor, cursorInRect } from '../../../lib/interactivity'
import { getRelativeCursor, isCursorInRect } from '../../../lib/interactivity'

class BarCanvas extends Component {
componentDidMount() {
Expand Down Expand Up @@ -116,7 +116,7 @@ class BarCanvas extends Component {

const { margin, theme } = this.props
const bar = this.bars.find(bar =>
cursorInRect(bar.x + margin.left, bar.y + margin.top, bar.width, bar.height, x, y)
isCursorInRect(bar.x + margin.left, bar.y + margin.top, bar.width, bar.height, x, y)
)

if (bar !== undefined) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/charts/calendar/Calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
import _ from 'lodash'
import React, { Component } from 'react'
import Nivo from '../../../Nivo'
import { defaultMargin } from '../../../defaults'
import SvgWrapper from '../SvgWrapper'
import CalendarLayout from '../../../lib/charts/calendar/CalendarLayout'
import { calendarPropTypes, calendarDefaultProps } from './CalendarProps'
Expand Down Expand Up @@ -54,7 +54,7 @@ export default class Calendar extends Component {
motionDamping,
} = this.props

const margin = Object.assign({}, Nivo.defaults.margin, this.props.margin)
const margin = Object.assign({}, defaultMargin, this.props.margin)
const width = this.props.width - margin.left - margin.right
const height = this.props.height - margin.top - margin.bottom

Expand Down
24 changes: 13 additions & 11 deletions src/components/charts/calendar/CalendarProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
import PropTypes from 'prop-types'
import Nivo from '../../../Nivo'
import { defaultMargin, defaultMotionDamping, defaultMotionStiffness } from '../../../defaults'
import { marginPropType, scalePropType } from '../../../props'
import { DIRECTION_HORIZONTAL, DIRECTION_VERTICAL } from '../../../constants/directions'

Expand All @@ -34,24 +34,25 @@ export const calendarPropTypes = {
direction: oneOf([DIRECTION_HORIZONTAL, DIRECTION_VERTICAL]),
colorScale: scalePropType.isRequired,
emptyColor: string.isRequired,

// years
yearSpacing: number.isRequired,
yearLegendOffset: number.isRequired,

// days
daySpacing: number.isRequired,
dayBorderWidth: number.isRequired,
dayBorderColor: string.isRequired,

// months
monthBorderWidth: number.isRequired,
monthBorderColor: string.isRequired,
monthLegendOffset: number.isRequired,

// transitions
animate: bool.isRequired,
motionStiffness: number.isRequired, // react-motion
motionDamping: number.isRequired, // react-motion
transitionDuration: number.isRequired, // d3 transitions
transitionEasing: string.isRequired, // d3 transitions
transitionStaggering: number.isRequired, // d3 transitions
}

/**
Expand All @@ -60,26 +61,27 @@ export const calendarPropTypes = {
* @type {object}
*/
export const calendarDefaultProps = {
margin: Nivo.defaults.margin,
margin: defaultMargin,
direction: DIRECTION_HORIZONTAL,
onDayClick: () => {},
emptyColor: '#fff',

// years
yearSpacing: 30,
yearLegendOffset: 10,

// days
daySpacing: 0,
dayBorderWidth: 1,
dayBorderColor: '#000',

// months
monthBorderWidth: 2,
monthBorderColor: '#000',
monthLegendOffset: 6,
// transitions

// motion
animate: false,
motionStiffness: Nivo.defaults.motionStiffness, // react-motion
motionDamping: Nivo.defaults.motionDamping, // react-motion
transitionDuration: Nivo.defaults.transitionDuration, // d3 transitions
transitionEasing: Nivo.defaults.transitionEasing, // d3 transitions
transitionStaggering: 5, // d3 transitions
motionStiffness: defaultMotionStiffness, // react-motion
motionDamping: defaultMotionDamping, // react-motion
}
95 changes: 27 additions & 68 deletions src/components/charts/chord/Chord.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,111 +7,60 @@
* file that was distributed with this source code.
*/
import React from 'react'
import { getColorRange } from '../../../lib/colors'
import Container from '../Container'
import SvgWrapper from '../SvgWrapper'
import enhance from './enhance'
import { ChordPropTypes } from './props'
import ChordRibbons from './ChordRibbons'
import ChordArcs from './ChordArcs'
import ChordLabels from './ChordLabels'

const Chord = ({
matrix,
keys,

// dimensions
margin,
width,
height,
outerWidth,
outerHeight,

ribbonOpacity,
ribbonBorderWidth,
arcOpacity,
// arcs
arcBorderWidth,

chord, // computed
// ribbons
ribbonBorderWidth,

// labels
enableLabels,
getLabel, // computed
labelOffset,
labelRotation,
getLabelTextColor,

arcGenerator, // computed
ribbonGenerator, // computed

// theming
theme,
colors,

// interactivity
isInteractive,
arcHoverOpacity,
arcHoverOthersOpacity,
ribbonHoverOpacity,
ribbonHoverOthersOpacity,

// motion
animate,
motionDamping,
motionStiffness,

currentArc,
ribbons, // computed
arcs, // computed
radius, // computed
setCurrentArc,
currentRibbon,
setCurrentRibbon,
getArcOpacity,
getRibbonOpacity,
}) => {
const centerX = width / 2
const centerY = height / 2

const color = getColorRange(colors)

const colorById = keys.reduce((acc, key) => {
acc[key] = color(key)
return acc
}, {})

const ribbons = chord(matrix)
ribbons.forEach(ribbon => {
ribbon.source.id = keys[ribbon.source.index]
ribbon.source.color = colorById[ribbon.source.id]
ribbon.target.id = keys[ribbon.target.index]
ribbon.target.color = colorById[ribbon.target.id]
const ribbonKeys = [ribbon.source.id, ribbon.target.id]
ribbonKeys.sort()
ribbon.key = ribbonKeys.sort().join('.')
})

const arcs = ribbons.groups.map(arc => {
arc.key = arc.id = keys[arc.index]
arc.color = colorById[arc.id]
return arc
})

let getArcOpacity = () => arcOpacity
let getRibbonOpacity = () => ribbonOpacity
if (isInteractive) {
if (currentArc) {
getArcOpacity = arc => {
if (arc.id === currentArc.id) return arcHoverOpacity
return arcHoverOthersOpacity
}
getRibbonOpacity = ribbon => {
if (ribbon.source.id === currentArc.id) return ribbonHoverOpacity
return ribbonHoverOthersOpacity
}
} else if (currentRibbon) {
getArcOpacity = arc => {
if (arc.id === currentRibbon.source.id || arc.id === currentRibbon.target.id)
return arcHoverOpacity
return arcHoverOthersOpacity
}
getRibbonOpacity = ribbon => {
if (
ribbon.source.id === currentRibbon.source.id &&
ribbon.target.id === currentRibbon.target.id
)
return ribbonHoverOpacity
return ribbonHoverOthersOpacity
}
}
}

const motionProps = {
animate,
motionDamping,
Expand Down Expand Up @@ -146,6 +95,16 @@ const Chord = ({
hideTooltip={hideTooltip}
{...motionProps}
/>
{enableLabels &&
<ChordLabels
arcs={arcs}
radius={radius + labelOffset}
rotation={labelRotation}
getLabel={getLabel}
getColor={getLabelTextColor}
theme={theme}
{...motionProps}
/>}
</g>
</SvgWrapper>
)
Expand Down
22 changes: 22 additions & 0 deletions src/components/charts/chord/ChordArcTooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 PropTypes from 'prop-types'
import pure from 'recompose/pure'
import BasicTooltip from '../../tooltip/BasicTooltip'

const ChordArcTooltip = ({ arc, theme }) =>
<BasicTooltip id={arc.id} value={arc.value} color={arc.color} enableChip={true} theme={theme} />

ChordArcTooltip.propTypes = {
arc: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
}

export default pure(ChordArcTooltip)
11 changes: 5 additions & 6 deletions src/components/charts/chord/ChordArcs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
import React from 'react'
import PropTypes from 'prop-types'
import { TransitionMotion, spring } from 'react-motion'
import pure from 'recompose/pure'
import { colorMotionSpring, getInterpolatedColor } from '../../../lib/colors'
import BasicTooltip from '../../tooltip/BasicTooltip'

const ArcTooltip = ({ arc, theme }) =>
<BasicTooltip id={arc.id} value={arc.value} color={arc.color} enableChip={true} theme={theme} />
import ChordArcTooltip from './ChordArcTooltip'

const ChordArcs = ({
arcs,
Expand All @@ -31,7 +29,7 @@ const ChordArcs = ({
motionStiffness,
}) => {
const commonProps = arc => {
const arcTooltip = <ArcTooltip arc={arc} theme={theme} />
const arcTooltip = <ChordArcTooltip arc={arc} theme={theme} />

return {
strokeWidth: arcBorderWidth,
Expand Down Expand Up @@ -74,6 +72,7 @@ const ChordArcs = ({
const springConfig = {
damping: motionDamping,
stiffness: motionStiffness,
precision: 0.001,
}

return (
Expand Down Expand Up @@ -127,4 +126,4 @@ ChordArcs.propTypes = {
hideTooltip: PropTypes.func.isRequired,
}

export default ChordArcs
export default pure(ChordArcs)
Loading

0 comments on commit 281021b

Please sign in to comment.