Newer
Older
// From https://codesandbox.io/s/w0ol90x9z5
import React, { Component } from "react";
import NodeGroup from "react-move/NodeGroup";
/* import {
getAppendedData,
getTruncatedData,
getUpdatedData
} from "./helpers"; */
import "./barchart.css";
let barPadding = 2;
let widthScale = d => d * 5;
function getTextWidth(text, font) {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
context.font = font || getComputedStyle(document.body).font;
return context.measureText(text).width;
}
return "red";
} else {
return "orange";
}
};
function BarGroup(props) {
let width = widthScale(props.state.value);
let yMid = barHeight * 0.5;
return (
<g className="bar-group" transform={`translate(0, ${props.state.y})`}>
<rect
y={barPadding * 0.5}
width={width}
height={barHeight - barPadding}
style={{ fill: barColour, opacity: props.state.opacity }}
/>
<text
className="value-label"
y={yMid}
alignmentBaseline="middle"
>
{props.state.value.toFixed(0)}
</text>
<text
className="name-label"
x="-6"
y={yMid}
alignmentBaseline="middle"
style={{ opacity: props.state.opacity }}
>
{props.data.name}
</text>
</g>
);
}
class BarChart extends Component {
constructor(props) {
super(props);
this.state = {
data: this.handleData(props.data)
};
let max_name_width = 10;
for (let i = 0; i < this.state.data.length; i++){
let text_width = getTextWidth(this.state.data[i].name);
if (text_width > max_name_width){
max_name_width = text_width;
}
}
const svg_width = widthScale(100) + max_name_width;
const svg_height = barHeight*this.state.data.length + 10;
this.state = {
data: this.state.data,
max_name_width: max_name_width,
svg_width: svg_width,
svg_height: svg_height,
};
/* this.handleAdd = this.handleAdd.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.handleUpdate = this.handleUpdate.bind(this);
}
handleAdd() {
this.setState({
data: getAppendedData(this.state.data)
});
}
handleRemove() {
this.setState({
data: getTruncatedData(this.state.data)
});
}
handleUpdate() {
this.setState({
data: getUpdatedData(this.state.data)
}); */
};
handleData(arr) {
var items = Object.keys(arr).map((key) => [key, arr[key].probability]);
items.sort((first, second) => second[1] - first[1]);
let numItems = items.length;
let data = Array(numItems);
for (let i = 0; i < items.length; i++) {
value: items[i][1],
name: items[i][0],
};
data[i] = item
}
data.map(d => d)
return data;
};
startTransition(d, i) {
return { value: 0, y: i * barHeight, opacity: 0 };
}
enterTransition(d) {
return { value: [d.value], opacity: [1], timing: { duration: 250 } };
}
updateTransition(d, i) {
return { value: [d.value], y: [i * barHeight], timing: { duration: 300 } };
}
leaveTransition(d) {
return { y: [-barHeight], opacity: [0], timing: { duration: 250 } };
}
render() {
return (
<div>
<svg width="100%" height={this.state.svg_height} viewBox={"0 0 " + this.state.svg_width + " "+this.state.svg_height} preserveAspectRatio="xMinYMin">
<g className="chart" transform={"translate(" + this.state.max_name_width.toString() + ",10)"}>
<NodeGroup
data={this.state.data}
keyAccessor={d => d.name}
start={this.startTransition}
enter={this.enterTransition}
update={this.updateTransition}
leave={this.leaveTransition}
>
{nodes => (
<g>
{nodes.map(({ key, data, state }) => (
<BarGroup key={key} data={data} state={state} />
))}
</g>
)}
</NodeGroup>
</g>
</svg>
</div>
);
}
}
export default BarChart;