Skip to content

Commit

Permalink
feat(stack): add Stack component for d3.layout.stack
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphael Benitte committed Apr 16, 2016
1 parent a27a211 commit 7122dca
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 64 deletions.
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"presets": [
"es2015",
"react"
"react",
"stage-0"
]
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
},
"devDependencies": {
"ava": "0.14.0",
"babel-cli": "6.7.5",
"babel-preset-es2015": "6.6.0",
"babel-preset-react": "6.5.0",
"babel-preset-stage-0": "6.5.0",
"react": "^0.13.3"
},
"peerDependencies": {
"react": "^0.13.3"
},
"main": "src/index.js",
"main": "lib",
"scripts": {
"watch": "babel src --watch --out-dir lib",
"test": "ava",
"test-cover": "nyc ava"
},
Expand Down
42 changes: 21 additions & 21 deletions src/ArcUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ export const radiansToDegrees = radians => 180 * radians / Math.PI;
/**
* Try to get a neighbor arc, otherwise, returns null.
*
* @param {Number} i
* @param {String} keyProp
* @param {Array} prevData
* @param {Array} newData
* @param {Number} i
* @param {function} identity
* @param {Array} prevData
* @param {Array} newData
* @returns {{startAngle: *, endAngle: *}}
*/
export const findNeighbor = (i, keyProp, prevData, newData) => {
const preceding = findPreceding(i, keyProp, prevData, newData);
export const findNeighbor = (i, identity, prevData, newData) => {
const preceding = findPreceding(i, identity, prevData, newData);
if (preceding) {
return {
startAngle: preceding.endAngle,
endAngle: preceding.endAngle
};
}

const following = findFollowing(i, keyProp, prevData, newData);
const following = findFollowing(i, identity, prevData, newData);
if (following) {
return {
startAngle: following.startAngle,
Expand All @@ -38,20 +38,20 @@ export const findNeighbor = (i, keyProp, prevData, newData) => {
/**
* Find the element in prevData that joins the highest preceding element in newData.
*
* @param {Number} i
* @param {String} keyProp
* @param {Array} prevData
* @param {Array} newData
* @param {Number} i
* @param {function} identity
* @param {Array} prevData
* @param {Array} newData
* @returns {*}
*/
export const findPreceding = (i, keyProp, prevData, newData) => {
export const findPreceding = (i, identity, prevData, newData) => {
const m = prevData.length;

while (--i >= 0) {
let k = newData[i].data[keyProp];
let k = identity(newData[i]);

for (let j = 0; j < m; ++j) {
if (prevData[j].data[keyProp] === k) {
if (identity(prevData[j]) === k) {
return prevData[j];
}
}
Expand All @@ -61,21 +61,21 @@ export const findPreceding = (i, keyProp, prevData, newData) => {
/**
* Find the element in prevData that joins the lowest following element in newData.
*
* @param {Number} i
* @param {String} keyProp
* @param {Array} prevData
* @param {Array} newData
* @param {Number} i
* @param {function} identity
* @param {Array} prevData
* @param {Array} newData
* @returns {*}
*/
export const findFollowing = (i, keyProp, prevData, newData) => {
export const findFollowing = (i, identity, prevData, newData) => {
const n = newData.length;
const m = prevData.length;

while (++i < n) {
let k = newData[i].data[keyProp];
let k = identity(newData[i]);

for (let j = 0; j < m; ++j) {
if (prevData[j].data[keyProp] === k) {
if (identity(prevData[j]) === k) {
return prevData[j];
}
}
Expand Down
1 change: 0 additions & 1 deletion src/components/Chart.jsx → src/components/Chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class Chart extends Component {
} = this.props;

const margin = _.assign({}, defaultMargin, this.props.margin);

const width = containerWidth - margin.left - margin.right;
const height = containerHeight - margin.top - margin.bottom;

Expand Down
14 changes: 12 additions & 2 deletions src/components/axes/AxisX.jsx → src/components/axes/AxisX.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react';
import d3 from 'd3';

class AxisX extends Component {
shouldComponentUpdate(nextProps) {
renderD3(props) {
const {
orient,
xScale,
Expand All @@ -11,7 +11,7 @@ class AxisX extends Component {
height,
transitionDuration,
transitionEasing
} = nextProps;
} = props;

const element = d3.select(React.findDOMNode(this));
element.attr('transform', `translate(0, ${height})`);
Expand All @@ -36,6 +36,16 @@ class AxisX extends Component {
return false;
}

componentDidMount() {
this.renderD3(this.props);
}

shouldComponentUpdate(nextProps) {
this.renderD3(nextProps);

return false;
}

render() {
return <g className="chart__axis chart__axis--x"/>;
}
Expand Down
14 changes: 12 additions & 2 deletions src/components/axes/AxisY.jsx → src/components/axes/AxisY.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react';
import d3 from 'd3';

class AxisY extends Component {
shouldComponentUpdate(nextProps) {
renderD3(props) {
const {
orient,
yScale,
Expand All @@ -11,7 +11,7 @@ class AxisY extends Component {
width,
transitionDuration,
transitionEasing
} = nextProps;
} = props;

const element = d3.select(React.findDOMNode(this));

Expand All @@ -35,6 +35,16 @@ class AxisY extends Component {
return false;
}

componentDidMount() {
this.renderD3(this.props);
}

shouldComponentUpdate(nextProps) {
this.renderD3(nextProps);

return false;
}

render() {
return <g className="chart__axis chart__axis--y"/>;
}
Expand Down
29 changes: 24 additions & 5 deletions src/components/layouts/Pie.jsx → src/components/layouts/Pie.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { degreesToRadians, findNeighbor } from '../../ArcUtils';


class Pie extends Component {
shouldComponentUpdate(nextProps) {
renderD3(nextProps) {
const {
data,
width, height,
Expand All @@ -16,6 +16,8 @@ class Pie extends Component {
transitionDuration, transitionEasing,
} = nextProps;

const identity = d => d.data[keyProp];

const element = d3.select(React.findDOMNode(this));
const container = element.select('.chart__layout__pie__slices');

Expand Down Expand Up @@ -60,17 +62,17 @@ class Pie extends Component {
};
}

slices = slices.data(newData, d => d.data[keyProp]);
slices = slices.data(newData, identity);
slices.enter().append('path')
.attr('class', 'chart__layout__pie__slice')
.style('fill', d => d.data.color)
.each(function (d, i) {
this._current = findNeighbor(i, keyProp, previousData, newData) || _.assign({}, d, { endAngle: d.startAngle });
this._current = findNeighbor(i, identity, previousData, newData) || _.assign({}, d, { endAngle: d.startAngle });
})
;
slices.exit()
.datum((d, i) => {
return findNeighbor(i, keyProp, newData, previousData) || d;
return findNeighbor(i, identity, newData, previousData) || d;
})
.transition()
.duration(transitionDuration)
Expand All @@ -86,14 +88,31 @@ class Pie extends Component {
.style('fill', d => d.data.color)
;

const pieContext = {
element,
pie,
arc, radius,
identity,
previousData, newData
};

this.legends.forEach(legend => {
legend({ element, pie, arc, keyProp, data: newData, radius });
legend(pieContext);
});
}

shouldComponentUpdate(nextProps) {
this.renderD3(nextProps);

return false;
}

componentDidMount() {
this.renderD3(this.props);
}

componentWillMount() {
console.log('Pie.render()');
const { children } = this.props;

const legends = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import React, { Component, PropTypes } from 'react';
import invariant from 'invariant';
import d3 from 'd3';
import { midAngle } from '../../ArcUtils';
import { midAngle, findNeighbor } from '../../ArcUtils';


class PieColumnLegends extends Component {
static createLegendsFromReactElement(element) {
const { props } = element;

return ({ element, arc, keyProp, pie, data, radius }) => {
// Receive context from Parent Pie component
return ({ element, arc, identity, pie, previousData, newData, radius }) => {

const labelFn = props.labelFn || (d => d.data[keyProp]);
const labelFn = props.labelFn || identity;

const outerArc = d3.svg.arc()
.innerRadius(radius + props.radiusOffset)
.outerRadius(radius + props.radiusOffset)
;

let lines = element.selectAll('.line').data(data, d => d.data[keyProp]);
let lines = element.selectAll('.line').data(newData, identity);
lines.enter()
.append('polyline')
.attr('stroke', '#fff')
Expand All @@ -39,7 +40,7 @@ class PieColumnLegends extends Component {
.remove()
;

let labels = element.selectAll('.column-label').data(data, d => d.data[keyProp]);
let labels = element.selectAll('.column-label').data(newData, identity);
labels.enter()
.append('text')
.attr('fill', '#fff')
Expand Down
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 7122dca

Please sign in to comment.