fixed svg by creating data arrays rahter than the react svg component arrays and then mapping those arrays out to svg tags, apparently it didn't like having mutliple react children

This commit is contained in:
csawatzky 2025-03-11 13:15:58 -06:00
parent e52a9a4fbf
commit 60d7eba6db

View file

@ -125,6 +125,43 @@ interface GrainNodePoint {
y: number; y: number;
} }
interface EllipseData {
key: string | number;
xCenter: string | number;
yCenter: string | number;
xRadius: string | number;
yRadius: string | number;
fillColour: string;
}
interface NodeData { //this could be either a box or a circle depending
key: string | number
x: number;
y: number
width: string | number
height: string | number
borderRad: string | number
nodeNumber: number
nodeTemp: number
}
interface CircleData {
key: string | number
centerX: string | number
centerY: string | number
radius: string | number
onClick?: () => void
}
interface TextData {
key: number | string,
x: number,
y: number,
stroke: string,
filter?: string,
value: string
}
export default function BinSVGV2(props: Props) { export default function BinSVGV2(props: Props) {
const classes = useStyles(); const classes = useStyles();
const { const {
@ -399,6 +436,20 @@ export default function BinSVGV2(props: Props) {
return classes.cableNode; return classes.cableNode;
}; };
const renderText = (text: TextData[]) => {
return text.map(text => (
<text
key={text.key}
x={text.x}
y={text.y}
stroke={text.stroke}
filter={text.filter}
className={classes.tempHum}>
{text.value}
</text>
))
}
const multiCables = () => { const multiCables = () => {
if (!cables) return; if (!cables) return;
//sort the cables by node number so the one with the most nodes is in the middle //sort the cables by node number so the one with the most nodes is in the middle
@ -478,11 +529,17 @@ export default function BinSVGV2(props: Props) {
const filledToY = (fillPercentage * (minNodeY - maxNodeY)) / 100 + maxNodeY; const filledToY = (fillPercentage * (minNodeY - maxNodeY)) / 100 + maxNodeY;
const nodeSpacingY = (maxNodeY - minNodeY) / (cable.temperatures.length + 1); //removing the +1 here would place the nodes starting at the bottom of the cable line rather than from the center const nodeSpacingY = (maxNodeY - minNodeY) / (cable.temperatures.length + 1); //removing the +1 here would place the nodes starting at the bottom of the cable line rather than from the center
let nodeHeatMap: React.SVGProps<SVGEllipseElement>[] = []; //let nodeHeatMap: React.SVGProps<SVGEllipseElement>[] = [];
let nodes: React.SVGProps<SVGCircleElement | SVGRectElement | SVGElement>[] = []; let nodeHeatMapData: EllipseData[] = [];
let temps: React.SVGProps<SVGTextElement>[] = []; //let nodes: React.SVGProps<SVGCircleElement | SVGRectElement | SVGElement>[] = [];
let hums: React.SVGProps<SVGTextElement>[] = []; let nodesData: NodeData[] = [];
let nodeClickers: React.SVGProps<SVGCircleElement>[] = [];
//let temps: React.SVGProps<SVGTextElement>[] = [];
let tempData: TextData[] = []
//let hums: React.SVGProps<SVGTextElement>[] = [];
let humData: TextData[] = [];
//let nodeClickers: React.SVGProps<SVGCircleElement>[] = [];
let nodeClickData: CircleData[] = [];
cable.temperatures.forEach((temp, index) => { cable.temperatures.forEach((temp, index) => {
//since the array goes from the top down set the nodeNumber we are currently working with to be the number of nodes we have left //since the array goes from the top down set the nodeNumber we are currently working with to be the number of nodes we have left
@ -509,88 +566,141 @@ export default function BinSVGV2(props: Props) {
//if we are using the auto top nodes only show the heatmap for nodes at or below the top node //if we are using the auto top nodes only show the heatmap for nodes at or below the top node
if (cable.topNode > 0) { if (cable.topNode > 0) {
if (nodeNumber <= cable.topNode) { if (nodeNumber <= cable.topNode) {
nodeHeatMap.push( // nodeHeatMap.push(
<ellipse // <ellipse
key={index} // key={index}
cx={cablePos} // cx={cablePos}
cy={nodeY} // cy={nodeY}
rx="120" // rx="120"
ry="60" // ry="60"
fill={getGrainGradient(temp)} // fill={getGrainGradient(temp)}
/> // />
); // );
nodeHeatMapData.push({
key: index,
xCenter: cablePos,
yCenter: nodeY,
xRadius: "120",
yRadius: "60",
fillColour: getGrainGradient(temp)
})
} }
} else if (nodeY > filledToY) { } else if (nodeY > filledToY) {
//otherwise use the fill level of the bin //otherwise use the fill level of the bin
nodeHeatMap.push( // nodeHeatMap.push(
<ellipse // <ellipse
key={index} // key={index}
cx={cablePos} // cx={cablePos}
cy={nodeY} // cy={nodeY}
rx="120" // rx="120"
ry="60" // ry="60"
fill={getGrainGradient(temp)} // fill={getGrainGradient(temp)}
/> // />
); // );
nodeHeatMapData.push({
key: index,
xCenter: cablePos,
yCenter: nodeY,
xRadius: "120",
yRadius: "60",
fillColour: getGrainGradient(temp)
})
} }
const displayWidth = 90; const displayWidth = 90;
const displayHeight = 45; const displayHeight = 45;
const cornerRad = 10; const cornerRad = 10;
//add the boxes to display the temps in fulscreen view //add the boxes to display the temps in fulscreen view
nodes.push( // nodes.push(
showTempHum ? ( // showTempHum ? (
<rect // <rect
key={"node" + index} // key={"node" + index}
x={cablePos - displayWidth / 2} // x={cablePos - displayWidth / 2}
y={nodeY - displayHeight / 2} // y={nodeY - displayHeight / 2}
width={displayWidth} // width={displayWidth}
height={displayHeight} // height={displayHeight}
rx={cornerRad} // rx={cornerRad}
className={classes.cableNode}></rect> // className={classes.cableNode}></rect>
) : ( // ) : (
<g key={"node" + index}> // <g key={"node" + index}>
{nodeNumber === topNode && topNodeHat(cablePos, nodeY)} // {nodeNumber === topNode && topNodeHat(cablePos, nodeY)}
<circle cx={cablePos} cy={nodeY} className={nodeClass(temp)} r="16"></circle> // <circle cx={cablePos} cy={nodeY} className={nodeClass(temp)} r="16"></circle>
</g> // </g>
) // )
); // );
//if showTempHum is true will render as a box otherwise will render as a circle which is why the x,y, and radius values will be different
nodesData.push({
key: "node" + index,
x: showTempHum ? cablePos - displayWidth / 2 : cablePos,
y: showTempHum ? nodeY - displayHeight / 2 : nodeY,
height: displayHeight,
width: displayWidth,
borderRad: showTempHum ? cornerRad : "16",
nodeNumber: nodeNumber,
nodeTemp: temp
})
temps.push( // temps.push(
<text // <text
filter="drop-shadow( 4px 4px 10px rgba(0, 0, 0, .7))" // key={"node" + index + "temp"}
key={"node" + index + "temp"} // x={cablePos}
x={cablePos} // y={nodeY + 10}
y={nodeY + 10} // stroke="blue"
stroke="blue" // filter="drop-shadow( 4px 4px 10px rgba(0, 0, 0, .7))"
className={classes.tempHum}> // className={classes.tempHum}>
{displayTemp.toFixed(1)}° // {displayTemp.toFixed(1)}°
</text> // </text>
); // );
hums.push( tempData.push({
<text key: "node" + index + "temp",
key={"node" + index + "hum"} x: cablePos,
x={cablePos} y: nodeY + 10,
y={nodeY + 10} stroke: "blue",
stroke="green" value: displayTemp.toFixed(1) +"°",
className={classes.tempHum}> filter: "drop-shadow( 4px 4px 10px rgba(0, 0, 0, .7))"
{ExtractMoisture(props.grainType, temp, cable.humidities[index] ?? 0).toFixed(1)}% })
</text> // hums.push(
); // <text
// key={"node" + index + "hum"}
// x={cablePos}
// y={nodeY + 10}
// stroke="green"
// className={classes.tempHum}>
// {ExtractMoisture(props.grainType, temp, cable.humidities[index] ?? 0).toFixed(1)}%
// </text>
// );
humData.push({
key: "node" + index + "hum",
x: cablePos,
y: nodeY + 10,
stroke: "green",
value: ExtractMoisture(props.grainType, temp, cable.humidities[index] ?? 0).toFixed(1)+"%",
})
!showTempHum && !showTempHum &&
nodeClickers.push( // nodeClickers.push(
<circle // <circle
key={"node" + index} // key={"node" + index}
onClick={() => { // onClick={() => {
// if (cable.key() !== "" && cableNodeClicked) {
// cableNodeClicked(cable, nodeNumber);
// }
// }}
// cx={cablePos}
// cy={nodeY}
// className={classes.clickableArea}
// r="50"
// />
// );
nodeClickData.push({
key: "node"+index,
centerX: cablePos,
centerY: nodeY,
radius: "50",
onClick: () => {
if (cable.key() !== "" && cableNodeClicked) { if (cable.key() !== "" && cableNodeClicked) {
cableNodeClicked(cable, nodeNumber); cableNodeClicked(cable, nodeNumber);
} }
}} }
cx={cablePos} })
cy={nodeY}
className={classes.clickableArea}
r="50"
/>
);
//if the current node is the top node of the cable use its x and y to add to the cable grain path //if the current node is the top node of the cable use its x and y to add to the cable grain path
if (nodeNumber === topNode) { if (nodeNumber === topNode) {
@ -617,22 +727,60 @@ export default function BinSVGV2(props: Props) {
numNodes--; numNodes--;
}); });
// cableLines.push( cableLines.push(
// <g key={"cable" + cableIndex} id={"cable " + cableIndex} data-name={"cable " + cableIndex}> <g key={"cable" + cableIndex} id={"cable " + cableIndex} data-name={"cable " + cableIndex}>
// {nodeHeatMap} {nodeHeatMapData.map(e => (
// <line <ellipse
// stroke={cableCol} key={e.key}
// x1={cablePos} cx={e.xCenter}
// y1={topY} cy={e.yCenter}
// x2={cablePos} rx={e.xRadius}
// y2={bottomY} ry={e.yRadius}
// className={classes.cableLine} fill={e.fillColour}
// /> />
// {nodes} ))}
// {showTempHum && (extraDetails === "temps" ? temps : hums)} <line
// {nodeClickers} stroke={cableCol}
// </g> x1={cablePos}
// ); y1={topY}
x2={cablePos}
y2={bottomY}
className={classes.cableLine}
/>
{nodesData.map(e => {
if (showTempHum) {
return (
<rect
key={e.key}
x={e.x}
y={e.y}
width={e.width}
height={e.height}
rx={e.borderRad}
className={classes.cableNode}/>
)
} else {
return (
<g key={e.key}>
{e.nodeNumber === topNode && topNodeHat(cablePos, e.y)}
<circle cx={cablePos} cy={e.y} className={nodeClass(e.nodeTemp)} r="16"></circle>
</g>
)
}
})}
{showTempHum && (extraDetails === "temps" ? renderText(tempData) : renderText(humData))}
{nodeClickData.map((e) => (
<circle
key={e.key}
onClick={e.onClick}
cx={e.centerX}
cy={e.centerY}
className={classes.clickableArea}
r={e.radius}
/>
))}
</g>
);
}); });
//for single cable bins the endY would still be 0 so just make it the startY to draw a straight line across the bin //for single cable bins the endY would still be 0 so just make it the startY to draw a straight line across the bin
if (cableGrainEndY === 0) { if (cableGrainEndY === 0) {