99 * OF ANY KIND, either express or implied. See the License for the specific language
1010 * governing permissions and limitations under the License.
1111 */
12- import { useMemo } from 'react' ;
12+ import { useEffect , useMemo , useRef } from 'react' ;
1313
1414import { Data , Spec , ValuesData } from 'vega' ;
1515
1616import { getColorValue } from '@spectrum-charts/themes' ;
17- import { ChartSpecOptions , baseData , buildSpec } from '@spectrum-charts/vega-spec-builder' ;
17+ import { ChartData , ChartSpecOptions , baseData , buildSpec } from '@spectrum-charts/vega-spec-builder' ;
1818
19+ import { Venn } from '../alpha' ;
1920import { rscPropsToSpecBuilderOptions } from '../rscToSbAdapter' ;
20- import { ChartData , SanitizedSpecProps } from '../types' ;
21+ import { SanitizedSpecProps } from '../types' ;
22+ import { chartHasChild } from '../utils' ;
2123
2224export default function useSpec ( {
2325 backgroundColor,
26+ chartHeight,
27+ chartWidth,
2428 children,
2529 colors,
2630 colorScheme,
@@ -38,7 +42,38 @@ export default function useSpec({
3842 title,
3943 UNSAFE_vegaSpec,
4044} : SanitizedSpecProps ) : Spec {
45+ const prevSpec = useRef < Spec | null > ( null ) ;
46+ const hasVenn = useMemo ( ( ) => chartHasChild ( { children, displayName : Venn . displayName as string } ) , [ children ] ) ;
47+
48+ // invalidate cache if changes to props other than width, height change
49+ useEffect ( ( ) => {
50+ prevSpec . current = null ;
51+ } , [
52+ UNSAFE_vegaSpec ,
53+ backgroundColor ,
54+ children ,
55+ colors ,
56+ colorScheme ,
57+ description ,
58+ hiddenSeries ,
59+ highlightedItem ,
60+ highlightedSeries ,
61+ idKey ,
62+ lineTypes ,
63+ lineWidths ,
64+ opacities ,
65+ symbolShapes ,
66+ symbolSizes ,
67+ title ,
68+ data ,
69+ ] ) ;
70+
4171 return useMemo ( ( ) => {
72+ // returned cached spec if there is a cached spec and if venn is not a child element
73+ if ( ! hasVenn && prevSpec . current !== null ) {
74+ return prevSpec . current ;
75+ }
76+
4277 // They already supplied a spec, fill it in with defaults
4378 if ( UNSAFE_vegaSpec ) {
4479 const vegaSpecWithDefaults = initializeSpec ( UNSAFE_vegaSpec , {
@@ -50,15 +85,20 @@ export default function useSpec({
5085 } ) ;
5186
5287 // copy the spec so we don't mutate the original
53- return JSON . parse ( JSON . stringify ( vegaSpecWithDefaults ) ) ;
88+ const spec = JSON . parse ( JSON . stringify ( vegaSpecWithDefaults ) ) ;
89+ prevSpec . current = spec ;
90+ return spec ;
5491 }
5592
5693 // or we need to build their spec
5794 const chartOptions = rscPropsToSpecBuilderOptions ( {
5895 backgroundColor,
96+ chartHeight,
97+ chartWidth,
5998 children,
6099 colors,
61100 colorScheme,
101+ data,
62102 description,
63103 hiddenSeries,
64104 highlightedItem,
@@ -73,7 +113,10 @@ export default function useSpec({
73113 } ) ;
74114
75115 // stringify-parse so that all immer stuff gets cleared out
76- return buildSpec ( chartOptions ) ;
116+ const spec = buildSpec ( chartOptions ) ;
117+ prevSpec . current = spec ;
118+
119+ return spec ;
77120 } , [
78121 UNSAFE_vegaSpec ,
79122 backgroundColor ,
@@ -92,6 +135,9 @@ export default function useSpec({
92135 symbolSizes ,
93136 title ,
94137 data ,
138+ chartHeight ,
139+ chartWidth ,
140+ hasVenn ,
95141 ] ) ;
96142}
97143
0 commit comments