Skip to content

Commit cce5980

Browse files
author
Chris Thomas
authored
Created ContentClipPath (#1351)
* 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)'}}
1 parent 881dbe8 commit cce5980

File tree

18 files changed

+202
-7
lines changed

18 files changed

+202
-7
lines changed

docs/clip.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## Clip
2+
3+
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.
4+
5+
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.
6+
7+
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.
8+
9+
```jsx
10+
<XYPlot>
11+
<ContentClipArea id="clip" />
12+
<LineSeries style={{clipPath: 'url(#clip)'}} />
13+
</XYPlot>
14+
```
15+
16+
17+
18+
## API Reference
19+
20+
#### id (optional)
21+
22+
Type: `String`
23+
24+
The id to assign to the `clipArea`. If not provided, this will default to `content-area`

packages/react-vis/jest.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ module.exports = {
55
transform: {
66
'^.+\\.js$': path.resolve(__dirname, './jestBabelTransform.js')
77
},
8-
setupFilesAfterEnv: ['./jest.setup.js']
8+
setupFilesAfterEnv: ['./jest.setup.js'],
9+
snapshotSerializers: ['enzyme-to-json/serializer']
910
};

packages/react-vis/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,16 @@
6363
"@babel/preset-react": "^7.0.0",
6464
"@babel/register": "^7.0.0",
6565
"babel-eslint": "^10.1.0",
66-
"babel-jest":"^25.5.1",
66+
"babel-jest": "^25.5.1",
6767
"babel-plugin-module-resolver": "^4.0.0",
6868
"babelify": "^10.0.0",
6969
"browserify": "^14.3.0",
7070
"canvas-prebuilt": "^1.6.11",
7171
"enzyme": "^3.11.0",
7272
"enzyme-adapter-react-16": "^1.15.2",
73-
"eslint-plugin-jest":"^23.13.2",
74-
"jest":"^25.5.4",
73+
"enzyme-to-json": "^3.5.0",
74+
"eslint-plugin-jest": "^23.13.2",
75+
"jest": "^25.5.4",
7576
"jsdom": "^9.9.1",
7677
"node-sass": "^4.9.3",
7778
"prettier": "^1.14.2",

packages/react-vis/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export Sankey from 'sankey';
7272
export Sunburst from 'sunburst';
7373
export Treemap from 'treemap';
7474

75+
export ContentClipPath from './plot/content-clip-path';
76+
7577
export {
7678
makeHeightFlexible,
7779
makeVisFlexible,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
3+
export default function ContentClipPath(props) {
4+
const {id = 'content-area', innerWidth, innerHeight} = props;
5+
return (
6+
<defs>
7+
<clipPath id={id}>
8+
<rect x={0} y={0} width={innerWidth} height={innerHeight} />
9+
</clipPath>
10+
</defs>
11+
);
12+
}
13+
14+
ContentClipPath.requiresSVG = true;
15+
ContentClipPath.displayName = 'ContentClipPath';
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"typeAcquisition": {
3+
"enable": true,
4+
"include": [
5+
"jest"
6+
]
7+
}
8+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`content-clip-path should render 1`] = `
4+
<defs>
5+
<clipPath
6+
id="foo"
7+
>
8+
<rect
9+
height={200}
10+
width={300}
11+
x={0}
12+
y={0}
13+
/>
14+
</clipPath>
15+
</defs>
16+
`;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
import {shallow} from 'enzyme';
3+
import ContentClipPath from '../../src/plot/content-clip-path';
4+
5+
describe('content-clip-path', () => {
6+
it('should render', () => {
7+
const wrapper = shallow(
8+
<ContentClipPath id="foo" innerWidth={300} innerHeight={200} />
9+
);
10+
expect(wrapper).toMatchSnapshot();
11+
});
12+
13+
it('should default id to content-area', () => {
14+
const wrapper = shallow(
15+
<ContentClipPath innerWidth={300} innerHeight={200} />
16+
);
17+
const clip = wrapper.find('clipPath');
18+
expect(clip.prop('id')).toEqual('content-area');
19+
});
20+
});

packages/showcase/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ import HorizontalDiscreteCustomPalette from './legends/horizontal-discrete-custo
124124
import AnimationExample from './misc/animation-example';
125125
import LabelSeriesExample from './misc/label-series-example';
126126
import GradientExample from './misc/gradient-example';
127+
import ClipExample from './misc/clip-example';
127128
import NullDataExample from './misc/null-data-example';
128129
import SyncedCharts from './misc/synced-charts';
129130
import TimeChart from './misc/time-chart';
@@ -226,6 +227,7 @@ const mainShowCase = {
226227
CustomAxes,
227228
LabelSeriesExample,
228229
GradientExample,
230+
ClipExample,
229231
NullDataExample,
230232
ZoomableChartExample,
231233
SelectionPlotExample,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, {useState} from 'react';
2+
3+
import {
4+
XYPlot,
5+
XAxis,
6+
YAxis,
7+
VerticalGridLines,
8+
HorizontalGridLines,
9+
AreaSeries,
10+
ContentClipPath
11+
} from 'react-vis';
12+
13+
export default function ClipExample() {
14+
const [clip, setClip] = useState(true);
15+
16+
return (
17+
<>
18+
<label style={{display: 'block'}}>
19+
<input
20+
type="checkbox"
21+
checked={clip}
22+
onChange={e => setClip(e.currentTarget.checked)}
23+
/>
24+
Enable Clipping
25+
</label>
26+
<XYPlot xDomain={[1.2, 3]} yDomain={[11, 26]} width={300} height={300}>
27+
{clip && <ContentClipPath id="content" />}
28+
29+
<VerticalGridLines />
30+
<HorizontalGridLines />
31+
32+
<AreaSeries
33+
data={[
34+
{x: 1, y: 10, y0: 1},
35+
{x: 2, y: 25, y0: 5},
36+
{x: 3, y: 15, y0: 3}
37+
]}
38+
style={{clipPath: 'url(#content)'}}
39+
/>
40+
<XAxis />
41+
<YAxis />
42+
<AreaSeries
43+
data={[
44+
{x: 1, y: 5, y0: 6},
45+
{x: 2, y: 20, y0: 11},
46+
{x: 3, y: 10, y0: 9}
47+
]}
48+
style={{clipPath: 'url(#content)'}}
49+
/>
50+
</XYPlot>
51+
</>
52+
);
53+
}

0 commit comments

Comments
 (0)