Skip to content

Commit

Permalink
Scatterplot already exisits (uber#911)
Browse files Browse the repository at this point in the history
* Make scatterplot voronoi more visible

* impove previous voronoi scatterplot example
  • Loading branch information
mcnuttandrew authored Aug 20, 2018
1 parent 0ff1fdc commit abfeacc
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 44 deletions.
6 changes: 5 additions & 1 deletion docs/mark-series.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ The SVG mode is accessed by using the normal `MarkSeries`, just as above, while
-**NOTE**: using the Canvas version of this layer disables animation
Mark series can usefully be deployed with voronois for fast and accurate mouse overs!
<!-- INJECT:"DynamicCrosshairScatterplotLink" -->
## Data format reference
#### x
Expand Down Expand Up @@ -239,4 +243,4 @@ The handler passes two arguments, the corresponding datapoint and the actual eve
// does something on right click
// you can access the value of the event
}}
```
```
3 changes: 2 additions & 1 deletion docs/voronoi.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Voronoi diagrams are useful for making a chart interactive by creating target ar

## API Reference

<!-- INJECT:"DynamicCrosshairScatterplotLink" -->

### extend (required)
Type: `Array`
Sets the clip extent of the Voronoi layout to the specified bounds. The extent bounds are specified as an array [[x0, y0], [x1, y1]], where x0 is the left side of the extent, y0 is the top, x1 is the right and y1 is the bottom.
Expand Down Expand Up @@ -81,4 +83,3 @@ Add css styles to Voronoi cells.
For example:
`polygonStyle={{stroke: 'red'}}`
This will add a red border around cell which is very useful for debugging the Voronoi diagram.

85 changes: 44 additions & 41 deletions showcase/axes/dynamic-crosshair-scatterplot.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,73 +48,76 @@ const DATA = [
{x: 2.7, y: 13.7, size: 14},
{x: 2.9, y: 7.7, size: 26},
{x: 3, y: 5.4, size: 6}
];
].map((d, id) => ({...d, id}));

const x = scaleLinear()
.domain([1, 3])
.range([40, 290]);
const y = scaleLinear()
.domain([4, 14])
.range([260, 10]);
const getDomain = (data, key) => {
const {min, max} = data.reduce((acc, row) => ({
min: Math.min(acc.min, row[key]),
max: Math.max(acc.max, row[key])
}), {min: Infinity, max: -Infinity});
return [min, max];
};

// magic numbers chosen for design
const sizeRange = [5, 13];
const margin = {top: 10, left: 40, bottom: 40, right: 10};
const width = 300;
const height = 300;

const x = scaleLinear().domain(getDomain(DATA, 'x')).range([0, width]);
const y = scaleLinear().domain(getDomain(DATA, 'y')).range([height, 0]);

export default class Example extends React.Component {
state = {
data: DATA,
selectedPointId: null,
showVoronoi: false
}

/**
* Event handler for onNearestXY.
* @param {Object} value Selected value.
* @private
*/
_onNearestXY = (value, {index}) => {
this.setState({selectedPointId: index});
}

/**
* Event handler for onMouseLeave.
* @private
*/
_onMouseLeave = () => {
this.setState({selectedPointId: null});
showVoronoi: true
}

render() {
const {data, selectedPointId, showVoronoi} = this.state;
const {
crosshairValues,
selectedPointId,
showVoronoi
} = this.state;

return (
<div>
<label style={{display: 'block'}}>
<input type="checkbox"
checked={showVoronoi}
onChange={e => this.setState({showVoronoi: !showVoronoi})}
onChange={() => this.setState({showVoronoi: !showVoronoi})}
/>
Show Voronoi
</label>
<XYPlot
onMouseLeave={this._onMouseLeave}
width={300}
height={300}>
onMouseLeave={() => this.setState({selectedPointId: null, crosshairValues: null})}
width={width}
height={height}>
<VerticalGridLines />
<HorizontalGridLines />
<XAxis />
<YAxis />
<MarkSeries
className="mark-series-example"
colorType="literal"
data={data.map((point, index) =>
({...point, color: selectedPointId === index ? '#FF9833' : '#12939A'}))}
onNearestXY={this._onNearestXY}
sizeRange={[5, 13]} />
<Crosshair values={this.state.crosshairValues}/>
<Voronoi
extent={[[40, 10], [290, 260]]}
nodes={data}
polygonStyle={{stroke: showVoronoi ? 'rgba(0, 0, 0, .2)' : null}}
data={DATA}
onNearestXY={(value, {index}) => this.setState({
selectedPointId: index,
crosshairValues: [value]
})}
getColor={({id}) => selectedPointId === id ? '#FF9833' : '#12939A'}
sizeRange={sizeRange} />
{crosshairValues && <Crosshair values={crosshairValues}/>}
{showVoronoi && <Voronoi
extent={[
[margin.left, margin.top],
[width - margin.right, height - margin.bottom]
]}
nodes={DATA}
polygonStyle={{stroke: 'rgba(0, 0, 0, .2)'}}
x={d => x(d.x)}
y={d => y(d.y)}
/>
/>}
</XYPlot>
</div>
);
Expand Down
24 changes: 23 additions & 1 deletion tests/components/voronoi-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import React from 'react';
import {mount} from 'enzyme';
import Voronoi from '../../src/plot/voronoi.js';

test('Voronoi: ', t => {
import VoronoiLineChart from '../../showcase/misc/voronoi-line-chart';

test('Voronoi: Basic Chart', t => {
const $ = mount(<Voronoi
extent={[[0, 0], [200, 200]]}
nodes={Array(100).fill().map((e, x) => ({
Expand All @@ -21,3 +23,23 @@ test('Voronoi: ', t => {
t.end();
});

test('Voronoi: Showcase Example - VoronoiLineChart', t => {
const $ = mount(<VoronoiLineChart/>);

t.equal($.text(), 'Show Voronoi1.01.52.02.53.03.54.0X Axis2468101214Y Axis', 'should find the correct text');
t.equal($.find('.rv-voronoi__cell').length, 12, 'should find the right number of voronoi cells');
t.equal($.find('.rv-xy-plot__series--line').length, 3, 'should find the right number of line series');
t.equal($.find('circle').length, 0, 'should initially find no scatterplot dots');

$.find('input').simulate('click');
$.find('.rv-voronoi__cell').at(0).simulate('mouseOver');

t.equal($.find('circle').length, 1, 'should now find a single hover dot');

$.find('.rv-voronoi__cell').at(0).simulate('mouseOut');

t.equal($.find('circle').length, 0, 'after mouse out should find no hover dots');

t.end();
});

0 comments on commit abfeacc

Please sign in to comment.