Last active
May 11, 2022 07:04
-
-
Save carlhannes/50a9688de3e57dd735a3dc264be18777 to your computer and use it in GitHub Desktop.
React picasso.js rendering area
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect } from 'react'; | |
import picasso from 'picasso.js'; | |
const debounce = (func, wait, immediate = false) => { | |
let timeout; | |
return function debouncedFn(...args) { | |
return new Promise((resolve) => { | |
clearTimeout(timeout); | |
timeout = setTimeout(() => { | |
timeout = null; | |
if (!immediate) { | |
Promise.resolve(func.apply(this, [...args])).then(resolve); | |
} | |
}, wait); | |
if (immediate && !timeout) { | |
Promise.resolve(func.apply(this, [...args])).then(resolve); | |
} | |
}); | |
}; | |
}; | |
const useResize = (ref, callback) => { | |
useEffect(() => { | |
let resizeObserver; | |
if (ref && ref.current) { | |
const debouncer = debounce(callback, 200); | |
resizeObserver = new ResizeObserver((entries) => { | |
// should only be one | |
debouncer(entries[0].contentRect); | |
}); | |
resizeObserver.observe(ref.current); | |
} | |
return () => { | |
if (resizeObserver) { | |
resizeObserver.disconnect(); | |
} | |
}; | |
}, [ref, callback]); | |
}; | |
function PicassoRenderer({ | |
data, settings, style, | |
}) { | |
const element = React.useRef(null); | |
const [chart, setChart] = React.useState(null); | |
React.useEffect(() => { | |
let ch; | |
ch = picasso().chart({ | |
element: element.current, | |
settings, | |
data: undefined, | |
}); | |
setChart(ch); | |
return () => { | |
if (ch) { | |
ch.destroy(); | |
ch = null; | |
} | |
}; | |
}, [settings, element]); | |
React.useEffect(() => { | |
if (!data) { | |
// Data not arrived yet | |
return; | |
} | |
if (chart && chart.update) { | |
chart.update({ data }); | |
} | |
}, [data, chart]); | |
const updateChart = React.useCallback(() => { | |
if (!data) { | |
// Data not arrived yet | |
return; | |
} | |
if (chart && chart.update) { | |
chart.update(); | |
} | |
}, [chart, data]); | |
useResize(element, updateChart); | |
// render | |
return ( | |
<div style={style} ref={element} /> | |
); | |
} | |
export default PicassoRenderer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment