Skip to content

Instantly share code, notes, and snippets.

@cjgunnar
Created January 5, 2022 01:14
Show Gist options
  • Save cjgunnar/851cf2b10e735d1108451313a3eb2613 to your computer and use it in GitHub Desktop.
Save cjgunnar/851cf2b10e735d1108451313a3eb2613 to your computer and use it in GitHub Desktop.
A basic, size-responsive, interactive React plot created with the excellent Plotly library
import Plotly from 'plotly.js-cartesian-dist';
import { useEffect, useMemo, useState } from 'react';
import createPlotlyComponent from 'react-plotly.js/factory';
// use only portion of plotly library necessary
const Plot = createPlotlyComponent(Plotly);
/**
* a simple plot with x and y axis, will completely fill div it's placed in
* @param {Object} props
* @param {Array<Array<number>>} props.data pass in as [xseries, yseries]
* @param {string} props.xLabel label on x axis
* @param {string} props.yLabel label on y axis
* @param {boolean} props.log plot as a loglog plot
* @requires plotly.js-cartesian-dist
* @requires react-plotly.js
*/
export function Chart({data, xLabel, yLabel, log=false}) {
// create data field
const graphData = useMemo(() => [{
x: data[0],
y: data[1],
type: 'scatter',
mode: 'lines'
}], [data]);
// set layout parameters
const layout = useMemo(() => ({
xaxis: {
title: xLabel ?? '',
rangemode: 'tozero',
type: log ? 'log' : 'linear'
},
yaxis: {
title: yLabel ?? '',
rangemode: 'tozero',
type: log ? 'log' : 'linear'
},
autosize: true
}), [xLabel, yLabel, log]);
// create persistent state across redraws
const [plotState, setPlotState] = useState({
layout,
data: graphData,
config: {
responsive: true
},
frames: []
});
useEffect(()=>{
// merge old and new state
setPlotState(prev => ({...prev, data: graphData, layout}))
}, [graphData, layout]);
return (
<div style={{boxSizing: 'border-box'}}>
<Plot
data={plotState.data}
layout={plotState.layout}
config={plotState.config}
frames={plotState.frames}
useResizeHandler
style={{width: '100%', height: '100%', boxSizing: 'border-box'}}
onInitialized={setPlotState}
onUpdate={setPlotState}
/>
</div>
);
}
@cjgunnar
Copy link
Author

cjgunnar commented Jun 16, 2022

Wow didn't know people were finding this. Word of warning: I'm finding bugs relating to this code. I'll post a revision when that gets sorted out. Until then, check out this excellent blog post that does it properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment