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:
parent
e52a9a4fbf
commit
60d7eba6db
1 changed files with 241 additions and 93 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue