canvasxpress-react 65.5.0 → 65.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/index.d.ts +16 -6
- package/index.js +66 -49
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -62,6 +62,29 @@ var reactapp = document.createElement("div");
|
|
|
62
62
|
document.body.appendChild(reactapp);
|
|
63
63
|
ReactDOM.render(<Bar />, reactapp)
|
|
64
64
|
```
|
|
65
|
+
Notes
|
|
66
|
+
-----------------
|
|
67
|
+
|
|
68
|
+
- Requires **React 16.8+** (the component is implemented with hooks).
|
|
69
|
+
- `target` is **optional** — the component renders through an internal ref, so you
|
|
70
|
+
no longer need to supply a globally unique DOM id. If you do pass `target`, it is
|
|
71
|
+
applied as the `<canvas>` id.
|
|
72
|
+
- The live CanvasXpress instance is available two ways: the `onRef` callback (fired
|
|
73
|
+
with the instance on mount and `undefined` on unmount), or a forwarded `ref`
|
|
74
|
+
(`ref.current` is the instance; `ref.current.graph` also resolves for backward
|
|
75
|
+
compatibility):
|
|
76
|
+
|
|
77
|
+
```jsx
|
|
78
|
+
import React, { useRef } from 'react';
|
|
79
|
+
import CanvasXpressReact from 'canvasxpress-react';
|
|
80
|
+
|
|
81
|
+
function Chart(props) {
|
|
82
|
+
const cx = useRef(null);
|
|
83
|
+
// cx.current is the CanvasXpress instance after mount
|
|
84
|
+
return <CanvasXpressReact ref={cx} data={props.data} config={props.config} />;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
65
88
|
Alternative Used
|
|
66
89
|
-----------------
|
|
67
90
|
|
package/index.d.ts
CHANGED
|
@@ -8,8 +8,9 @@ import * as CanvasXpress from 'canvasxpress';
|
|
|
8
8
|
export = CanvasXpressReact;
|
|
9
9
|
|
|
10
10
|
interface CanvasXpressReactProps {
|
|
11
|
-
/** DOM id
|
|
12
|
-
|
|
11
|
+
/** DOM id applied to the rendered <canvas> (optional; the component uses an
|
|
12
|
+
* internal ref, so a unique id is no longer required). */
|
|
13
|
+
target?: string;
|
|
13
14
|
/** CanvasXpress data object. */
|
|
14
15
|
data?: CanvasXpress.CXData;
|
|
15
16
|
/** CanvasXpress configuration. */
|
|
@@ -28,7 +29,16 @@ interface CanvasXpressReactProps {
|
|
|
28
29
|
onRef?: (instance: CanvasXpress.CanvasXpressInstance | undefined) => void;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
/**
|
|
33
|
+
* The value resolved by a forwarded `ref`: the live CanvasXpress instance,
|
|
34
|
+
* carrying a `graph` self-alias for backward compatibility with code that read
|
|
35
|
+
* `ref.current.graph` off the previous class component.
|
|
36
|
+
*/
|
|
37
|
+
type CanvasXpressReactHandle = CanvasXpress.CanvasXpressInstance & {
|
|
38
|
+
/** Self-reference to the CanvasXpress instance (legacy accessor). */
|
|
39
|
+
graph: CanvasXpress.CanvasXpressInstance;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
declare const CanvasXpressReact: React.ForwardRefExoticComponent<
|
|
43
|
+
CanvasXpressReactProps & React.RefAttributes<CanvasXpressReactHandle>
|
|
44
|
+
>;
|
package/index.js
CHANGED
|
@@ -2,71 +2,88 @@ var React = require('react');
|
|
|
2
2
|
var CanvasXpress = require('canvasxpress');
|
|
3
3
|
require('canvasxpress/src/canvasXpress.css');
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
//Hooks-based wrapper (requires React >= 16.8). The previous release shipped a
|
|
6
|
+
//class component; the public surface is unchanged: the same props are accepted,
|
|
7
|
+
//onRef(instance) still fires on mount/unmount, and a forwarded ref now resolves
|
|
8
|
+
//to the live CanvasXpress instance (with a .graph self-alias, so the old
|
|
9
|
+
//ref.current.graph access keeps working).
|
|
10
|
+
var CanvasXpressReact = React.forwardRef(function CanvasXpressReact(props, ref) {
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
this.events = props.events ? props.events : false;
|
|
13
|
-
this.width = props.width ? props.width : 500;
|
|
14
|
-
this.height = props.height ? props.height : 500;
|
|
15
|
-
this.responsive = props.responsive ? props.responsive : false;
|
|
16
|
-
this.aspectRatio = props.aspectratio ? props.aspectratio : "1:1";
|
|
17
|
-
}
|
|
12
|
+
//A ref to the <canvas> node replaces the old required-unique `target` id, so
|
|
13
|
+
//two components can no longer collide on a shared DOM id. `target`, if passed,
|
|
14
|
+
//is still applied as the canvas id for backward compatibility.
|
|
15
|
+
var canvasRef = React.useRef(null);
|
|
16
|
+
var graphRef = React.useRef(null);
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
//Expose the live instance through the forwarded ref, and mirror the legacy
|
|
19
|
+
//ref.current.graph accessor onto the instance itself (the engine never reads
|
|
20
|
+
//`.graph`, so this alias is inert).
|
|
21
|
+
React.useImperativeHandle(ref, function () {
|
|
22
|
+
var instance = graphRef.current;
|
|
23
|
+
if (instance && !instance.graph) {
|
|
24
|
+
instance.graph = instance;
|
|
24
25
|
}
|
|
25
|
-
|
|
26
|
+
return instance;
|
|
27
|
+
});
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
//Mount / unmount. Empty dependency list: build the graph once, tear it down on
|
|
30
|
+
//unmount. Data/config/event updates are handled by the effect below.
|
|
31
|
+
React.useEffect(function () {
|
|
32
|
+
graphRef.current = new CanvasXpress.init(
|
|
33
|
+
canvasRef.current,
|
|
34
|
+
props.data ? props.data : false,
|
|
35
|
+
props.config ? props.config : false,
|
|
36
|
+
props.events ? props.events : false
|
|
37
|
+
);
|
|
38
|
+
if (props.onRef) {
|
|
39
|
+
props.onRef(graphRef.current);
|
|
40
|
+
}
|
|
41
|
+
return function () {
|
|
42
|
+
if (graphRef.current) {
|
|
43
|
+
graphRef.current.destroy();
|
|
44
|
+
graphRef.current = null;
|
|
45
|
+
}
|
|
46
|
+
if (props.onRef) {
|
|
47
|
+
props.onRef(undefined);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
|
+
}, []);
|
|
35
52
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
//Re-apply data, config, and events whenever any of them change. The class
|
|
54
|
+
//component only refreshed data/config; events are now re-bound too (the engine
|
|
55
|
+
//reads handlers off instance.events).
|
|
56
|
+
React.useEffect(function () {
|
|
57
|
+
var graph = graphRef.current;
|
|
58
|
+
if (!graph) {
|
|
39
59
|
return;
|
|
40
60
|
}
|
|
61
|
+
graph.events = props.events ? props.events : false;
|
|
41
62
|
//resetConfig()/updateConfig() land in canvasxpress >= 65.4. Guard so an
|
|
42
63
|
//older library falls back to updateData's config-merge path instead of
|
|
43
64
|
//throwing on a missing method.
|
|
44
|
-
if (typeof
|
|
45
|
-
|
|
65
|
+
if (typeof graph.resetConfig === 'function' && typeof graph.updateConfig === 'function') {
|
|
66
|
+
graph.resetConfig();
|
|
46
67
|
//Second arg (n) = "do not draw": defer the redraw so only updateData below
|
|
47
68
|
//paints, avoiding a double render.
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
graph.updateConfig(props.config, true);
|
|
70
|
+
graph.updateData(props.data);
|
|
50
71
|
} else {
|
|
51
72
|
//Fallback: apply config alongside the data in a single redraw.
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
componentWillUnmount() {
|
|
57
|
-
//Destroy graph and remove reference
|
|
58
|
-
if (this.graph) {
|
|
59
|
-
this.graph.destroy();
|
|
60
|
-
}
|
|
61
|
-
if (this.props.onRef) {
|
|
62
|
-
this.props.onRef(undefined);
|
|
73
|
+
graph.updateData(props.data, true, false, props.config);
|
|
63
74
|
}
|
|
64
|
-
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [props.data, props.config, props.events]);
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
return React.createElement('canvas', {
|
|
79
|
+
ref: canvasRef,
|
|
80
|
+
id: props.target ? props.target : undefined,
|
|
81
|
+
width: props.width ? props.width : 500,
|
|
82
|
+
height: props.height ? props.height : 500,
|
|
83
|
+
'data-responsive': props.responsive ? props.responsive : false,
|
|
84
|
+
'data-aspectratio': props.aspectratio ? props.aspectratio : "1:1"
|
|
85
|
+
});
|
|
69
86
|
|
|
70
|
-
}
|
|
87
|
+
});
|
|
71
88
|
|
|
72
89
|
module.exports = CanvasXpressReact;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"main": "index.js",
|
|
4
4
|
"types": "index.d.ts",
|
|
5
5
|
"title": "CanvasXpress React",
|
|
6
|
-
"version": "65.
|
|
6
|
+
"version": "65.7.1",
|
|
7
7
|
"license": {
|
|
8
8
|
"type": "Dual licensing",
|
|
9
9
|
"url": "https://www.canvasxpress.org/docs/license.html"
|
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/neuhausi/canvasxpress#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"canvasxpress": "^65.
|
|
32
|
+
"canvasxpress": "^65.7.1"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": ">=16.8.0"
|
|
33
36
|
}
|
|
34
37
|
}
|