aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/DataVizBox/ChartBox.tsx4
-rw-r--r--src/client/views/nodes/DataVizBox/LineChart.tsx124
2 files changed, 98 insertions, 30 deletions
diff --git a/src/client/views/nodes/DataVizBox/ChartBox.tsx b/src/client/views/nodes/DataVizBox/ChartBox.tsx
index 36d23d30e..7424fbe5f 100644
--- a/src/client/views/nodes/DataVizBox/ChartBox.tsx
+++ b/src/client/views/nodes/DataVizBox/ChartBox.tsx
@@ -32,6 +32,7 @@ export interface ChartData {
xLabel: string;
yLabel: string;
data: DataPoints[];
+ tooltipContent: (data: DataPoints) => string;
}
@observer
@@ -64,6 +65,9 @@ export class ChartBox extends React.Component<ChartBoxProps> {
xLabel: '',
yLabel: '',
data: [],
+ tooltipContent: (data: DataPoints) => {
+ return `<b>x: ${data.x} y: ${data.y}</b>`;
+ },
};
if (this.props.pairs && this.props.pairs.length > 0) {
diff --git a/src/client/views/nodes/DataVizBox/LineChart.tsx b/src/client/views/nodes/DataVizBox/LineChart.tsx
index 2d2e67d4f..5ad8f0846 100644
--- a/src/client/views/nodes/DataVizBox/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/LineChart.tsx
@@ -1,4 +1,4 @@
-import { computed, IReactionDisposer, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { ChartData, DataPoints } from './ChartBox';
@@ -11,9 +11,18 @@ interface LineChartProps {
height: number;
}
+interface SelectedDataPoint {
+ x: number;
+ y: number;
+ elem: d3.Selection<d3.BaseType, unknown, SVGGElement, unknown>;
+}
+
@observer
export class LineChart extends React.Component<LineChartProps> {
private _dataReactionDisposer: IReactionDisposer | undefined = undefined;
+ @observable private _x: number = 0;
+ @observable private _y: number = 0;
+ @observable private _currSelected: SelectedDataPoint | undefined = undefined;
componentDidMount() {
console.log('Getting to line chart');
@@ -27,9 +36,15 @@ export class LineChart extends React.Component<LineChartProps> {
}
}
+ tooltipContent(data: DataPoints) {
+ return `<b>x: ${data.x} y: ${data.y}</b>`;
+ }
+
drawChart() {
- console.log('Getting called');
- console.log(this.props.data);
+ // clearing tooltip
+ d3.select('#chart-container').select('svg').remove();
+ d3.select('#chart-container').select('.tooltip').remove();
+
const margin = { top: 50, right: 50, bottom: 50, left: 50 };
const { data } = this.props;
@@ -54,7 +69,7 @@ export class LineChart extends React.Component<LineChartProps> {
// 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]);
+ const yScale = d3.scaleLinear().domain([0, 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
@@ -86,37 +101,86 @@ export class LineChart extends React.Component<LineChartProps> {
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);
+ svg.append('path').datum(data.data).attr('fill', 'none').attr('stroke', 'rgba(53, 162, 235, 0.5)').attr('stroke-width', 2).attr('class', 'line').attr('d', lineGen);
+
+ // draw the datapoint circles
+ svg.selectAll('.circle-d1')
+ .data(data.data)
+ .join('circle') // enter append
+ .attr('class', 'circle-d1')
+ .attr('r', '3') // radius
+ .attr('cx', d => xScale(d.x))
+ .attr('cy', d => yScale(d.y))
+ .attr('data-x', d => d.x)
+ .attr('data-y', d => d.y);
+
+ // this.setupDatapointClickHandlers();
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);
+ const tooltip = d3
+ .select('#chart-container')
+ .append('div')
+ .attr('class', 'tooltip')
+ .style('opacity', 0)
+ .style('position', 'absolute')
+ // .style('z-index', '10')
+ .style('background', '#fff')
+ .style('border', '1px solid #ccc')
+ .style('padding', '5px')
+ .style('font-size', '12px');
+ // add all the tooltipContent to the tooltip
+ // @action
+ const mousemove = action((e: any) => {
+ const bisect = d3.bisector((d: DataPoints) => d.x).left;
+ const xPos = d3.pointer(e)[0];
+ const x0 = bisect(data.data, xScale.invert(xPos));
+ const d0 = data.data[x0];
+ this._x = d0.x;
+ this._y = d0.y;
+ focus.attr('transform', `translate(${xScale(d0.x)},${yScale(d0.y)})`);
+ // TODO: nda - implement tooltips
+ // tooltip.transition().duration(300).style('opacity', 0.9);
+ // tooltip.html(() => this.tooltipContent(d0)).attr('transform', `translate(${xScale(d0.x) + 30}px,${yScale(d0.y) + 30}px)`);
+ });
+
+ const onPointClick = action((e: any) => {
+ const bisect = d3.bisector((d: DataPoints) => d.x).left;
+ const xPos = d3.pointer(e)[0];
+ const x0 = bisect(data.data, xScale.invert(xPos));
+ const d0 = data.data[x0];
+ this._x = d0.x;
+ this._y = d0.y;
+ // find .circle-d1 with data-x = d0.x and data-y = d0.y
+ const selected = svg.selectAll('.circle-d1').filter((d: any) => d['data-x'] === d0.x && d['data-y'] === d0.y);
+ this._currSelected = { x: d0.x, y: d0.y, elem: selected };
+ console.log('Getting here');
+ console.log(this._currSelected);
+ });
+
+ 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)
+ .on('click', onPointClick);
}
render() {
- return <div id="chart-container"></div>;
+ return (
+ <div id="chart-container">
+ <span>
+ x: {this._x} y: {this._y}
+ Curr Selected: {this._currSelected ? `x: ${this._currSelected.x} y: ${this._currSelected.y}` : 'none'}
+ </span>
+ </div>
+ );
}
}