Skip to content

Commit

Permalink
Created ContentClipPath (#1351)
Browse files Browse the repository at this point in the history
* Created ContentClipPath

The ContentClipPath creates a new clipPath that is the size of the
inner portion of the graph.
Other series can use this with `style={{clipPath: 'url(#content-area)'}}
  • Loading branch information
Chris Thomas authored Jun 7, 2020
1 parent 881dbe8 commit cce5980
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 7 deletions.
24 changes: 24 additions & 0 deletions docs/clip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Clip

Depending on the data and domain, sometimes the series in the plot will extend into the axis. This can either be solved with a [Border](border.md), or the elements can be clipped.

To have the rendered series, clipped you will need to set up a `clipPath` (see [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/clipPath)) and tell the series to use it.

As seen below, the `clipPath` can be created with the `ContentClipArea` component, and its `id` can be referenced by the components that want to be clipped.

```jsx
<XYPlot>
<ContentClipArea id="clip" />
<LineSeries style={{clipPath: 'url(#clip)'}} />
</XYPlot>
```



## API Reference

#### id (optional)

Type: `String`

The id to assign to the `clipArea`. If not provided, this will default to `content-area`
3 changes: 2 additions & 1 deletion packages/react-vis/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ module.exports = {
transform: {
'^.+\\.js$': path.resolve(__dirname, './jestBabelTransform.js')
},
setupFilesAfterEnv: ['./jest.setup.js']
setupFilesAfterEnv: ['./jest.setup.js'],
snapshotSerializers: ['enzyme-to-json/serializer']
};
7 changes: 4 additions & 3 deletions packages/react-vis/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,16 @@
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.0.0",
"babel-eslint": "^10.1.0",
"babel-jest":"^25.5.1",
"babel-jest": "^25.5.1",
"babel-plugin-module-resolver": "^4.0.0",
"babelify": "^10.0.0",
"browserify": "^14.3.0",
"canvas-prebuilt": "^1.6.11",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"eslint-plugin-jest":"^23.13.2",
"jest":"^25.5.4",
"enzyme-to-json": "^3.5.0",
"eslint-plugin-jest": "^23.13.2",
"jest": "^25.5.4",
"jsdom": "^9.9.1",
"node-sass": "^4.9.3",
"prettier": "^1.14.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/react-vis/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ export Sankey from 'sankey';
export Sunburst from 'sunburst';
export Treemap from 'treemap';

export ContentClipPath from './plot/content-clip-path';

export {
makeHeightFlexible,
makeVisFlexible,
Expand Down
15 changes: 15 additions & 0 deletions packages/react-vis/src/plot/content-clip-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

export default function ContentClipPath(props) {
const {id = 'content-area', innerWidth, innerHeight} = props;
return (
<defs>
<clipPath id={id}>
<rect x={0} y={0} width={innerWidth} height={innerHeight} />
</clipPath>
</defs>
);
}

ContentClipPath.requiresSVG = true;
ContentClipPath.displayName = 'ContentClipPath';
8 changes: 8 additions & 0 deletions packages/react-vis/tests/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"typeAcquisition": {
"enable": true,
"include": [
"jest"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`content-clip-path should render 1`] = `
<defs>
<clipPath
id="foo"
>
<rect
height={200}
width={300}
x={0}
y={0}
/>
</clipPath>
</defs>
`;
20 changes: 20 additions & 0 deletions packages/react-vis/tests/plot/content-clip-path.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import {shallow} from 'enzyme';
import ContentClipPath from '../../src/plot/content-clip-path';

describe('content-clip-path', () => {
it('should render', () => {
const wrapper = shallow(
<ContentClipPath id="foo" innerWidth={300} innerHeight={200} />
);
expect(wrapper).toMatchSnapshot();
});

it('should default id to content-area', () => {
const wrapper = shallow(
<ContentClipPath innerWidth={300} innerHeight={200} />
);
const clip = wrapper.find('clipPath');
expect(clip.prop('id')).toEqual('content-area');
});
});
2 changes: 2 additions & 0 deletions packages/showcase/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ import HorizontalDiscreteCustomPalette from './legends/horizontal-discrete-custo
import AnimationExample from './misc/animation-example';
import LabelSeriesExample from './misc/label-series-example';
import GradientExample from './misc/gradient-example';
import ClipExample from './misc/clip-example';
import NullDataExample from './misc/null-data-example';
import SyncedCharts from './misc/synced-charts';
import TimeChart from './misc/time-chart';
Expand Down Expand Up @@ -226,6 +227,7 @@ const mainShowCase = {
CustomAxes,
LabelSeriesExample,
GradientExample,
ClipExample,
NullDataExample,
ZoomableChartExample,
SelectionPlotExample,
Expand Down
53 changes: 53 additions & 0 deletions packages/showcase/misc/clip-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, {useState} from 'react';

import {
XYPlot,
XAxis,
YAxis,
VerticalGridLines,
HorizontalGridLines,
AreaSeries,
ContentClipPath
} from 'react-vis';

export default function ClipExample() {
const [clip, setClip] = useState(true);

return (
<>
<label style={{display: 'block'}}>
<input
type="checkbox"
checked={clip}
onChange={e => setClip(e.currentTarget.checked)}
/>
Enable Clipping
</label>
<XYPlot xDomain={[1.2, 3]} yDomain={[11, 26]} width={300} height={300}>
{clip && <ContentClipPath id="content" />}

<VerticalGridLines />
<HorizontalGridLines />

<AreaSeries
data={[
{x: 1, y: 10, y0: 1},
{x: 2, y: 25, y0: 5},
{x: 3, y: 15, y0: 3}
]}
style={{clipPath: 'url(#content)'}}
/>
<XAxis />
<YAxis />
<AreaSeries
data={[
{x: 1, y: 5, y0: 6},
{x: 2, y: 20, y0: 11},
{x: 3, y: 10, y0: 9}
]}
style={{clipPath: 'url(#content)'}}
/>
</XYPlot>
</>
);
}
1 change: 1 addition & 0 deletions packages/showcase/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"version": "0.1.0",
"scripts": {
"start": "webpack-dev-server --progress --hot --port 3001",
"lint": "eslint .",
"build": "NODE_ENV=production webpack",
"build:windows": "set NODE_ENV=production&&.\\node_modules\\.bin\\webpack"
},
Expand Down
1 change: 1 addition & 0 deletions packages/showcase/showcase-links.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const SHOWCASE_LINKS = {
TriangleExample: `${SHOWCASE_BASE_URL}/misc/triangle-example.js`,
VoronoiLineChart: `${SHOWCASE_BASE_URL}/misc/voronoi-line-chart.js`,
GradientExample: `${SHOWCASE_BASE_URL}/misc/gradient-example.js`,
ClipExample: `${SHOWCASE_BASE_URL}/misc/clip-example.js`,
AnimationExample: `${SHOWCASE_BASE_URL}/misc/animation-example.js`,
LabelSeriesExample: `${SHOWCASE_BASE_URL}/misc/label-series-example.js`,
NullDataExample: `${SHOWCASE_BASE_URL}/misc/null-data-example.js`,
Expand Down
10 changes: 9 additions & 1 deletion packages/showcase/showcase-sections/misc-showcase.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const {
ZoomableChartExample,
SelectionPlotExample,
DragableChartExample,
BidirectionDragChart
BidirectionDragChart,
ClipExample
} = showCase;

const MISC = [
Expand Down Expand Up @@ -49,6 +50,13 @@ const MISC = [
docsLink:
'http://uber.github.io/react-vis/documentation/api-reference/gradients'
},
{
name: 'Content Area Clipping',
component: ClipExample,
componentName: 'ClipExample',
sourceLink: `${SHOWCASE_BASE_URL}/misc/clip-example.js`,
docsLink: 'http://uber.github.io/react-vis/documentation/api-reference/clip'
},
{
name: 'Animation Example',
component: AnimationExample,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import {mapSection} from '../showcase-components/showcase-utils';
import {showCase} from '../index';
import {REACTVIS_BASE_URL} from '../index';
import {REACTVIS_BASE_URL} from '../showcase-links';
const {
AnimatedParallelCoordinates,
BasicParallelCoordinates,
Expand Down
2 changes: 2 additions & 0 deletions packages/website/src/mdRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import treemap from '../../docs/treemap.md';
import voronoi from '../../docs/voronoi.md';
import whiskerSeries from '../../docs/whisker-series.md';
import xy from '../../docs/xy-plot.md';
import clip from '../../docs/clip.md';

const mdRoutes = [
{
Expand Down Expand Up @@ -238,6 +239,7 @@ const mdRoutes = [
name: 'Flexible plots',
markdown: flexiblePlots
},
{name: 'Clipping', markdown: clip},
{
name: 'Borders',
markdown: borders
Expand Down
2 changes: 2 additions & 0 deletions packages/website/storybook/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ import './radial-story';

import './axis-story';
import './legend-story';

import './misc-story';
31 changes: 31 additions & 0 deletions packages/website/storybook/misc-story.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* eslint-env node */

import React from 'react';

import {storiesOf} from '@storybook/react';

import {withKnobs, boolean} from '@storybook/addon-knobs/react';
import {SimpleChartWrapper} from './storybook-utils';
import {generateLinearData} from './storybook-data';

import {LineSeries, ContentClipPath} from 'react-vis';

const data = generateLinearData({randomFactor: 10});

storiesOf('Misc', module)
.addDecorator(withKnobs)
.addWithJSX('Clip Content', () => {
const margin = {left: 40, top: 40, bottom: 40, right: 40};
const xDomain = [data[1].x, data[data.length - 2].x];
const shouldClip = boolean(
'Enable Clipping',
false,
'General chart options'
);
return (
<SimpleChartWrapper xDomain={xDomain} yDomain={[0, 20]} margin={margin}>
{shouldClip && <ContentClipPath id="clip" />}
<LineSeries data={data} style={{clipPath: 'url(#clip)'}} />
</SimpleChartWrapper>
);
});
10 changes: 9 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6335,6 +6335,14 @@ enzyme-shallow-equal@^1.0.1:
has "^1.0.3"
object-is "^1.0.2"

enzyme-to-json@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.5.0.tgz#3d536f1e8fb50d972360014fe2bd64e6a672f7dd"
integrity sha1-PVNvHo+1DZcjYAFP4r1k5qZy990=
dependencies:
lodash "^4.17.15"
react-is "^16.12.0"

enzyme@^3.11.0:
version "3.11.0"
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28"
Expand Down Expand Up @@ -9549,7 +9557,7 @@ js-base64@^2.1.8, js-base64@^2.1.9:
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209"
integrity sha1-MTtidN2nGPcU0AszMLuubjjpAgk=

js-beautify@1.10.3, js-beautify@^1.8.8:
js-beautify@^1.8.8:
version "1.10.3"
resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.10.3.tgz#c73fa10cf69d3dfa52d8ed624f23c64c0a6a94c1"
integrity sha1-xz+hDPadPfpS2O1iTyPGTApqlME=
Expand Down

0 comments on commit cce5980

Please sign in to comment.