1
0
Fork 0
empact/app/jsx/charts/bc/bar.jsx

104 lines
3.6 KiB
JavaScript

var Bar = React.createClass({
mixins: [ReactRouter.Navigation, ChartAnimationMixin],
height: 28,
labelPaddingH: 5, // Label horizontal padding
labelPaddingV: 2, // Label vertical padding
labelMarginV: 4, // Tune text vertical alignment
labelHeight: 16, // Text size
labelOuterHeight: 20, // labelHeight + 2*labelPaddingV,
getInitialState: function() {
return {
labelX: 0,
lastLabelX: this.labelPaddingH
};
},
componentDidMount: function() {
this.calculateLabelPosition();
},
componentWillReceiveProps: function(newProps) {
if (_.isEqual(this.props, newProps)) {
return;
}
this.setState({
lastBarX: (this.props.x !== undefined ? this.props.x : newProps.x),
lastBarWidth: (this.props.width !== undefined ? this.props.width : newProps.width),
lastLabelX: this.state.labelX
}, this.calculateLabelPosition);
},
calculateLabelPosition: function() {
var val = this.props.value,
offset = this.props.offset,
label = this.props.item + ': ' + formatNumber(val),
labelWidth = textWidth(label),
labelOffsetWidth = labelWidth + 2*this.labelPaddingH,
labelX;
if (offset === 0) {
labelX = this.labelPaddingH;
} else {
if (val < 0) {
if (offset >= labelOffsetWidth) {
labelX = offset - labelOffsetWidth + this.labelPaddingH;
} else {
labelX = offset + this.labelPaddingH;
}
} else {
if (offset + labelOffsetWidth <= this.props.max) {
labelX = offset + this.labelPaddingH;
} else {
labelX = offset - labelOffsetWidth + this.labelPaddingH;
}
}
}
this.setState({
labelX: labelX,
barWidth: (this.props.item && this.props.width < 5 ? 5 : this.props.width)
}, this.animateAll);
},
animateAll: function() {
this.clearAnimations(this.refs.bar);
this.clearAnimations(this.refs.label);
this.animate(this.refs.bar, 'width', this.state.lastBarWidth, this.state.barWidth);
this.animate(this.refs.bar, 'x', this.state.lastBarX, this.props.x);
this.animate(this.refs.label, 'x', this.state.lastLabelX, this.state.labelX);
},
render: function() {
var label = this.props.item ? (this.props.item + ': ' + formatNumber(this.props.value)) : '',
labelWidth = textWidth(label),
labelOuterWidth = (labelWidth == 0 ? 0 : labelWidth + 2*this.labelPaddingH),
barX = (this.state.lastBarX && this.state.lastBarX !== this.props.x
? this.state.lastBarX
: this.props.x),
barWidth = (this.state.lastBarWidth && this.state.lastBarWidth !== this.state.barWidth
? this.state.lastBarWidth
: this.state.barWidth);
return (
<g onClick={this.props.onClick}>
<rect ref="bar" className="bar"
fill={this.props.color}
width={barWidth}
height={this.props.height}
x={barX}
y={this.props.y}
rx="2"
ry="2" />
<text ref="label" className="label"
x={this.state.labelX}
y={this.props.y + this.labelMarginV + this.labelHeight}>
{label}
</text>
</g>
);
}
});