Skip to content

Commit 6b13f1f

Browse files
committed
Add support for headless, styleEnabled and the following (canvas renderer) rendering hints: hideEdgesOnViewport, textureOnViewport, motionBlur, motionBlurOpacity, wheelSensitivity, pixelRatio
- Add support for the options. - Add check for style patching, in the case of a headless instance. - Add test cases for `headless` and `styleEnabled`.
1 parent 0edbf07 commit 6b13f1f

5 files changed

Lines changed: 205 additions & 6 deletions

File tree

src/component.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,30 @@ export default class CytoscapeComponent extends React.Component {
4545

4646
componentDidMount() {
4747
const container = ReactDOM.findDOMNode(this);
48-
const { global } = this.props;
49-
const cy = (this._cy = new Cytoscape({ container }));
48+
49+
const {
50+
global,
51+
headless,
52+
styleEnabled,
53+
hideEdgesOnViewport,
54+
textureOnViewport,
55+
motionBlur,
56+
motionBlurOpacity,
57+
wheelSensitivity,
58+
pixelRatio
59+
} = this.props;
60+
61+
const cy = (this._cy = new Cytoscape({
62+
container,
63+
headless,
64+
styleEnabled,
65+
hideEdgesOnViewport,
66+
textureOnViewport,
67+
motionBlur,
68+
motionBlurOpacity,
69+
wheelSensitivity,
70+
pixelRatio
71+
}));
5072

5173
if (global) {
5274
window[global] = cy;

src/patch.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@ const patchLayout = (cy, layout1, layout2, toJson) => {
6767
};
6868

6969
const patchStyle = (cy, style1, style2, toJson) => {
70-
cy.style()
71-
.fromJson(toJson(style2))
72-
.update();
70+
const style = cy.style();
71+
72+
if (style == null) {
73+
return;
74+
}
75+
76+
style.fromJson(toJson(style2)).update();
7377
};
7478

7579
const patchElements = (cy, eles1, eles2, toJson, get, forEach, diff) => {

src/types.js

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,66 @@ export const types = {
210210
*
211211
* `<CytoscapeComponent cy={cy => (myCyRef = cy)} />`
212212
*/
213-
cy: func
213+
cy: func,
214+
215+
/**
216+
* headless
217+
* The `headless` proper allows for setting whether the Cytoscape instance is headless, i.e.
218+
* not rendered. This value can not be changed after initialisation of the component.
219+
*/
220+
headless: bool,
221+
222+
/**
223+
* styleEnabled
224+
* The `styleEnabled` flag is used to enable style functionality in a headless instance (i.e.
225+
* `headless: true, styleEnabled: true`). For a rendered instance, do not set this value.
226+
*/
227+
styleEnabled: bool,
228+
229+
/**
230+
* hideEdgesOnViewport
231+
* A rendering hint that specifies, for renderers which support the hint, whether edges should
232+
* be hidden during zoom and pan operations.
233+
*/
234+
hideEdgesOnViewport: bool,
235+
236+
/**
237+
* textureOnViewport
238+
* A rendering hint that specifies, for renderers which support the hint, whether a preview
239+
* based on the existing scene should be used in place of building a new scene.
240+
*/
241+
textureOnViewport: bool,
242+
243+
/**
244+
* motionBlur
245+
* A rendering hint that specifies, for renderers which support the hint, whether a motion blur
246+
* effect should be applied.
247+
*/
248+
motionBlur: bool,
249+
250+
/**
251+
* motionBlurOpacity
252+
* A rendering hint that specifies, for renderers which support the hint, how strong the motion
253+
* blur effect should be. The value ranges from 0 to 1, with larger values indicating larger
254+
* strength.
255+
*/
256+
motionBlurOpacity: number,
257+
258+
/**
259+
* wheelSensitivity
260+
* A rendering hint that specifies, for renderers which support the hint, how fast wheel zooming
261+
* should be. The value is a positive multiplier. Do not set this value unless you are using
262+
* unconventional hardware and can guarantee that all your users will use the same hardware. The
263+
* default value works well for standard mice on common operating systems. If you change this
264+
* value, it is very likely that you will create a bad user experience for many or most of your
265+
* users.
266+
*/
267+
wheelSensitivity: number,
268+
269+
/**
270+
* pixelRatio
271+
* A rendering hint that specifies, for renderers which support the hint, the pixel ratio that
272+
* should be used. May be 'auto' or a positive number.
273+
*/
274+
pixelRatio: oneOfType([string, object])
214275
};

test/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<!-- Add refs to test/*.js files here: -->
2929
<script src="component.js"></script>
3030
<script src="immutable-component.js"></script>
31+
<script src="rendering-hints.js"></script>
3132

3233
<script>
3334
mocha.run();

test/rendering-hints.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* global expect, ReactDOM, React, ReactCytoscape, cy */
2+
3+
(function() {
4+
const defaults = {
5+
global: 'cy',
6+
id: 'cy',
7+
style: { width: '500px', height: '500px' },
8+
zoom: 1,
9+
pan: {
10+
x: 0,
11+
y: 0
12+
},
13+
elements: [
14+
{
15+
data: { id: 'a', label: 'apple' },
16+
position: { x: 0, y: 0 },
17+
scratch: { _test: 1 },
18+
classes: 'foo bar'
19+
},
20+
{
21+
data: { id: 'b', label: 'banana' },
22+
position: { x: 0, y: 0 },
23+
scratch: { _test: 2 },
24+
classes: 'foo bar'
25+
},
26+
{
27+
data: { id: 'c', label: 'cherry' },
28+
position: { x: 0, y: 0 },
29+
scratch: { _test: 3 },
30+
classes: 'foo bar'
31+
}
32+
],
33+
stylesheet: [
34+
{
35+
selector: 'node',
36+
style: {
37+
'width': 100
38+
}
39+
}
40+
]
41+
};
42+
43+
const cloneDefaults = () => JSON.parse(JSON.stringify(defaults));
44+
45+
/**
46+
* The TestComponent drives updates to the ReactCytoscape component. Updates
47+
* to the state of the TestComponent trigger updates to the props of
48+
* ReactCytoscape via componentDidUpdate(props).
49+
*/
50+
class TestComponent extends React.Component {
51+
constructor(props) {
52+
super(props);
53+
54+
props.setStateRef(this.setState.bind(this));
55+
56+
this.state = props.defaults;
57+
}
58+
59+
render() {
60+
return React.createElement(ReactCytoscape, this.state);
61+
}
62+
}
63+
64+
describe('Rendering hints', function() {
65+
let root, setState, json;
66+
67+
let updateCyProps = props =>
68+
new Promise(resolve => setState(Object.assign({}, json, props), resolve));
69+
70+
afterEach(function() {
71+
ReactDOM.unmountComponentAtNode(root);
72+
document.body.removeChild(root);
73+
});
74+
75+
let createComponent = props => {
76+
json = Object.assign(cloneDefaults(), props);
77+
78+
root = document.createElement('div');
79+
80+
document.body.appendChild(root);
81+
82+
ReactDOM.render(
83+
React.createElement(TestComponent, {
84+
setStateRef: ref => (setState = ref),
85+
defaults: json
86+
}),
87+
root
88+
);
89+
};
90+
91+
it('allows headless:true', function(){
92+
createComponent({ headless: true });
93+
94+
expect(cy.style()).to.not.exist;
95+
96+
// TODO add another assertion here if/when there is a public getter for headless state
97+
98+
expect(cy.nodes().length).to.equal(3); // sanity check
99+
});
100+
101+
it('allows headless:true styleEnabled:true', function(){
102+
createComponent({ headless: true, styleEnabled: true });
103+
104+
expect(cy.style()).to.exist;
105+
106+
expect(cy.nodes().length).to.equal(3); // sanity check
107+
108+
expect(cy.nodes().first().width()).to.equal(100);
109+
});
110+
});
111+
})();

0 commit comments

Comments
 (0)