Merge branch 'dev_environment' of gitlab.com:brandx/bxt-app into dev_environment
This commit is contained in:
commit
8df5b5e602
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) {
|
// if (cable.key() !== "" && cableNodeClicked) {
|
||||||
cableNodeClicked(cable, nodeNumber);
|
// cableNodeClicked(cable, nodeNumber);
|
||||||
}
|
// }
|
||||||
}}
|
// }}
|
||||||
cx={cablePos}
|
// cx={cablePos}
|
||||||
cy={nodeY}
|
// cy={nodeY}
|
||||||
className={classes.clickableArea}
|
// className={classes.clickableArea}
|
||||||
r="50"
|
// 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 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