Following is the code I'm using to return the Plotly graph, What I need to do in here is I need to return a message or different layout when the graph data is empty or there is nothing to show on the graph. use a default content like no data available if no data for charts. How do I do that?
import React, { useEffect } from "react";
import Plot from "react-plotly.js";
import PropTypes from "prop-types";
let dataArray;
let index;
let obj;
function PlotlyStackedChart({ labels, data, xTitle, yTitle, mainTitle, preHeading }) {
useEffect(() => {
dataArray = [];
for (index = 0; index < data.length; index = 1) {
obj = {
x: labels,
y: data[index].data,
type: "bar",
name: data[index].name,
};
dataArray.push(obj);
}
}, [data]);
return (
<>
<Plot
data={dataArray}
layout={{
barmode: "stack",
autosize: true,
title: {
text: preHeading mainTitle,
y: 0.9,
},
margin: {
t: 225,
},
xaxis: {
// all "layout.xaxis" attributes: #layout-xaxis
title: {
text: xTitle,
font: {
family: "Arial Black",
},
}, // more about "layout.xaxis.title": #layout-xaxis-title
// dtick: 1,
},
yaxis: {
// all "layout.yaxis" attributes: #layout-yaxis
title: {
text: yTitle,
font: {
family: "Arial Black",
},
}, // more about "layout.yaxis.title": #layout-yaxis-title
},
font: {
// family: "Courier New, monospace",
size: 12,
color: "#7f7f7f",
},
legend: {
bgcolor: "transparent",
x: 0,
y: 1.4,
xanchor: "auto",
traceorder: "normal",
orientation: "h",
},
marker: { size: 40 },
}}
useResizeHandler
style={{ width: "100%", height: 600 }}
/>
</>
);
}
export default PlotlyStackedChart;
PlotlyStackedChart.defaultProps = {
xTitle: "",
yTitle: "",
mainTitle: "",
preHeading: "",
};
// Typechecking props for the MDDatePicker
PlotlyStackedChart.propTypes = {
labels: PropTypes.oneOfType([PropTypes.string, PropTypes.array]).isRequired,
xTitle: PropTypes.string,
yTitle: PropTypes.string,
mainTitle: PropTypes.string,
preHeading: PropTypes.string,
data: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.object]).isRequired,
};
explaining further, If there is no data to plot in the graph I want to return the following code else the current one which retrieves the data and plot in the graph.
return {
"layout": {
"xaxis": {
"visible": false
},
"yaxis": {
"visible": false
},
"annotations": [
{
"text": "No matching data found",
"xref": "paper",
"yref": "paper",
"showarrow": false,
"font": {
"size": 28
}
}
]
}
}
CodePudding user response:
You can try returning the empty content template if there is no content.
import React, { useEffect } from "react";
import Plot from "react-plotly.js";
import PropTypes from "prop-types";
let dataArray;
let index;
let obj;
function PlotlyStackedChart({ labels, data, xTitle, yTitle, mainTitle, preHeading }) {
useEffect(() => {
if(data?.length){ // <--- place condition here
dataArray = [];
for (index = 0; index < data.length; index = 1) {
obj = {
x: labels,
y: data[index].data,
type: "bar",
name: data[index].name,
};
dataArray.push(obj);
}
}
}, [data]);
// Place this conditional return
if(!data?.length) {
return <>No data found</>
}
return (
<>
<Plot
data={dataArray}
layout={{
barmode: "stack",
autosize: true,
title: {
text: preHeading mainTitle,
y: 0.9,
},
margin: {
t: 225,
},
xaxis: {
// all "layout.xaxis" attributes: #layout-xaxis
title: {
text: xTitle,
font: {
family: "Arial Black",
},
}, // more about "layout.xaxis.title": #layout-xaxis-title
// dtick: 1,
},
yaxis: {
// all "layout.yaxis" attributes: #layout-yaxis
title: {
text: yTitle,
font: {
family: "Arial Black",
},
}, // more about "layout.yaxis.title": #layout-yaxis-title
},
font: {
// family: "Courier New, monospace",
size: 12,
color: "#7f7f7f",
},
legend: {
bgcolor: "transparent",
x: 0,
y: 1.4,
xanchor: "auto",
traceorder: "normal",
orientation: "h",
},
marker: { size: 40 },
}}
useResizeHandler
style={{ width: "100%", height: 600 }}
/>
</>
);
}
export default PlotlyStackedChart;
CodePudding user response:
useEffect is entirely irrelevant to the problem you describe.
If you want to render something different when the array is empty, then do it in the render logic, not as an effect.
if (data.length === 0) {
return <Loading />
} else {
return <Plot .../>
}
That said, your effect logic is broken. You can't just assign a new array to a variable and have React render it. You've done nothing to tell React that it needs to do a re-render. Make data a state variable (with useState).
