Merge branch 'dev_environment' of gitlab.com:brandx/bxt-app into dev_environment

This commit is contained in:
Carter 2025-03-11 13:35:43 -06:00
commit 8df5b5e602

View file

@ -125,6 +125,43 @@ interface GrainNodePoint {
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) {
const classes = useStyles();
const {
@ -399,6 +436,20 @@ export default function BinSVGV2(props: Props) {
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 = () => {
if (!cables) return;
//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 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 nodes: React.SVGProps<SVGCircleElement | SVGRectElement | SVGElement>[] = [];
let temps: React.SVGProps<SVGTextElement>[] = [];
let hums: React.SVGProps<SVGTextElement>[] = [];
let nodeClickers: React.SVGProps<SVGCircleElement>[] = [];
//let nodeHeatMap: React.SVGProps<SVGEllipseElement>[] = [];
let nodeHeatMapData: EllipseData[] = [];
//let nodes: React.SVGProps<SVGCircleElement | SVGRectElement | SVGElement>[] = [];
let nodesData: NodeData[] = [];
//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) => {
//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 (cable.topNode > 0) {
if (nodeNumber <= cable.topNode) {
nodeHeatMap.push(
<ellipse
key={index}
cx={cablePos}
cy={nodeY}
rx="120"
ry="60"
fill={getGrainGradient(temp)}
/>
);
// nodeHeatMap.push(
// <ellipse
// key={index}
// cx={cablePos}
// cy={nodeY}
// rx="120"
// ry="60"
// fill={getGrainGradient(temp)}
// />
// );
nodeHeatMapData.push({
key: index,
xCenter: cablePos,
yCenter: nodeY,
xRadius: "120",
yRadius: "60",
fillColour: getGrainGradient(temp)
})
}
} else if (nodeY > filledToY) {
//otherwise use the fill level of the bin
nodeHeatMap.push(
<ellipse
key={index}
cx={cablePos}
cy={nodeY}
rx="120"
ry="60"
fill={getGrainGradient(temp)}
/>
);
// nodeHeatMap.push(
// <ellipse
// key={index}
// cx={cablePos}
// cy={nodeY}
// rx="120"
// ry="60"
// fill={getGrainGradient(temp)}
// />
// );
nodeHeatMapData.push({
key: index,
xCenter: cablePos,
yCenter: nodeY,
xRadius: "120",
yRadius: "60",
fillColour: getGrainGradient(temp)
})
}
const displayWidth = 90;
const displayHeight = 45;
const cornerRad = 10;
//add the boxes to display the temps in fulscreen view
nodes.push(
showTempHum ? (
<rect
key={"node" + index}
x={cablePos - displayWidth / 2}
y={nodeY - displayHeight / 2}
width={displayWidth}
height={displayHeight}
rx={cornerRad}
className={classes.cableNode}></rect>
) : (
<g key={"node" + index}>
{nodeNumber === topNode && topNodeHat(cablePos, nodeY)}
<circle cx={cablePos} cy={nodeY} className={nodeClass(temp)} r="16"></circle>
</g>
)
);
// nodes.push(
// showTempHum ? (
// <rect
// key={"node" + index}
// x={cablePos - displayWidth / 2}
// y={nodeY - displayHeight / 2}
// width={displayWidth}
// height={displayHeight}
// rx={cornerRad}
// className={classes.cableNode}></rect>
// ) : (
// <g key={"node" + index}>
// {nodeNumber === topNode && topNodeHat(cablePos, nodeY)}
// <circle cx={cablePos} cy={nodeY} className={nodeClass(temp)} r="16"></circle>
// </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(
<text
filter="drop-shadow( 4px 4px 10px rgba(0, 0, 0, .7))"
key={"node" + index + "temp"}
x={cablePos}
y={nodeY + 10}
stroke="blue"
className={classes.tempHum}>
{displayTemp.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>
);
// temps.push(
// <text
// key={"node" + index + "temp"}
// x={cablePos}
// y={nodeY + 10}
// stroke="blue"
// filter="drop-shadow( 4px 4px 10px rgba(0, 0, 0, .7))"
// className={classes.tempHum}>
// {displayTemp.toFixed(1)}°
// </text>
// );
tempData.push({
key: "node" + index + "temp",
x: cablePos,
y: nodeY + 10,
stroke: "blue",
value: displayTemp.toFixed(1) +"°",
filter: "drop-shadow( 4px 4px 10px rgba(0, 0, 0, .7))"
})
// 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 &&
nodeClickers.push(
<circle
key={"node" + index}
onClick={() => {
if (cable.key() !== "" && cableNodeClicked) {
cableNodeClicked(cable, nodeNumber);
}
}}
cx={cablePos}
cy={nodeY}
className={classes.clickableArea}
r="50"
/>
);
// nodeClickers.push(
// <circle
// key={"node" + index}
// 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) {
cableNodeClicked(cable, nodeNumber);
}
}
})
//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) {
@ -617,22 +727,60 @@ export default function BinSVGV2(props: Props) {
numNodes--;
});
// cableLines.push(
// <g key={"cable" + cableIndex} id={"cable " + cableIndex} data-name={"cable " + cableIndex}>
// {nodeHeatMap}
// <line
// stroke={cableCol}
// x1={cablePos}
// y1={topY}
// x2={cablePos}
// y2={bottomY}
// className={classes.cableLine}
// />
// {nodes}
// {showTempHum && (extraDetails === "temps" ? temps : hums)}
// {nodeClickers}
// </g>
// );
cableLines.push(
<g key={"cable" + cableIndex} id={"cable " + cableIndex} data-name={"cable " + cableIndex}>
{nodeHeatMapData.map(e => (
<ellipse
key={e.key}
cx={e.xCenter}
cy={e.yCenter}
rx={e.xRadius}
ry={e.yRadius}
fill={e.fillColour}
/>
))}
<line
stroke={cableCol}
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
if (cableGrainEndY === 0) {