frontend/farm_designer/map/profile/plants_and_weeds.tsx
import React from "react";
import { TaggedWeedPointer } from "farmbot";
import { PlantPointState, ProfilePointProps } from "./interfaces";
import { Color } from "../../../ui";
import { defaultSpreadCmDia, scaleIcon } from "../util";
import { svgToUrl } from "../../../open_farm/icons";
import { TaggedPlant } from "../interfaces";
import { cachedCrop } from "../../../open_farm/cached_crop";
import { BooleanSetting } from "../../../session_keys";
import { FilePath } from "../../../internal_urls";
/** Plant point profile. */
export class PlantPoint
extends React.Component<ProfilePointProps<TaggedPlant>, PlantPointState> {
state: PlantPointState = {
icon: FilePath.DEFAULT_ICON,
spreadDiaCm: defaultSpreadCmDia(this.props.point.body.radius),
};
componentDidMount() {
cachedCrop(this.props.point.body.openfarm_slug)
.then(({ svg_icon, spread }) =>
this.setState({ icon: svgToUrl(svg_icon), spreadDiaCm: spread || 0 }));
}
render() {
const { point, getX, soilHeight, getConfigValue, designer } = this.props;
const { icon, spreadDiaCm } = this.state;
const currentPlantUuid = designer.selectedPoints?.[0];
const radius = point.uuid == currentPlantUuid && designer.hoveredSpread
? designer.hoveredSpread / 2
: point.body.radius;
const plantIconSize = scaleIcon(radius) * 2;
const spreadRadius = (spreadDiaCm || defaultSpreadCmDia(radius)) / 2 * 10;
const profileX = getX(point.body);
const profileY = point.body.z == 0 ? soilHeight : point.body.z;
const depth = point.kind == "Point"
? point.body.depth
: 0;
return <g id={"plant-profile-point"}>
<defs>
<radialGradient id={"plant-radius-gradient"}>
<stop offset="90%" stopColor={Color.darkGreen} stopOpacity={0.1} />
<stop offset="100%" stopColor={Color.darkGreen} stopOpacity={0} />
</radialGradient>
</defs>
<clipPath id={`plant-radius-clip-path-${point.uuid}`}>
<rect
x={profileX - radius}
y={profileY - radius}
height={radius}
width={radius * 2} />
</clipPath>
<clipPath id={`spread-clip-path-${point.uuid}`}>
<rect
x={profileX - spreadRadius - 2}
y={profileY - spreadRadius - 2}
height={spreadRadius + 2}
width={(spreadRadius + 2) * 2} />
</clipPath>
<circle className={"plant-radius"} stroke={"none"}
clipPath={`url(#plant-radius-clip-path-${point.uuid})`}
cx={profileX} cy={profileY} r={radius}
fill={"url(#plant-radius-gradient)"} />
<g id={"plant-icon"}>
<image className={"plant-image"}
xlinkHref={icon}
x={profileX - plantIconSize / 2}
y={profileY - plantIconSize}
height={plantIconSize}
width={plantIconSize} />
</g>
{getConfigValue(BooleanSetting.show_spread) &&
<circle className={"spread"} id={"spread-profile"} strokeWidth={2}
cx={profileX} cy={profileY} r={spreadRadius}
clipPath={`url(#spread-clip-path-${point.uuid})`}
stroke={spreadDiaCm ? Color.darkGreen : Color.gray}
opacity={0.5} fill={"none"} />}
<circle id={"point-coordinate-indicator"} opacity={0.5}
fill={Color.darkGreen} cx={profileX} cy={profileY} r={5} />
<line id={"point-depth-indicator"} opacity={0.5}
stroke={Color.darkGreen} strokeWidth={2}
x1={profileX} y1={profileY}
x2={profileX} y2={profileY + depth} />
<circle id={"point-bottom-indicator"} opacity={0.5}
fill={Color.darkGreen} cx={profileX} cy={profileY + depth} r={2} />
</g>;
}
}
/** Weed point profile. */
export const WeedPoint = (props: ProfilePointProps<TaggedWeedPointer>) => {
const { point } = props;
const { radius } = point.body;
const color = point.body.meta.color || Color.red;
const plantIconSize = scaleIcon(radius) * 2;
const profileX = props.getX(point.body);
const profileY = props.soilHeight;
return <g id={"weed-profile-point"}>
<defs>
<radialGradient id={`weed-radius-gradient-${point.uuid}`}>
<stop offset="90%" stopColor={color} stopOpacity={0.1} />
<stop offset="100%" stopColor={color} stopOpacity={0} />
</radialGradient>
</defs>
<clipPath id={`weed-radius-clip-path-${point.uuid}`}>
<rect
x={profileX - radius}
y={profileY - radius}
height={radius}
width={radius * 2} />
</clipPath>
<circle className={"weed-radius"} stroke={"none"}
clipPath={`url(#weed-radius-clip-path-${point.uuid})`}
cx={profileX} cy={profileY} r={radius}
fill={`url(#weed-radius-gradient-${point.uuid})`} />
<g id={"weed-icon"}>
<image className={"weed-image"}
xlinkHref={FilePath.DEFAULT_WEED_ICON}
x={profileX - plantIconSize / 2}
y={profileY - plantIconSize}
height={plantIconSize}
width={plantIconSize} />
</g>
<circle id={"point-coordinate-indicator"} opacity={0.5}
fill={color} cx={profileX} cy={profileY} r={5} />
</g>;
};