diff --git a/package.json b/package.json index c7e0fdb30..0c4aa07a9 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,9 @@ "test:unit": "jest --verbose ./test", "test:unit:cover": "jest --verbose --coverage ./test", "build:commonjs": "cross-env NODE_ENV=commonjs babel src --out-dir lib", + "build:commonjs:watch": "npm run build:commonjs -- --watch", "build:es": "cross-env NODE_ENV=es babel src --out-dir es", + "build:es:watch": "npm run build:es -- --watch", "build": "npm run build:commonjs && npm run build:es", "fmt": "prettier --print-width=100 --tab-width=4 --bracket-spacing --no-semi --trailing-comma es5 --single-quote --color --write \"{src,specs,test}/**/*.js\"", "fmt:check": "prettier --print-width=100 --tab-width=4 --bracket-spacing --no-semi --trailing-comma es5 --single-quote --list-different \"{src,specs,test}/**/*.js\"", diff --git a/src/HierarchyUtils.js b/src/HierarchyUtils.js deleted file mode 100644 index 46c744a07..000000000 --- a/src/HierarchyUtils.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ -export const HIERARCHICAL_NODE_TYPE_ROOT = 'root' -export const HIERARCHICAL_NODE_TYPE_INTERMEDIATE = 'intermediate' -export const HIERARCHICAL_NODE_TYPE_LEAF = 'leaf' - -export const getHierarchicalNodeType = node => { - if (node.depth === 0) { - return HIERARCHICAL_NODE_TYPE_ROOT - } else if (!node.children || node.children.length === 0) { - return HIERARCHICAL_NODE_TYPE_LEAF - } - - return HIERARCHICAL_NODE_TYPE_INTERMEDIATE -} diff --git a/src/Nivo.js b/src/Nivo.js index c8080a5d2..d7ba2e424 100644 --- a/src/Nivo.js +++ b/src/Nivo.js @@ -8,7 +8,7 @@ */ import { scaleOrdinal } from 'd3-scale' import { schemeSet3 } from 'd3-scale-chromatic' -import { nivoCategoricalColors } from './ColorUtils' +import { nivoCategoricalColors } from './lib/colorUtils' const defaults = { transitionDuration: 600, diff --git a/src/PropTypes.js b/src/PropTypes.js deleted file mode 100644 index 5b6b9b3a5..000000000 --- a/src/PropTypes.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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' - -const { number, string, array, shape, oneOf } = PropTypes - -export const lineInterpolation = oneOf([ - 'linear', // piecewise linear segments, as in a polyline. - 'linear-closed', // close the linear segments to form a polygon. - 'step', // alternate between horizontal and vertical segments, as in a step function. - 'step-before', // alternate between vertical and horizontal segments, as in a step function. - 'step-after', // alternate between horizontal and vertical segments, as in a step function. - 'basis', // a B-spline, with control point duplication on the ends. - 'basis-open', // an open B-spline; may not intersect the start or end. - 'basis-closed', // a closed B-spline, as in a loop. - 'bundle', // equivalent to basis, except the tension parameter is used to straighten the spline. - 'cardinal', // a Cardinal spline, with control point duplication on the ends. - 'cardinal-open', // an open Cardinal spline; may not intersect the start or end, but will intersect other control points. - 'cardinal-closed', // a closed Cardinal spline, as in a loop. - 'monotone', // cubic interpolation that preserves monotonicity in y. -]) - -export const scale = shape({ - type: string.isRequired, - domain: array.isRequired, - range: array.isRequired, -}) - -export const margin = shape({ - top: number, - right: number, - bottom: number, - left: number, -}).isRequired - -export const motion = { - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, -} diff --git a/src/components/axes/Axes.js b/src/components/axes/Axes.js index 53e73f400..5ed1364ef 100644 --- a/src/components/axes/Axes.js +++ b/src/components/axes/Axes.js @@ -8,7 +8,7 @@ */ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { motion as motionPropTypes } from '../../PropTypes' +import { motionPropTypes } from '../../props' import Axis from './Axis' const horizontalPositions = ['top', 'bottom'] diff --git a/src/components/axes/Axis.js b/src/components/axes/Axis.js index 8a2c7e04c..5e64a4c35 100644 --- a/src/components/axes/Axis.js +++ b/src/components/axes/Axis.js @@ -9,7 +9,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { TransitionMotion, spring } from 'react-motion' -import { motion as motionPropTypes } from '../../PropTypes' +import { motionPropTypes } from '../../props' import Nivo from '../../Nivo' import AxisTick from './AxisTick' diff --git a/src/components/charts/Chart.js b/src/components/charts/Chart.js deleted file mode 100644 index bef8c695a..000000000 --- a/src/components/charts/Chart.js +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import _ from 'lodash' -import Nivo from '../../Nivo' -import { margin as marginPropType } from '../../PropTypes' -import Scale from '../scales/Scale' - -const defaultTheme = { - axis: { - textColor: '#000', - fontSize: '11px', - tickColor: '#000', - legendColor: '#000', - legendFontSize: '11px', - }, - grid: { - stroke: '#000', - strokeDasharray: '3,6', - }, -} - -export default class Chart extends Component { - static propTypes = { - // dimensions - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - margin: marginPropType, - // composition - children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]), - // data - data: PropTypes.arrayOf(PropTypes.object).isRequired, - // motion - animate: PropTypes.bool.isRequired, - motionStiffness: PropTypes.number.isRequired, - motionDamping: PropTypes.number.isRequired, - } - - static defaultProps = { - // dimensions - margin: Nivo.defaults.margin, - // motion - animate: true, - motionStiffness: Nivo.defaults.motionStiffness, - motionDamping: Nivo.defaults.motionDamping, - } - - static childContextTypes = { - nivoTheme: PropTypes.object.isRequired, - } - - getChildContext() { - const theme = _.merge({}, defaultTheme, this.props.theme || {}) - - return { nivoTheme: theme } - } - - render() { - const { - data, - children, - margin: _margin, - width: _width, - height: _height, - animate, - motionStiffness, - motionDamping, - } = this.props - - const animationProps = { - animate, - motionStiffness, - motionDamping, - } - - const margin = Object.assign({}, Nivo.defaults.margin, _margin) - const width = _width - margin.left - margin.right - const height = _height - margin.top - margin.bottom - - const scales = {} - const axes = [] - const items = [] - - React.Children.forEach(children, (child, i) => { - if (child.type === Scale) { - scales[child.props.id] = Scale.create(child.props, data, width, height) - } else { - const item = React.cloneElement(child, { - ...child.props, - ...animationProps, - key: i, - data, - scales, - width, - height, - }) - - items.push(item) - } - }) - - return ( - - - {axes} - {items} - - - ) - } -} diff --git a/src/components/charts/ResponsiveChart.js b/src/components/charts/ResponsiveChart.js deleted file mode 100644 index 7e145c0a6..000000000 --- a/src/components/charts/ResponsiveChart.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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, { Component } from 'react' -import Measure from 'react-measure' -import Chart from './Chart' - -export default class ResponsiveChart extends Component { - state = { - dimensions: { - width: -1, - height: -1, - }, - } - - render() { - const { width, height } = this.state.dimensions - - const shouldRender = width > 0 && height > 0 - - return ( - { - this.setState({ dimensions: contentRect.bounds }) - }} - > - {({ measureRef }) => -
- {shouldRender && } -
} -
- ) - } -} diff --git a/src/components/charts/Tree.js b/src/components/charts/Tree.js deleted file mode 100644 index 1bf8e6cbf..000000000 --- a/src/components/charts/Tree.js +++ /dev/null @@ -1,431 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import { findDOMNode } from 'react-dom' -import Dimensions from 'react-dimensions' -import _ from 'lodash' -import d3 from 'd3' -import Nivo from '../../Nivo' -import { margin as marginPropType } from '../../PropTypes' -import { getColorRange } from '../../ColorUtils' -import makeLabel, { - LABEL_POSITION_TOP, - LABEL_POSITION_RIGHT, - LABEL_POSITION_BOTTOM, - LABEL_POSITION_LEFT, -} from '../../lib/charts/labels' -import { - HIERARCHICAL_NODE_TYPE_ROOT, - HIERARCHICAL_NODE_TYPE_LEAF, - getHierarchicalNodeType, -} from '../../HierarchyUtils' - -const horizontalDiagonal = d3.svg.diagonal().projection(d => [d.y, d.x]) -const verticalDiagonal = d3.svg.diagonal().projection(d => [d.x, d.y]) - -const horizontalTransform = d => `translate(${d.y},${d.x})` -const verticalTransform = d => `translate(${d.x},${d.y})` - -const horizontalLabelTextAnchor = d => (d.children ? 'end' : 'start') -const horizontalReverseLabelTextAnchor = d => (d.children ? 'start' : 'end') -const verticalLabelTextAnchor = 'middle' - -const labelPositions = { - root: { - horizontal: LABEL_POSITION_LEFT, - 'horizontal-reverse': LABEL_POSITION_RIGHT, - vertical: LABEL_POSITION_TOP, - 'vertical-reverse': LABEL_POSITION_BOTTOM, - }, - intermediate: { - horizontal: LABEL_POSITION_LEFT, - 'horizontal-reverse': LABEL_POSITION_RIGHT, - vertical: LABEL_POSITION_TOP, - 'vertical-reverse': LABEL_POSITION_BOTTOM, - }, - leaf: { - horizontal: LABEL_POSITION_RIGHT, - 'horizontal-reverse': LABEL_POSITION_LEFT, - vertical: LABEL_POSITION_LEFT, - 'vertical-reverse': LABEL_POSITION_RIGHT, - }, -} - -const computeLabelPositions = ({ - direction, - rootLabelPosition, - intermediateLabelPosition, - leafLabelPosition, -}) => { - rootLabelPosition = rootLabelPosition || labelPositions.root[direction] - intermediateLabelPosition = intermediateLabelPosition || labelPositions.intermediate[direction] - leafLabelPosition = leafLabelPosition || labelPositions.leaf[direction] - - return { - rootLabelPosition, - intermediateLabelPosition, - leafLabelPosition, - } -} - -const labelRotations = { - root: { - horizontal: 0, - 'horizontal-reverse': 0, - vertical: 0, - 'vertical-reverse': 0, - }, - intermediate: { - horizontal: 0, - 'horizontal-reverse': 0, - vertical: 0, - 'vertical-reverse': 0, - }, - leaf: { - horizontal: 0, - 'horizontal-reverse': 0, - vertical: -90, - 'vertical-reverse': -90, - }, -} - -const computeLabelRotations = ({ - direction, - rootLabelRotation, - intermediateLabelRotation, - leafLabelRotation, -}) => { - rootLabelRotation = rootLabelRotation || labelRotations.root[direction] - intermediateLabelRotation = intermediateLabelRotation || labelRotations.intermediate[direction] - leafLabelRotation = leafLabelRotation || labelRotations.leaf[direction] - - return { - rootLabelRotation, - intermediateLabelRotation, - leafLabelRotation, - } -} - -class Tree extends Component { - renderD3(nextProps) { - const { - root, - identity, - labelFn, - containerWidth, - containerHeight, - direction, - colors, - nodeRadius, - transitionDuration, - transitionEasing, - labelOffset, - labelPaddingX, - labelPaddingY, - } = nextProps - - const margin = _.assign({}, Nivo.defaults.margin, this.props.margin) - - const width = containerWidth - margin.left - margin.right - const height = containerHeight - margin.top - margin.bottom - - const element = d3.select(findDOMNode(this)).attr({ - width: containerWidth, - height: containerHeight, - }) - - let position - let size - let diagonal - let transformer - let labelTextAnchor - - switch (direction) { - case 'horizontal': - position = [margin.left, margin.top] - size = [height, width] - diagonal = horizontalDiagonal - transformer = horizontalTransform - labelTextAnchor = horizontalLabelTextAnchor - break - - case 'horizontal-reverse': - position = [margin.left + width, margin.top] - size = [height, -width] - diagonal = horizontalDiagonal - transformer = horizontalTransform - labelTextAnchor = horizontalReverseLabelTextAnchor - break - - case 'vertical': - position = [margin.left, margin.top] - size = [width, height] - diagonal = verticalDiagonal - transformer = verticalTransform - labelTextAnchor = verticalLabelTextAnchor - break - - case 'vertical-reverse': - position = [margin.left, margin.top + height] - size = [width, -height] - diagonal = verticalDiagonal - transformer = verticalTransform - labelTextAnchor = verticalLabelTextAnchor - break - } - - const wrapper = element.select('.nivo_tree_wrapper').attr({ width, height }) - const previousNodes = _.cloneDeep(wrapper.selectAll('.nivo_tree_circle').data()) - - wrapper - //.transition() - //.duration(transitionDuration) - //.ease(transitionEasing) - .attr('transform', `translate(${position[0]},${position[1]})`) - - const cluster = d3.layout.cluster().size(size) - - const color = getColorRange(colors) - - // prevents mutation on the original object by cloning original dataset - // add color to each datum - const nodes = cluster.nodes(_.cloneDeep(root)).map(node => { - node.hierarchicalType = getHierarchicalNodeType(node) - if (node.depth <= 1) { - node.color = color(node.name) - } else if (node.depth > 1) { - node.color = node.parent.color - } - - return node - }) - - const links = cluster.links(nodes) - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Links - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const link = wrapper - .selectAll('.nivo_tree_link') - .data(links, d => `${identity(d.source)}.${identity(d.target)}`) - - link - .enter() - .append('path') - .attr('fill', 'none') - .style('stroke', d => d.target.color) - .attr('class', 'nivo_tree_link') - .attr('d', diagonal) - .attr('stroke-dasharray', function() { - return this.getTotalLength() - }) - .attr('stroke-dashoffset', function() { - return this.getTotalLength() - }) - - link - .transition() - //.delay(d => d.source.depth * transitionDuration) - .duration(transitionDuration) - .ease(transitionEasing) - .attr('d', diagonal) - .attr('stroke-dasharray', function() { - return this.getTotalLength() - }) - .attr('stroke-dashoffset', 0) - - link - .exit() - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('stroke-dashoffset', function() { - return this.getTotalLength() - }) - .remove() - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Circles - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const circle = wrapper.selectAll('.nivo_tree_circle').data(nodes, identity) - - circle - .enter() - .append('circle') - .attr('class', 'nivo_tree_circle') - .style('fill', d => d.color) - .attr('transform', transformer) - .attr('r', 0) - - circle - .transition() - //.delay(d => d.depth * transitionDuration) - .duration(transitionDuration) - .ease(transitionEasing) - .attr('transform', transformer) - .attr('r', nodeRadius) - - circle.exit().remove() - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Labels - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const label = wrapper.selectAll('.nivo_tree_label').data(nodes, identity) - - const { - rootLabelPosition, - intermediateLabelPosition, - leafLabelPosition, - } = computeLabelPositions(nextProps) - - const { - rootLabelRotation, - intermediateLabelRotation, - leafLabelRotation, - } = computeLabelRotations(nextProps) - - label - .enter() - .append('g') - .attr('class', 'nivo_tree_label') - .style('opacity', 0) - .each(function(d) { - const el = d3.select(this) - - let position - let rotation - if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_ROOT) { - position = rootLabelPosition - rotation = rootLabelRotation - } else if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_LEAF) { - position = leafLabelPosition - rotation = leafLabelRotation - } else { - position = intermediateLabelPosition - rotation = intermediateLabelRotation - } - - el.attr('transform', `${transformer(d)} rotate(${rotation})`) - - el.call( - makeLabel({ - text: d.name, - position, - labelOffset: 0, - labelPaddingX, - labelPaddingY, - }) - ) - }) - - label - .transition() - //.delay(d => d.depth === 0 ? 0 : (Math.max(d.depth - 1, 0) + 1) * transitionDuration) - .duration(transitionDuration) - .ease(transitionEasing) - .style('opacity', 1) - .attr('transform', d => { - const translate = transformer(d) - - let rotation - if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_ROOT) { - rotation = rootLabelRotation - } else if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_LEAF) { - rotation = leafLabelRotation - } else { - rotation = intermediateLabelRotation - } - - return `${translate} rotate(${rotation})` - }) - .each(function(d) { - const el = d3.select(this) - - let position - if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_ROOT) { - position = rootLabelPosition - } else if (d.hierarchicalType === HIERARCHICAL_NODE_TYPE_LEAF) { - position = leafLabelPosition - } else { - position = intermediateLabelPosition - } - - el.call( - makeLabel({ - text: d.name, - position, - labelOffset, - labelPaddingX, - labelPaddingY, - }) - ) - }) - } - - shouldComponentUpdate(nextProps) { - this.renderD3(nextProps) - - return false - } - - componentDidMount() { - this.renderD3(this.props) - } - - render() { - return ( - - - - ) - } -} - -const { object, number, string, func, any, oneOf } = PropTypes - -Tree.propTypes = { - containerWidth: number.isRequired, - containerHeight: number.isRequired, - margin: marginPropType, - root: object.isRequired, - identity: func.isRequired, - labelFn: func.isRequired, - direction: oneOf(['horizontal', 'horizontal-reverse', 'vertical', 'vertical-reverse']) - .isRequired, - colors: any.isRequired, - nodeRadius: number.isRequired, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, - labelOffset: number.isRequired, - labelPaddingX: number.isRequired, - labelPaddingY: number.isRequired, - rootLabelPosition: string, - intermediateLabelPosition: string, - leafLabelPosition: string, - rootLabelRotation: number, - intermediateLabelRotation: number, - leafLabelRotation: number, -} - -Tree.defaultProps = { - margin: Nivo.defaults.margin, - labelFn: d => d.name, - direction: 'horizontal', - identity: d => `${d.parent ? d.parent.name : 'root'}.${d.name}.${d.depth}`, - colors: Nivo.defaults.colorRange, - labelOffset: 8, - labelPaddingX: 8, - labelPaddingY: 4, - nodeRadius: 6, - transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, -} - -export default Dimensions()(Tree) diff --git a/src/components/charts/bar/Bar.js b/src/components/charts/bar/Bar.js index 92cdbe76b..6eba008c8 100644 --- a/src/components/charts/bar/Bar.js +++ b/src/components/charts/bar/Bar.js @@ -11,8 +11,8 @@ import PropTypes from 'prop-types' import { merge } from 'lodash' import { TransitionMotion, spring } from 'react-motion' import Nivo, { defaultTheme } from '../../../Nivo' -import { margin as marginPropType, motion as motionPropTypes } from '../../../PropTypes' -import { getColorsGenerator } from '../../../ColorUtils' +import { marginPropType, motionPropTypes } from '../../../props' +import { getColorsGenerator } from '../../../lib/colorUtils' import { generateGroupedBars, generateStackedBars } from '../../../lib/charts/bar' import SvgWrapper from '../SvgWrapper' import Axes from '../../axes/Axes' diff --git a/src/components/charts/bar/BarD3.js b/src/components/charts/bar/BarD3.js index 4335ca5bb..cbf57e393 100644 --- a/src/components/charts/bar/BarD3.js +++ b/src/components/charts/bar/BarD3.js @@ -12,8 +12,8 @@ import { findDOMNode } from 'react-dom' import d3 from 'd3' import _ from 'lodash' import Nivo from '../../../Nivo' -import { getColorRange, getColorGenerator } from '../../../ColorUtils' -import { margin as marginPropType } from '../../../PropTypes' +import { getColorRange, getColorGenerator } from '../../../lib/colorUtils' +import { marginPropType } from '../../../props' import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' class BarD3 extends Component { diff --git a/src/components/charts/bubble/Bubble.js b/src/components/charts/bubble/Bubble.js index d18603736..d207d20ba 100644 --- a/src/components/charts/bubble/Bubble.js +++ b/src/components/charts/bubble/Bubble.js @@ -11,7 +11,7 @@ import _ from 'lodash' import { convertLabel } from '../../../lib/propertiesConverters' import { bubblePropTypes, bubbleDefaultProps } from './BubbleProps' import BubblePlaceholders from './BubblePlaceholders' -import { getColorGenerator } from '../../../ColorUtils' +import { getColorGenerator } from '../../../lib/colorUtils' const createNodes = ({ borderWidth, diff --git a/src/components/charts/bubble/BubblePlaceholders.js b/src/components/charts/bubble/BubblePlaceholders.js index bed94739d..518917895 100644 --- a/src/components/charts/bubble/BubblePlaceholders.js +++ b/src/components/charts/bubble/BubblePlaceholders.js @@ -11,7 +11,7 @@ import { TransitionMotion, spring } from 'react-motion' import { rgb } from 'd3-color' import _ from 'lodash' import Nivo from '../../../Nivo' -import { getColorsGenerator, extractRGB } from '../../../ColorUtils' +import { getColorsGenerator, extractRGB } from '../../../lib/colorUtils' import BubbleHelper from '../../../lib/charts/bubble/BubbleHelper' import { convertGetter } from '../../../lib/propertiesConverters' import { bubblePropTypes, bubbleDefaultProps } from './BubbleProps' diff --git a/src/components/charts/bubble/BubbleProps.js b/src/components/charts/bubble/BubbleProps.js index 17a01adcc..2426c5c4a 100644 --- a/src/components/charts/bubble/BubbleProps.js +++ b/src/components/charts/bubble/BubbleProps.js @@ -8,7 +8,7 @@ */ import PropTypes from 'prop-types' import Nivo from '../../../Nivo' -import { margin, motion } from '../../../PropTypes' +import { marginPropType, motionPropTypes } from '../../../props' /** * Bubble components propTypes. @@ -21,7 +21,7 @@ export const bubblePropTypes = { // dimensions width: PropTypes.number.isRequired, height: PropTypes.number.isRequired, - margin, + margin: marginPropType, leavesOnly: PropTypes.bool.isRequired, onBubbleClick: PropTypes.func.isRequired, @@ -50,7 +50,7 @@ export const bubblePropTypes = { labelSkipRadius: PropTypes.number.isRequired, // transitions - ...motion, + ...motionPropTypes, transitionDuration: PropTypes.number.isRequired, // d3 transitions transitionEasing: PropTypes.string.isRequired, // d3 transitions } diff --git a/src/components/charts/calendar/CalendarProps.js b/src/components/charts/calendar/CalendarProps.js index 686201623..062c9ca77 100644 --- a/src/components/charts/calendar/CalendarProps.js +++ b/src/components/charts/calendar/CalendarProps.js @@ -8,7 +8,7 @@ */ import PropTypes from 'prop-types' import Nivo from '../../../Nivo' -import { margin, scale } from '../../../PropTypes' +import { marginPropType, scalePropType } from '../../../props' import { DIRECTION_HORIZONTAL, DIRECTION_VERTICAL } from '../../../constants/directions' const { number, string, bool, func, shape, oneOf, oneOfType, instanceOf, arrayOf } = PropTypes @@ -21,7 +21,7 @@ const { number, string, bool, func, shape, oneOf, oneOfType, instanceOf, arrayOf export const calendarPropTypes = { width: number.isRequired, height: number.isRequired, - margin, + margin: marginPropType, from: oneOfType([string, instanceOf(Date)]).isRequired, to: oneOfType([string, instanceOf(Date)]).isRequired, data: arrayOf( @@ -32,7 +32,7 @@ export const calendarPropTypes = { ).isRequired, onDayClick: func.isRequired, direction: oneOf([DIRECTION_HORIZONTAL, DIRECTION_VERTICAL]), - colorScale: scale.isRequired, + colorScale: scalePropType.isRequired, emptyColor: string.isRequired, // years yearSpacing: number.isRequired, diff --git a/src/components/charts/chord/Chord.js b/src/components/charts/chord/Chord.js index ca4fee311..f48be199a 100644 --- a/src/components/charts/chord/Chord.js +++ b/src/components/charts/chord/Chord.js @@ -9,8 +9,8 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import Nivo from '../../../Nivo' -import { margin as marginPropType } from '../../../PropTypes' -import { getColorRange } from '../../../ColorUtils' +import { marginPropType } from '../../../props' +import { getColorRange } from '../../../lib/colorUtils' import { chord as d3Chord, ribbon as Ribbon } from 'd3-chord' import { arc as Arc } from 'd3-shape' import { rgb } from 'd3-color' diff --git a/src/components/charts/line/Line.js b/src/components/charts/line/Line.js index 00fb80d6a..179f77507 100644 --- a/src/components/charts/line/Line.js +++ b/src/components/charts/line/Line.js @@ -11,11 +11,10 @@ import PropTypes from 'prop-types' import { merge } from 'lodash' import { line } from 'd3-shape' import Nivo, { defaultTheme } from '../../../Nivo' -import { margin as marginPropType, motion as motionPropTypes } from '../../../PropTypes' -import { getColorsGenerator, getColorGenerator } from '../../../ColorUtils' +import { marginPropType, motionPropTypes, curvePropMapping, curvePropType } from '../../../props' +import { getColorsGenerator, getColorGenerator } from '../../../lib/colorUtils' import SvgWrapper from '../SvgWrapper' import { generateLines, generateStackedLines } from '../../../lib/charts/line' -import { curvePropMapping, curvePropType } from '../../../properties/curve' import Axes from '../../axes/Axes' import Grid from '../../axes/Grid' import LineMarkers from './LineMarkers' diff --git a/src/components/charts/line/LineMarkers.js b/src/components/charts/line/LineMarkers.js index 7b2306187..89db8a787 100644 --- a/src/components/charts/line/LineMarkers.js +++ b/src/components/charts/line/LineMarkers.js @@ -9,7 +9,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { TransitionMotion, spring } from 'react-motion' -import { motion as motionPropTypes } from '../../../PropTypes' +import { motionPropTypes } from '../../../props' export default class LineMarkers extends Component { static propTypes = { diff --git a/src/components/charts/pie/Pie.js b/src/components/charts/pie/Pie.js index cc6e82c3f..bc4a94a36 100644 --- a/src/components/charts/pie/Pie.js +++ b/src/components/charts/pie/Pie.js @@ -11,10 +11,10 @@ import PropTypes from 'prop-types' import { merge } from 'lodash' import { Motion, TransitionMotion, spring } from 'react-motion' import Nivo, { defaultTheme } from '../../../Nivo' -import { margin as marginPropType, motion as motionPropTypes } from '../../../PropTypes' -import { getColorsGenerator, getInheritedColorGenerator } from '../../../ColorUtils' +import { marginPropType, motionPropTypes } from '../../../props' +import { getColorsGenerator, getInheritedColorGenerator } from '../../../lib/colorUtils' import { getLabelGenerator } from '../../../lib/propertiesConverters' -import { degreesToRadians } from '../../../ArcUtils' +import { degreesToRadians } from '../../../lib/arcUtils' import SvgWrapper from '../SvgWrapper' import { pie as d3Pie, arc as d3Arc } from 'd3-shape' import PieRadialLabels from './PieRadialLabels' @@ -45,6 +45,7 @@ export default class Pie extends Component { // radial labels enableRadialLabels: PropTypes.bool.isRequired, radialLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + radialLabelsSkipAngle: PropTypes.number, radialLabelsTextXOffset: PropTypes.number, radialLabelsTextColor: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), radialLabelsLinkOffset: PropTypes.number, @@ -56,6 +57,7 @@ export default class Pie extends Component { // slices labels enableSlicesLabels: PropTypes.bool.isRequired, sliceLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + sliceLabelsSkipAngle: PropTypes.number, slicesLabelsTextColor: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), // theming @@ -121,6 +123,7 @@ export default class Pie extends Component { // radial labels enableRadialLabels, radialLabel, + radialLabelsSkipAngle, radialLabelsLinkOffset, radialLabelsLinkDiagonalLength, radialLabelsLinkHorizontalLength, @@ -132,6 +135,7 @@ export default class Pie extends Component { // slices labels enableSlicesLabels, sliceLabel, + sliceLabelsSkipAngle, slicesLabelsTextColor, // theming @@ -165,6 +169,7 @@ export default class Pie extends Component { const radialLabelsProps = { label: getLabelGenerator(radialLabel), + skipAngle: radialLabelsSkipAngle, linkOffset: radialLabelsLinkOffset, linkDiagonalLength: radialLabelsLinkDiagonalLength, linkHorizontalLength: radialLabelsLinkHorizontalLength, @@ -176,6 +181,7 @@ export default class Pie extends Component { const slicesLabelsProps = { label: getLabelGenerator(sliceLabel), + skipAngle: sliceLabelsSkipAngle, textColor: getInheritedColorGenerator(slicesLabelsTextColor, 'axis.textColor'), } diff --git a/src/components/charts/pie/PieColumnLegends.js b/src/components/charts/pie/PieColumnLegends.js index 650149bea..963bb2275 100644 --- a/src/components/charts/pie/PieColumnLegends.js +++ b/src/components/charts/pie/PieColumnLegends.js @@ -12,8 +12,8 @@ import invariant from 'invariant' import d3 from 'd3' import _ from 'lodash' import Nivo from '../../../Nivo' -import { midAngle, findNeighbor } from '../../../ArcUtils' -import { getColorStyleObject } from '../../../ColorUtils' +import { midAngle, findNeighbor } from '../../../lib/arcUtils' +import { getColorStyleObject } from '../../../lib/colorUtils' class PieColumnLegends extends Component { static decoratePie(element) { diff --git a/src/components/charts/pie/PieRadialLabels.js b/src/components/charts/pie/PieRadialLabels.js index 2b8bf3a41..26354c0dd 100644 --- a/src/components/charts/pie/PieRadialLabels.js +++ b/src/components/charts/pie/PieRadialLabels.js @@ -9,7 +9,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { Motion, TransitionMotion, spring } from 'react-motion' -import { midAngle, positionFromAngle } from '../../../ArcUtils' +import { midAngle, positionFromAngle } from '../../../lib/arcUtils' import { line } from 'd3-shape' const lineGenerator = line().x(d => d.x).y(d => d.y) @@ -17,6 +17,7 @@ const lineGenerator = line().x(d => d.x).y(d => d.y) export default class PieRadialLabels extends Component { static propTypes = { label: PropTypes.func.isRequired, + skipAngle: PropTypes.number.isRequired, radius: PropTypes.number.isRequired, linkOffset: PropTypes.number.isRequired, linkDiagonalLength: PropTypes.number.isRequired, @@ -34,6 +35,7 @@ export default class PieRadialLabels extends Component { } static defaultProps = { + skipAngle: 0, linkOffset: 0, linkDiagonalLength: 16, linkHorizontalLength: 24, diff --git a/src/components/charts/pie/PieRadialLegends.js b/src/components/charts/pie/PieRadialLegends.js index ef869bcaa..2b48ed031 100644 --- a/src/components/charts/pie/PieRadialLegends.js +++ b/src/components/charts/pie/PieRadialLegends.js @@ -11,8 +11,8 @@ import PropTypes from 'prop-types' import invariant from 'invariant' import d3 from 'd3' import Nivo from '../../../Nivo' -import { midAngle, radiansToDegrees } from '../../../ArcUtils' -import { getColorGenerator } from '../../../ColorUtils' +import { midAngle, radiansToDegrees } from '../../../lib/arcUtils' +import { getColorGenerator } from '../../../lib/colorUtils' class PieRadialLegends extends Component { static decoratePie(element) { diff --git a/src/components/charts/pie/PieSliceLegends.js b/src/components/charts/pie/PieSliceLegends.js index b72aa8074..fee1ebaae 100644 --- a/src/components/charts/pie/PieSliceLegends.js +++ b/src/components/charts/pie/PieSliceLegends.js @@ -12,8 +12,8 @@ import invariant from 'invariant' import _ from 'lodash' import d3 from 'd3' import Nivo from '../../../Nivo' -import { findNeighbor, midAngle, radiansToDegrees } from '../../../ArcUtils' -import { getColorStyleObject } from '../../../ColorUtils' +import { findNeighbor, midAngle, radiansToDegrees } from '../../../lib/arcUtils' +import { getColorStyleObject } from '../../../lib/colorUtils' class PieSliceLegends extends Component { static decoratePie(element) { diff --git a/src/components/charts/pie/PieSlicesLabels.js b/src/components/charts/pie/PieSlicesLabels.js index 8c6f1cdf8..4d4ab0699 100644 --- a/src/components/charts/pie/PieSlicesLabels.js +++ b/src/components/charts/pie/PieSlicesLabels.js @@ -10,11 +10,12 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { merge } from 'lodash' import { Motion, TransitionMotion, spring } from 'react-motion' -import { midAngle, positionFromAngle } from '../../../ArcUtils' +import { midAngle, positionFromAngle } from '../../../lib/arcUtils' export default class PieSlicesLabels extends Component { static propTypes = { label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + skipAngle: PropTypes.number.isRequired, radius: PropTypes.number.isRequired, innerRadius: PropTypes.number.isRequired, textColor: PropTypes.func.isRequired, @@ -26,7 +27,9 @@ export default class PieSlicesLabels extends Component { }).isRequired, } - static defaultProps = {} + static defaultProps = { + skipAngle: 0, + } render() { const { data, label, radius, innerRadius, textColor, theme } = this.props diff --git a/src/components/charts/pie/ResponsivePieD3.js b/src/components/charts/pie/ResponsivePieD3.js index bccdbff58..6b384e148 100644 --- a/src/components/charts/pie/ResponsivePieD3.js +++ b/src/components/charts/pie/ResponsivePieD3.js @@ -12,8 +12,8 @@ import { findDOMNode } from 'react-dom' import _ from 'lodash' import d3 from 'd3' import Nivo from '../../../Nivo' -import { degreesToRadians, findNeighbor } from '../../../ArcUtils' -import { getColorRange } from '../../../ColorUtils' +import { degreesToRadians, findNeighbor } from '../../../lib/arcUtils' +import { getColorRange } from '../../../lib/colorUtils' class Pie extends Component { renderD3(nextProps) { diff --git a/src/components/charts/radial-stack/RadialStack.js b/src/components/charts/radial-stack/RadialStack.js deleted file mode 100644 index c212f824c..000000000 --- a/src/components/charts/radial-stack/RadialStack.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import { findDOMNode } from 'react-dom' -import _ from 'lodash' -import Nivo from '../../../Nivo' -import RadialStackD3Svg from '../../../lib/charts/radial-stack/RadialStackD3Svg' -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' -import { margin as marginPropType } from '../../../PropTypes' - -const RADIAL_STACK_DECORATOR = 'decorateRadialStack' - -class RadialStack extends Component { - shouldComponentUpdate(nextProps) { - this.radialStack.decorate( - decoratorsFromReactChildren(nextProps.children, RADIAL_STACK_DECORATOR) - ) - this.radialStack.draw( - _.assign({}, nextProps, { - margin: _.assign({}, Nivo.defaults.margin, nextProps.margin), - }) - ) - - return false - } - - componentDidMount() { - this.radialStack = RadialStackD3Svg(findDOMNode(this)) - this.radialStack.decorate( - decoratorsFromReactChildren(this.props.children, RADIAL_STACK_DECORATOR) - ) - this.radialStack.draw( - _.assign({}, this.props, { - margin: _.assign({}, Nivo.defaults.margin, this.props.margin), - }) - ) - } - - render() { - return - } -} - -const { array, number, string, func, any, oneOf } = PropTypes - -RadialStack.propTypes = { - width: number.isRequired, - height: number.isRequired, - margin: marginPropType, - innerRadius: number.isRequired, - sort: func, - layers: array.isRequired, - offset: oneOf(['silhouette', 'wiggle', 'expand', 'zero']).isRequired, - keyProp: string.isRequired, - valueProp: string.isRequired, - colors: any.isRequired, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, -} - -RadialStack.defaultProps = { - margin: Nivo.defaults.margin, - innerRadius: 0.6, - sort: null, - offset: 'zero', - keyProp: 'label', - valueProp: 'value', - transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - colors: Nivo.defaults.colorRange, -} - -export default RadialStack diff --git a/src/components/charts/radial-stack/RadialStackAngleAxis.js b/src/components/charts/radial-stack/RadialStackAngleAxis.js deleted file mode 100644 index c854af71f..000000000 --- a/src/components/charts/radial-stack/RadialStackAngleAxis.js +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import d3 from 'd3' -import invariant from 'invariant' -import { radiansToDegrees } from '../../../ArcUtils' -import makeLabel, { LABEL_POSITION_TOP } from '../../../lib/charts/labels' - -class RadialStackAngleAxis extends Component { - static decorateRadialStack({ - props: { labelPosition, labelRotation, labelOffset, labelPaddingX, labelPaddingY }, - }) { - const radialLine = d3.svg.line.radial().interpolate('cardinal-closed') - /* - .radius(radius) - .angle(function(d, i) { return angle(i); }); - */ - return ({ - element, - layers, - stacked, - angle, - radius, - innerRadius, - outerRadius, - transitionDuration, - transitionEasing, - }) => { - let wrapper = element.select('.nivo_radial-axis') - if (wrapper.node() === null) { - //wrapper = element.append('g') - wrapper = element.insert('g', ':first-child').attr('class', 'nivo_radial-axis') - } - - /* - radialLine.angle(d => angle(d.x)); - - const radialTicks = wrapper.selectAll('.nivo_radial-axis_circle').data([ - { radius: innerRadius, serie: stacked[0] }, - { radius: innerRadius + (outerRadius - innerRadius) / 2, serie: stacked[0] }, - { radius: outerRadius, serie: stacked[0] } - ]); - - radialTicks.enter().append('path') - .attr('class', 'nivo_radial-axis_circle') - .attr('fill', 'none') - .attr('stroke', '#000') - .attr('d', d => radialLine.radius(d.radius)(d.serie)) - ; - */ - - const lines = wrapper.selectAll('.nivo_radial-axis_tick').data(stacked[0], d => d.x) - - const newLine = lines - .enter() - .append('g') - .attr('class', 'nivo_radial-axis_tick') - .attr('transform', 'rotate(-90)') - - newLine - .append('line') - .attr('class', 'nivo_radial-axis_tick_grid-line') - .attr('x1', innerRadius) - .attr('x2', outerRadius) - - newLine.append('g').attr('transform', `translate(${outerRadius},0)`).each(function(d) { - const el = d3.select(this) - - el.append('g').attr('transform', d => `rotate(${labelRotation})`).call( - makeLabel({ - text: d.x, - position: labelPosition, - labelOffset, - labelPaddingX, - labelPaddingY, - }) - ) - }) - - lines - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('transform', d => `rotate(${radiansToDegrees(angle(d.x)) - 90})`) - .each(function(d) { - const el = d3.select(this) - - d3.transition(el.select('line')).attr('x1', innerRadius).attr('x2', outerRadius) - - el - .select('g') - .select('g') - .attr('transform', d => `rotate(${labelRotation})`) - .call( - makeLabel({ - text: d.x, - position: labelPosition, - labelOffset, - labelPaddingX, - labelPaddingY, - }) - ) - }) - } - } - - render() { - invariant( - false, - ' element is for RadialStack components configuration only and should not be rendered' - ) - } -} - -const { number, string } = PropTypes - -RadialStackAngleAxis.propTypes = { - labelPosition: string.isRequired, - labelRotation: number.isRequired, - labelOffset: number.isRequired, - labelPaddingX: number.isRequired, - labelPaddingY: number.isRequired, -} - -RadialStackAngleAxis.defaultProps = { - labelPosition: LABEL_POSITION_TOP, - labelRotation: 90, - labelOffset: 10, - labelPaddingX: 6, - labelPaddingY: 2, -} - -export default RadialStackAngleAxis diff --git a/src/components/charts/radial-stack/RadialStackRadiusAxis.js b/src/components/charts/radial-stack/RadialStackRadiusAxis.js deleted file mode 100644 index c735ded57..000000000 --- a/src/components/charts/radial-stack/RadialStackRadiusAxis.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import d3 from 'd3' -import invariant from 'invariant' -import { radiansToDegrees } from '../../../ArcUtils' - -class RadialStackRadiusAxis extends Component { - static decorateRadialStack({ props: { angleData } }) { - const axis = d3.svg.axis() - - return ({ element, angle, radius, transitionDuration, transitionEasing }) => { - let wrapper = d3.select(`.nivo_radial-stack_radius-axis-${angleData}`) - if (wrapper.node() === null) { - wrapper = element - .append('g') - .attr( - 'class', - `nivo_radial-stack_radius-axis nivo_radial-stack_radius-axis-${angleData}` - ) - } - - // copy original scale - const scale = radius.copy() - axis.scale(scale).ticks(3) - - wrapper.attr('transform', d => `rotate(${radiansToDegrees(angle(angleData))})`) - - wrapper.transition().duration(transitionDuration).ease(transitionEasing).call(axis) - } - } - - render() { - invariant( - false, - ' element is for Radial components configuration only and should not be rendered' - ) - } -} - -const { any } = PropTypes - -RadialStackRadiusAxis.propTypes = { - angleData: any.isRequired, -} - -RadialStackRadiusAxis.defaultProps = {} - -export default RadialStackRadiusAxis diff --git a/src/components/charts/radial-stack/ResponsiveRadialStack.js b/src/components/charts/radial-stack/ResponsiveRadialStack.js deleted file mode 100644 index 6f8e1c7b3..000000000 --- a/src/components/charts/radial-stack/ResponsiveRadialStack.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import RadialStack from './RadialStack' -import Dimensions from 'react-dimensions' - -class ResponsiveRadialStack extends Component { - render() { - const { containerWidth, containerHeight } = this.props - - return - } -} - -ResponsiveRadialStack.displayName = 'ResponsiveRadialStack' - -export default Dimensions()(ResponsiveRadialStack) diff --git a/src/components/charts/radial-stack/index.js b/src/components/charts/radial-stack/index.js deleted file mode 100644 index ffd55b284..000000000 --- a/src/components/charts/radial-stack/index.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * 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. - */ - -export { default as RadialStack } from './RadialStack' -export { default as ResponsiveRadialStack } from './ResponsiveRadialStack' -export { default as RadialStackRadiusAxis } from './RadialStackRadiusAxis' -export { default as RadialStackAngleAxis } from './RadialStackAngleAxis' diff --git a/src/components/charts/stack/ResponsiveStack.js b/src/components/charts/stack/ResponsiveStack.js deleted file mode 100644 index ec59b2769..000000000 --- a/src/components/charts/stack/ResponsiveStack.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import Stack from './Stack' -import Dimensions from 'react-dimensions' - -class ResponsiveStack extends Component { - render() { - const { containerWidth, containerHeight } = this.props - - return - } -} - -export default Dimensions()(ResponsiveStack) diff --git a/src/components/charts/stack/Stack.js b/src/components/charts/stack/Stack.js deleted file mode 100644 index 02450444e..000000000 --- a/src/components/charts/stack/Stack.js +++ /dev/null @@ -1,337 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import { findDOMNode } from 'react-dom' -import d3 from 'd3' -import _ from 'lodash' -import Nivo from '../../../Nivo' -import { lineInterpolation } from '../../../PropTypes' -import { getColorRange, getColorGenerator } from '../../../ColorUtils' -import { margin as marginPropType } from '../../../PropTypes' -import decoratorsFromReactChildren from '../../../lib/decoratorsFromReactChildren' - -const findPrecedingLayer = (layers, index) => { - if (layers === null) { - return null - } - - for (let i = layers.length - 1; i >= 0; i--) { - const layer = layers[i] - if (layer.index < index) { - return layer - } - } - - return null -} - -class Stack extends Component { - constructor(props) { - super(props) - - this.state = { - excludeLayers: [], - } - - this.previousData = null - } - - renderD3(props, state) { - const { - data, - offset, - interpolation, - colors, - overColor, - transitionDuration, - transitionEasing, - } = props - - const { excludeLayers } = state - - const overColorFn = getColorGenerator(overColor) - - const element = d3.select(findDOMNode(this)) - const wrapper = element.select('.nivo_stack_wrapper') - - const margin = _.assign({}, Nivo.defaults.margin, props.margin) - const width = props.width - margin.left - margin.right - const height = props.height - margin.top - margin.bottom - - element.attr({ - width: props.width, - height: props.height, - }) - wrapper.attr('transform', `translate(${margin.left},${margin.top})`) - - const color = getColorRange(colors) - - const normData = _.cloneDeep(data).map((values, i) => ({ - index: i, - color: color(i), - values, - })) - - let filteredData = [] - let hiddenData = [] - if (excludeLayers.length > 0) { - normData.forEach(layer => { - if (excludeLayers.indexOf(layer.index) === -1) { - filteredData.push(layer) - } else { - hiddenData.push(layer) - } - }) - } else { - filteredData = normData - } - - const stack = d3.layout.stack().offset(offset).values(d => d.values) - - const stacked = stack(filteredData) - - const xScale = d3.scale.linear().range([0, width]).domain([0, stacked[0].values.length - 1]) - - const yScale = d3.scale - .linear() - .range([height, 0]) - .domain([0, d3.max(stacked, layer => d3.max(layer.values, d => d.y0 + d.y))]) - - filteredData = filteredData.map(layer => { - return _.assign(layer, { - values: layer.values.map(v => ({ - value: v, - interpolated: { - x: xScale(v.x), - y0: yScale(v.y0), - y: yScale(v.y0 + v.y), - }, - })), - }) - }) - - const area = d3.svg.area().interpolate(interpolation).x(d => d.x).y0(d => d.y0).y1(d => d.y) - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Areas - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - let paths = wrapper - .select('.nivo_stack_areas') - .selectAll('.nivo_stack_area') - .data(stacked, d => d.index) - - // ENTER - paths - .enter() - .append('path') - .attr('class', 'nivo_stack_area') - .attr('d', d => { - if (this.previousData === null) { - return area( - d.values.map(p => ({ - x: p.interpolated.x, - y0: yScale.range()[0], - y: yScale.range()[0], - })) - ) - } - - const precedingLayer = findPrecedingLayer(this.previousData, d.index) - - if (precedingLayer !== null) { - return area( - precedingLayer.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y, - y: p.interpolated.y, - })) - ) - } - - return area( - d.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y0, - y: p.interpolated.y0, - })) - ) - }) - .style('fill', d => d.color) - - // UPDATE - paths - .on('click', d => { - // we cannot have no layer - if (filteredData.length > 1) { - this.setState({ - excludeLayers: excludeLayers.concat([d.index]), - }) - } - }) - .on('mouseover', function(d) { - d3.select(this).style('fill', overColorFn) - }) - .on('mousemove', function(d, i) { - d3.select(this).style('fill', overColorFn) - }) - .on('mouseout', function(d) { - d3.select(this).style('fill', d.color) - }) - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('d', d => area(d.values.map(v => v.interpolated))) - .style('fill', d => d.color) - - // EXIT - paths - .exit() - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('d', d => { - const precedingLayer = findPrecedingLayer(filteredData, d.index) - - if (precedingLayer !== null) { - return area( - precedingLayer.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y, - y: p.interpolated.y, - })) - ) - } - - return area( - d.values.map(p => ({ - x: p.interpolated.x, - y0: p.interpolated.y0, - y: p.interpolated.y0, - })) - ) - }) - .remove() - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Hidden layers - // ————————————————————————————————————————————————————————————————————————————————————————————————————————————— - const hiddenControls = wrapper - .selectAll('.nivo_stack_hidden_control') - .data(hiddenData, d => d.index) - - // ENTER - hiddenControls - .enter() - .append('circle') - .attr('class', 'nivo_stack_hidden_control') - .attr('r', 8) - .attr('transform', (d, i) => `translate(${i * 40},0)`) - .style('fill', d => d.color) - .style('opacity', 0) - .style('cursor', 'pointer') - - hiddenControls - .on('click', d => { - this.setState({ - excludeLayers: excludeLayers.filter(index => index !== d.index), - }) - }) - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('transform', (d, i) => `translate(${i * 40},0)`) - .style('fill', d => d.color) - .style('opacity', 1) - - hiddenControls - .exit() - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .style('opacity', 0) - .remove() - - const stackContext = { - element, - wrapper, - width, - height, - stacked, - xScale, - yScale, - transitionDuration, - transitionEasing, - } - - this.decorators.forEach(decorator => { - decorator(stackContext) - }) - - this.previousData = filteredData - } - - shouldComponentUpdate(nextProps, nextState) { - this.decorators = decoratorsFromReactChildren(nextProps.children, 'decorateStack') - - this.renderD3(nextProps, nextState) - - return false - } - - componentDidMount() { - this.decorators = decoratorsFromReactChildren(this.props.children, 'decorateStack') - - this.renderD3(this.props, this.state) - } - - render() { - return ( - - - - - - ) - } -} - -const { array, number, string, func, any, oneOf } = PropTypes - -Stack.propTypes = { - width: number.isRequired, - height: number.isRequired, - margin: marginPropType, - sort: func, - data: array.isRequired, - offset: oneOf(['silhouette', 'wiggle', 'expand', 'zero']).isRequired, - keyProp: string.isRequired, - valueProp: string.isRequired, - interpolation: lineInterpolation, - colors: any.isRequired, - overColor: any.isRequired, - transitionDuration: number.isRequired, - transitionEasing: string.isRequired, -} - -Stack.defaultProps = { - margin: Nivo.defaults.margin, - sort: null, - offset: 'zero', - keyProp: 'label', - valueProp: 'value', - interpolation: 'monotone', - transitionDuration: Nivo.defaults.transitionDuration, - transitionEasing: Nivo.defaults.transitionEasing, - colors: Nivo.defaults.colorRange, - overColor: 'inherit:brighter(.5)', -} - -export default Stack diff --git a/src/components/charts/stack/StackSlicer.js b/src/components/charts/stack/StackSlicer.js deleted file mode 100644 index e03d19f9f..000000000 --- a/src/components/charts/stack/StackSlicer.js +++ /dev/null @@ -1,218 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import invariant from 'invariant' -import _ from 'lodash' -import d3 from 'd3' -import { getColorGenerator } from '../../../ColorUtils' - -const overTransitionDuration = 200 -const overTransitionEasing = 'linear' - -class StackSlicer extends Component { - static decorateStack(element) { - const { props } = element - - const colorFn = getColorGenerator(props.color) - const dotBorderColorFn = getColorGenerator(props.dotBorderColor) - const lineColorFn = getColorGenerator(props.lineColor) - const { showOnOver } = props - - // Receive context from Parent Stack component - return ({ wrapper, stacked, width, height, transitionDuration, transitionEasing }) => { - const slices = [] - stacked.forEach(layer => { - layer.values.forEach((datum, i) => { - if (!slices[i]) { - slices[i] = { - x: datum.interpolated.x, - values: [], - } - } - - slices[i].values.push( - _.assign({}, datum, { - index: layer.index, - color: layer.color, - }) - ) - }) - }) - - const elements = wrapper.selectAll('.nivo_stack_slices').data(slices) - - const newSlices = elements - .enter() - .append('g') - .attr('class', 'nivo_stack_slices') - .attr('transform', d => `translate(${d.x},0)`) - .style('opacity', showOnOver ? 0 : 1) - .style('pointer-events', 'all') - - newSlices - .append('rect') - .attr('width', props.radius * 2 + 10) - .attr('height', height) - .attr('transform', `translate(-${props.radius + 5},0)`) - .style('fill', 'none') - .style('pointer-events', 'all') - - elements - .style('opacity', showOnOver ? 0 : 1) - .on('mouseover', function() { - if (!showOnOver) { - return - } - - d3 - .select(this) - .transition() - .duration(overTransitionDuration) - .ease(overTransitionEasing) - .style('opacity', 1) - }) - .on('mouseout', function() { - if (!showOnOver) { - return - } - - d3 - .select(this) - .transition() - .duration(overTransitionDuration) - .ease(overTransitionEasing) - .style('opacity', 0) - }) - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('transform', d => `translate(${d.x},0)`) - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Lines - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - const lines = elements.selectAll('line').data(d => d.values, d => d.index) - - // ENTER - lines - .enter() - .append('line') - .attr('y1', d => d.interpolated.y) - .attr('y2', d => d.interpolated.y0) - .style('stroke-width', props.lineWidth) - .style('stroke', lineColorFn) - - // UPDATE - lines - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('y1', d => d.interpolated.y) - .attr('y2', d => d.interpolated.y0) - .style('stroke-width', props.lineWidth) - .style('stroke', lineColorFn) - - // EXIT - lines - .exit() - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('y1', d => d.interpolated.y0) - .attr('y2', d => d.interpolated.y0) - .style('opacity', 0) - .remove() - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - // Circles - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - const circles = elements.selectAll('circle').data(d => d.values, d => d.index) - - // ENTER - circles - .enter() - .append('circle') - .attr('r', 0.1) - .style('cursor', 'pointer') - .attr('transform', d => `translate(0,${d.interpolated.y})`) - .style('fill', colorFn) - .style('stroke-width', props.dotBorderWidth) - .style('stroke', dotBorderColorFn) - - // UPDATE - circles - .on('mouseover', function() { - d3 - .select(this) - .transition() - .duration(overTransitionDuration) - .ease(overTransitionEasing) - .attr('r', props.radius * 2) - }) - .on('mouseout', function() { - d3 - .select(this) - .transition() - .duration(overTransitionDuration) - .ease(overTransitionEasing) - .attr('r', props.radius) - }) - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('r', props.radius) - .attr('transform', d => `translate(0,${d.interpolated.y})`) - .style('fill', colorFn) - .style('stroke-width', props.dotBorderWidth) - .style('stroke', dotBorderColorFn) - - // EXIT - circles - .exit() - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('r', 0.1) - .style('opacity', 0) - .remove() - } - } - - render() { - invariant( - false, - ' element is for Stack configuration only and should not be rendered' - ) - } -} - -const { number, bool, any } = PropTypes - -StackSlicer.propTypes = { - showOnOver: bool.isRequired, - radius: number.isRequired, - color: any.isRequired, - dotBorderWidth: number.isRequired, - dotBorderColor: any.isRequired, - lineWidth: number.isRequired, -} - -StackSlicer.defaultProps = { - showOnOver: false, - radius: 4, - color: 'inherit', - dotBorderWidth: 1, - dotBorderColor: 'inherit:darker(.5)', - lineWidth: 1, - lineColor: 'inherit:darker(.3)', -} - -export default StackSlicer diff --git a/src/components/charts/stack/index.js b/src/components/charts/stack/index.js deleted file mode 100644 index d002069d1..000000000 --- a/src/components/charts/stack/index.js +++ /dev/null @@ -1,12 +0,0 @@ -/* - * 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. - */ - -export { default as Stack } from './Stack' -export { default as ResponsiveStack } from './ResponsiveStack' -export { default as StackSlicer } from './StackSlicer' diff --git a/src/components/charts/treemap/TreeMap.js b/src/components/charts/treemap/TreeMap.js index a2774af5a..caa9415c9 100644 --- a/src/components/charts/treemap/TreeMap.js +++ b/src/components/charts/treemap/TreeMap.js @@ -13,7 +13,7 @@ import _ from 'lodash' import { convertLabel } from '../../../lib/propertiesConverters' import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' import TreeMapPlaceholders from './TreeMapPlaceholders' -import { getColorGenerator } from '../../../ColorUtils' +import { getColorGenerator } from '../../../lib/colorUtils' const createNodes = ({ borderWidth, diff --git a/src/components/charts/treemap/TreeMapD3.js b/src/components/charts/treemap/TreeMapD3.js index f884817b7..aa494ad99 100644 --- a/src/components/charts/treemap/TreeMapD3.js +++ b/src/components/charts/treemap/TreeMapD3.js @@ -12,7 +12,7 @@ import { findDOMNode } from 'react-dom' import _ from 'lodash' import d3 from 'd3' import Nivo from '../../../Nivo' -import { getColorStyleObject, getColorRange } from '../../../ColorUtils' +import { getColorStyleObject, getColorRange } from '../../../lib/colorUtils' import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' import Treemap from '../../../lib/charts/treemap/TreeMapD3' diff --git a/src/components/charts/treemap/TreeMapHTML.js b/src/components/charts/treemap/TreeMapHTML.js index de251bfd7..3e188ce42 100644 --- a/src/components/charts/treemap/TreeMapHTML.js +++ b/src/components/charts/treemap/TreeMapHTML.js @@ -13,7 +13,7 @@ import _ from 'lodash' import { convertLabel } from '../../../lib/propertiesConverters' import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' import TreeMapPlaceholders from './TreeMapPlaceholders' -import { getColorGenerator } from '../../../ColorUtils' +import { getColorGenerator } from '../../../lib/colorUtils' const createNodes = ({ borderWidth, diff --git a/src/components/charts/treemap/TreeMapPlaceholders.js b/src/components/charts/treemap/TreeMapPlaceholders.js index d7b64dc73..e7987159c 100644 --- a/src/components/charts/treemap/TreeMapPlaceholders.js +++ b/src/components/charts/treemap/TreeMapPlaceholders.js @@ -14,7 +14,7 @@ import Nivo from '../../../Nivo' import TreeMapHelper from '../../../lib/charts/treemap/TreeMapHelper' import { convertGetter } from '../../../lib/propertiesConverters' import { treeMapPropTypes, treeMapDefaultProps } from './TreeMapProps' -import { getColorsGenerator, extractRGB } from '../../../ColorUtils' +import { getColorsGenerator, extractRGB } from '../../../lib/colorUtils' class TreeMapPlaceholders extends Component { componentWillMount() { diff --git a/src/components/charts/treemap/TreeMapProps.js b/src/components/charts/treemap/TreeMapProps.js index 4939cf1d1..b6107a0d6 100644 --- a/src/components/charts/treemap/TreeMapProps.js +++ b/src/components/charts/treemap/TreeMapProps.js @@ -9,7 +9,7 @@ import PropTypes from 'prop-types' import Nivo from '../../../Nivo' -import { margin, motion } from '../../../PropTypes' +import { marginPropType, motionPropTypes } from '../../../props' import { tilingMethods } from '../../../lib/charts/treemap/TreeMapD3' /** @@ -23,7 +23,7 @@ export const treeMapPropTypes = { // dimensions width: PropTypes.number.isRequired, // for non responsive components height: PropTypes.number.isRequired, // for non responsive components - margin, + margin: marginPropType, leavesOnly: PropTypes.bool.isRequired, value: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired, @@ -48,7 +48,7 @@ export const treeMapPropTypes = { borderColor: PropTypes.any.isRequired, // transitions - ...motion, + ...motionPropTypes, transitionDuration: PropTypes.number.isRequired, // d3 transitions transitionEasing: PropTypes.string.isRequired, // d3 transitions diff --git a/src/components/scales/Scale.js b/src/components/scales/Scale.js deleted file mode 100644 index 457e9cac4..000000000 --- a/src/components/scales/Scale.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import { scaleLinear, scaleBand, scalePoint } from 'd3-scale' - -export default class Scale extends Component { - static propTypes = { - id: PropTypes.string.isRequired, - type: PropTypes.oneOf(['linear', 'point', 'band']).isRequired, - padding: PropTypes.number, - dataKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]), - aggregate: PropTypes.array, - maxOf: PropTypes.array, - } - - static create({ type, axis, dataKey: key, aggregate, maxOf, padding }, data, width, height) { - let mapper - if (Array.isArray(aggregate)) { - mapper = d => _.sum(aggregate.map(k => d[k])) - } else if (Array.isArray(maxOf)) { - mapper = d => _.max(maxOf.map(k => d[k])) - } else if (_.isFunction(key)) { - mapper = key - } else { - mapper = d => d[key] - } - - const range = [axis === 'y' ? height : 0, axis === 'x' ? width : 0] - - let scale - switch (type) { - case 'linear': - scale = scaleLinear().rangeRound(range).domain([0, _.max(data.map(mapper))]) - break - - case 'band': - scale = scaleBand().rangeRound(range).domain(data.map(mapper)) - - if (padding !== undefined) { - scale.padding(padding) - } - break - - case 'point': - scale = scalePoint().range(range).domain(data.map(mapper)) - break - } - - return scale - } - - render() { - return null - } -} diff --git a/src/components/scales/XYScales.js b/src/components/scales/XYScales.js deleted file mode 100644 index ba84190fd..000000000 --- a/src/components/scales/XYScales.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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, { Component } from 'react' -import PropTypes from 'prop-types' -import d3 from 'd3' - -class XYScales extends Component { - render() { - const { data, identityAccessor, valueAccessor, width, height, children } = this.props - - if (React.Children.count(children) === 0) { - return null - } - - const xScale = d3.scale.linear().range([0, width]).domain([0, data.length - 1]) - - const yScale = d3.scale - .linear() - .range([height, 0]) - .domain([0, d3.max(data.map(valueAccessor))]) - - return ( - - {React.Children.map(children, child => - React.cloneElement(child, { - data: data.slice(), - xScale, - yScale, - width, - height, - }) - )} - - ) - } -} - -XYScales.displayName = 'XYScales' - -const { array, func, number } = PropTypes - -XYScales.propTypes = { - data: array.isRequired, - identityAccessor: func.isRequired, - valueAccessor: func.isRequired, - width: number, - height: number, -} - -XYScales.defaultProps = { - identityAccessor: (d, i) => i, - valueAccessor: d => d, -} - -export default XYScales diff --git a/src/components/scales/index.js b/src/components/scales/index.js deleted file mode 100644 index d5058ebbf..000000000 --- a/src/components/scales/index.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 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. - */ - -export { default as Scale } from './Scale' diff --git a/src/index.js b/src/index.js index 2ca6001c3..283644648 100644 --- a/src/index.js +++ b/src/index.js @@ -19,7 +19,4 @@ export * from './components/charts/chord/' export * from './components/charts/calendar/' export * from './components/charts/voronoi/' export * from './components/axes/' -export * from './components/scales/' -export * from './properties/curve' -export { default as Chart } from './components/charts/Chart' -export { default as ResponsiveChart } from './components/charts/ResponsiveChart' +export * from './props/' diff --git a/src/ArcUtils.js b/src/lib/arcUtils.js similarity index 100% rename from src/ArcUtils.js rename to src/lib/arcUtils.js diff --git a/src/lib/charts/bubble/BubbleD3.js b/src/lib/charts/bubble/BubbleD3.js index f1a7c04e5..e057a3b8e 100644 --- a/src/lib/charts/bubble/BubbleD3.js +++ b/src/lib/charts/bubble/BubbleD3.js @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ -import { flatten } from '../../../DataUtils' +import { flatten } from '../../../lib/dataUtils' import { hierarchy, pack } from 'd3' /** diff --git a/src/lib/charts/bubble/BubbleD3Svg.js b/src/lib/charts/bubble/BubbleD3Svg.js index 61a396173..d8236d360 100644 --- a/src/lib/charts/bubble/BubbleD3Svg.js +++ b/src/lib/charts/bubble/BubbleD3Svg.js @@ -9,7 +9,7 @@ import d3 from 'd3' import BubbleD3 from './BubbleD3' -import { getColorRange, getColorGenerator, getColorStyleObject } from '../../../ColorUtils' +import { getColorRange, getColorGenerator, getColorStyleObject } from '../../../lib/colorUtils' import { convertLabel } from '../../propertiesConverters' const BubbleD3Svg = domRoot => { diff --git a/src/lib/charts/pie/PieD3Svg.js b/src/lib/charts/pie/PieD3Svg.js index 3dbafe1a2..a98e5fece 100644 --- a/src/lib/charts/pie/PieD3Svg.js +++ b/src/lib/charts/pie/PieD3Svg.js @@ -8,8 +8,8 @@ */ import d3 from 'd3' -import { degreesToRadians, midAngle, findNeighbor } from '../../../ArcUtils' -import { getColorRange } from '../../../ColorUtils' +import { degreesToRadians, midAngle, findNeighbor } from '../../../lib/arcUtils' +import { getColorRange } from '../../../lib/colorUtils' const PieD3Svg = domRoot => { // DOM elements diff --git a/src/lib/charts/radial-stack/RadialStackD3Svg.js b/src/lib/charts/radial-stack/RadialStackD3Svg.js deleted file mode 100644 index 5fd899517..000000000 --- a/src/lib/charts/radial-stack/RadialStackD3Svg.js +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 d3 from 'd3' -import _ from 'lodash' -import { getColorRange } from '../../../ColorUtils' - -const RadialStackD3Svg = domRoot => { - // DOM elements - const svg = d3.select(domRoot) - const element = svg.append('g') - - // d3 scales/layouts - const stack = d3.layout.stack() - const angle = d3.scale.linear() - const radius = d3.scale.linear() - const area = d3.svg.area.radial().interpolate('cardinal-closed') - - // an array to store decorator functions - let decorators = [] - - return { - draw(props) { - const { - margin, - layers, - offset, - innerRadius, - colors, - transitionDuration, - transitionEasing, - } = props - - const width = props.width - margin.left - margin.right - const height = props.height - margin.top - margin.bottom - - svg.attr({ - width: props.width, - height: props.height, - }) - - element.attr( - 'transform', - `translate(${width / 2 + margin.left}, ${height / 2 + margin.top})` - ) - - stack.offset(offset) - - const stacked = stack(layers) - - angle.range([0, 2 * Math.PI]).domain([0, stacked[0].length]) - - const outerRadius = Math.min(width, height) / 2 - radius - .range([outerRadius * innerRadius, outerRadius]) - .domain([0, d3.max(stacked, layer => d3.max(layer, d => d.y0 + d.y))]) - - const color = getColorRange(colors) - - area - .angle(d => angle(d.x)) - .innerRadius(d => radius(d.y0)) - .outerRadius(d => radius(d.y0 + d.y)) - - let paths = element.selectAll('.nivo_radial-stack_area').data(stacked) - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - // ENTER: creates new elements - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - paths - .enter() - .append('path') - .attr('class', 'nivo_radial-stack_area') - .attr('d', area) - .style('fill', (d, i) => color(i)) - - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - // UPDATE: updates existing elements - // ————————————————————————————————————————————————————————————————————————————————————————————————————————— - paths - .transition() - .duration(transitionDuration) - .ease(transitionEasing) - .attr('d', area) - .style('fill', (d, i) => color(i)) - - const radialStackContext = { - element, - outerRadius, - innerRadius: outerRadius * innerRadius, - layers, - stacked, - radius, - angle, - transitionDuration, - transitionEasing, - } - - decorators.forEach(decorator => { - decorator(radialStackContext) - }) - }, - - decorate(newDecorators = []) { - decorators = newDecorators - }, - } -} - -export default RadialStackD3Svg diff --git a/src/lib/charts/stack/StackD3.js b/src/lib/charts/stack/StackD3.js deleted file mode 100644 index 76e25717c..000000000 --- a/src/lib/charts/stack/StackD3.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 { flatten } from '../../../DataUtils' - -/** - * This wrapper is responsible for computing stack chart positions. - * It's used for all Stack related chart components. - * - * @returns {{ compute: (function) }} - * @constructor - */ -const StackD3 = () => { - const layout = d3.layout.pack() - - return { - /** - * - * @param {number} width - * @param {number} height - * @param {object} data - * @param {string} identityProperty - * @param {function} valueAccessor - * @param {number} padding - * @param {function} color - * @returns {array} - */ - compute({ width, height, data, identityProperty, valueAccessor, padding, color }) { - layout.value(valueAccessor).sort(null).size([width, height]).padding(padding) - - const flattened = flatten(data, identityProperty) - const nodes = layout.nodes(flattened).filter(d => !d.children).map(d => { - d.color = color(d.parentId) - - return d - }) - - return nodes - }, - } -} - -export default StackD3 diff --git a/src/ColorUtils.js b/src/lib/colorUtils.js similarity index 100% rename from src/ColorUtils.js rename to src/lib/colorUtils.js diff --git a/src/DataUtils.js b/src/lib/dataUtils.js similarity index 100% rename from src/DataUtils.js rename to src/lib/dataUtils.js diff --git a/src/properties/curve.js b/src/props/curve.js similarity index 100% rename from src/properties/curve.js rename to src/props/curve.js diff --git a/src/props/index.js b/src/props/index.js new file mode 100644 index 000000000..a62bc766d --- /dev/null +++ b/src/props/index.js @@ -0,0 +1,30 @@ +/* + * 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 scalePropType = PropTypes.shape({ + type: PropTypes.string.isRequired, + domain: PropTypes.array.isRequired, + range: PropTypes.array.isRequired, +}) + +export const marginPropType = PropTypes.shape({ + top: PropTypes.number, + right: PropTypes.number, + bottom: PropTypes.number, + left: PropTypes.number, +}).isRequired + +export const motionPropTypes = { + animate: PropTypes.bool.isRequired, + motionStiffness: PropTypes.number.isRequired, + motionDamping: PropTypes.number.isRequired, +} + +export * from './curve' diff --git a/test/ArcUtil.test.js b/test/lib/arcUtils.test.js similarity index 80% rename from test/ArcUtil.test.js rename to test/lib/arcUtils.test.js index d712cf7a4..e08e5ea32 100644 --- a/test/ArcUtil.test.js +++ b/test/lib/arcUtils.test.js @@ -6,9 +6,9 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -import * as crap from '../src/index' +import * as all from '../../src/index' -import { midAngle } from '../src/ArcUtils' +import { midAngle } from '../../src/lib/arcUtils' test('midAngle() should compute center of given angles', () => { expect(midAngle({ startAngle: 0, endAngle: 90 })).toBe(45) diff --git a/test/ColorUtils.test.js b/test/lib/colorUtils.test.js similarity index 97% rename from test/ColorUtils.test.js rename to test/lib/colorUtils.test.js index cf64101ad..25429bd44 100644 --- a/test/ColorUtils.test.js +++ b/test/lib/colorUtils.test.js @@ -7,7 +7,7 @@ * file that was distributed with this source code. */ import { rgb } from 'd3-color' -import { getColorGenerator, getColorsGenerator } from '../src/ColorUtils' +import { getColorGenerator, getColorsGenerator } from '../../src/lib/colorUtils' describe('getColorGenerator()', () => { it(`should return 'none' if 'none' provided`, () => {