diff options
Diffstat (limited to 'src/client/views/nodes/DataVizBox/LineChart.tsx')
-rw-r--r-- | src/client/views/nodes/DataVizBox/LineChart.tsx | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/client/views/nodes/DataVizBox/LineChart.tsx b/src/client/views/nodes/DataVizBox/LineChart.tsx new file mode 100644 index 000000000..2d2e67d4f --- /dev/null +++ b/src/client/views/nodes/DataVizBox/LineChart.tsx @@ -0,0 +1,122 @@ +import { computed, IReactionDisposer, reaction } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { ChartData, DataPoints } from './ChartBox'; +// import d3 +import * as d3 from 'd3'; + +interface LineChartProps { + data: ChartData; + width: number; + height: number; +} + +@observer +export class LineChart extends React.Component<LineChartProps> { + private _dataReactionDisposer: IReactionDisposer | undefined = undefined; + + componentDidMount() { + console.log('Getting to line chart'); + this.drawChart(); + this._dataReactionDisposer = reaction(() => this.props.data, this.drawChart); + } + + componentWillUnmount() { + if (this._dataReactionDisposer) { + this._dataReactionDisposer(); + } + } + + drawChart() { + console.log('Getting called'); + console.log(this.props.data); + const margin = { top: 50, right: 50, bottom: 50, left: 50 }; + const { data } = this.props; + + const yMin = d3.min(data.data, d => d.y); + const yMax = d3.max(data.data, d => d.y); + + // TODO: nda - modify data.x to support strings + + const xMin = d3.min(data.data, d => d.x); + const xMax = d3.max(data.data, d => d.x); + + // adding svg + const svg = d3.select('#chart-container').append('svg').attr('width', '100%').attr('height', '100%').append('g').attr('transform', `translate(${margin.left}, ${margin.top})`); + + // adding tooltip + // const tooltip = d3.select('#chart-container').append('div').attr('class', 'tooltip'); + + if (!xMin || !xMax || !yMin || !yMax) { + // TODO: nda - error handle + return; + } + // adding x axis + const xScale = d3.scaleLinear().domain([xMin, xMax]).range([0, this.props.width]); + + const yScale = d3.scaleLinear().domain([yMin, yMax]).range([this.props.height, 0]); + + // create a line function that takes in the data.data.x and data.data.y + // TODO: nda - fix the types for the d here + const lineGen = d3 + .line<DataPoints>() + .x(d => xScale(d.x)) + .y(d => yScale(d.y)) + .curve(d3.curveMonotoneX); + + // adding the line to the svg + svg.append('g') + .attr('class', 'grid') + .attr('transform', `translate(0,${this.props.height})`) + .call( + d3 + .axisBottom(xScale) + .tickSize(-this.props.height) + .tickFormat((a, b) => '') + ); + svg.append('g') + .attr('class', 'grid') + .call( + d3 + .axisLeft(yScale) + .tickSize(-this.props.width) + .tickFormat((a, b) => '') + ); + svg.append('g').attr('class', 'x-axis').attr('transform', `translate(0,${this.props.height})`).call(d3.axisBottom(xScale).tickSize(15)); + svg.append('g').attr('class', 'y-axis').call(d3.axisLeft(yScale)); + + // draw the line + svg.append('path').datum(data.data).attr('fill', 'none').attr('stroke', '#f6c3d0').attr('stroke-width', 4).attr('class', 'line').attr('d', lineGen); + + const focus = svg.append('g').attr('class', 'focus').style('display', 'none'); + focus.append('circle').attr('r', 5).attr('class', 'circle'); + // const tooltip = d3.select('#container').append('div').attr('class', 'tooltip').style('opacity', 0); + + // const mousemove = (event) => { + // const bisect = d3.bisector((d: DataPoints) => d.x).left; + // const xPos = d3.pointer(this)[0]; + // const x0 = bisect(data.data, xScale.invert(xPos)); + // const d0 = data.data[x0]; + // focus.attr('transform', `translate(${xScale(d0.x)},${yScale(d0.y)})`); + // tooltip.transition().duration(300).style('opacity', 0.9); + // tooltip.html(d0.tooltipContent || d0.label).style('transform', `translate(${xScale(d0.label) + 30}px,${yScale(d0.value) - 30}px)`); + // } + + // svg.append('rect') + // .attr('class', 'overlay') + // .attr('width', this.props.width) + // .attr('height', this.props.height) + // .style('opacity', 0) + // .on('mouseover', () => { + // focus.style('display', null); + // }) + // .on('mouseout', () => { + // tooltip.transition().duration(300).style('opacity', 0); + // }) + // .on('mousemove', mousemove); + } + + render() { + return <div id="chart-container"></div>; + } +} |