summaryrefslogtreecommitdiff
path: root/garden.js
diff options
context:
space:
mode:
Diffstat (limited to 'garden.js')
-rw-r--r--garden.js153
1 files changed, 88 insertions, 65 deletions
diff --git a/garden.js b/garden.js
index 8e27c31..6987c57 100644
--- a/garden.js
+++ b/garden.js
@@ -226,6 +226,7 @@ const CROPS = [
springPlant: 0
}),
new Crop("Kale", {
+ fallCrop: true,
headStart: 4,
maturity: 4,
species: ["brassica napus", "brassica oleracea"],
@@ -268,6 +269,7 @@ const CROPS = [
maturity: 14,
multisow: 3,
spacing: 4,
+ species: ["allium cepa"],
springPlant: -4,
transplant: true
}),
@@ -387,14 +389,14 @@ function makeCropSchedule(crop, season) {
return crop.interval > 0 &&
offset >= crop.springPlant &&
offset <= fallPlant &&
- (offset <= crop.pause ||
- offset >= season.length - crop.resume) &&
+ (offset <= crop.pause || offset >= resume) &&
(offset - start) % crop.interval == 0;
}
const springStart = crop.springPlant - crop.headStart;
const fallPlant = season.length - crop.maturity - FALL_FACTOR;
const fallStart = fallPlant - crop.headStart;
+ const resume = season.length - crop.resume;
return season.weeks.map(week => {
function action(type) {
@@ -443,6 +445,79 @@ function monthAndDay(date) {
return (date.getUTCMonth() + 1) + "/" + date.getUTCDate();
}
+function viewCropDetails(crop) {
+ function close() {
+ container.removeChild(overlay);
+ }
+
+ function addDetail(name, detail) {
+ const p = document.createElement("p");
+ p.appendChild(document.createTextNode(`${name}: ${detail}`));
+ modal.appendChild(p);
+ }
+
+ const container = document.getElementById("container");
+ const overlay = document.createElement("div");
+ const modal = document.createElement("div");
+ const heading = document.createElement("h2");
+ const subheading = document.createElement("h4");
+ const speciesDetail = `(${crop.species.join(", ")})`;
+ heading.appendChild(document.createTextNode(crop.name));
+ subheading.appendChild(document.createTextNode(speciesDetail));
+ subheading.classList.add("detail-subheading");
+ modal.classList.add("modal");
+ modal.appendChild(heading);
+ modal.appendChild(subheading);
+ addDetail("Average time to maturity",
+ `${crop.maturity} weeks from ${crop.transplant ? "transplant" : "seed"}`);
+ if(crop.springPlant == -1) {
+ addDetail("Spring planting time", `1 week before last frost`);
+ } else if(crop.springPlant < 0) {
+ addDetail("Spring planting time",
+ `${Math.abs(crop.springPlant)} weeks before last frost`);
+ } else if(crop.springPlant == 1) {
+ addDetail("Spring planting time", `1 week after last frost`);
+ } else if(crop.springPlant > 0) {
+ addDetail("Spring planting time",
+ `${crop.springPlant} weeks after last frost`);
+ } else if(crop.springPlant == 0) {
+ addDetail("Spring planting time", "On the last frost date");
+ } else {
+ addDetail("Spring planting time", "Not a spring crop");
+ }
+ if(crop.fallCrop) {
+ addDetail("Fall planting time", `${crop.maturity + FALL_FACTOR} weeks before first frost`);
+ } else if(crop.resume != 99) {
+ addDetail("Fall planting time", `Succession planted ${crop.resume} weeks before first frost`);
+ } else if(crop.interval > 0) {
+ addDetail("Fall planting time", `Succession planted until ${crop.maturity + FALL_FACTOR} weeks before first frost`);
+ } else {
+ addDetail("Fall planting time", "Not a fall crop");
+ }
+ addDetail("Planting method", crop.transplant ? "Transplant" : "Direct sow");
+ if(crop.transplant) {
+ addDetail("Start indoors", `${crop.headStart} weeks before planting`);
+ }
+ if(crop.interval > 0) {
+ addDetail("Succession planting interval", `Every ${crop.interval} weeks`);
+ }
+ if(crop.multisow > 1) {
+ addDetail("Multisow", `${crop.multisow} seeds per module`);
+ } else {
+ addDetail("Multisow", "No");
+ }
+ if(crop.spacing >= 1) {
+ addDetail("Spacing", `${crop.spacing} ${crop.multisow > 1 ? "clumps" : "plants"} per square foot`);
+ } else {
+ addDetail("Spacing", `1 per ${Math.floor(1 / crop.spacing)} square feet`);
+ }
+ addDetail("Needs a trellis", crop.trellis ? "Yes" : "No");
+ overlay.classList.add("overlay");
+ overlay.appendChild(modal);
+ container.appendChild(overlay);
+ overlay.addEventListener("click", event => close());
+}
+
function makeDetailLink(crop) {
const span = document.createElement("span");
span.classList.add("crop");
@@ -550,15 +625,21 @@ function refreshInstructions(crops, season, schedule) {
weekDiv.appendChild(heading);
actions.forEach(action => {
const p = document.createElement("p");
- let text;
+ let prefix;
+ let suffix;
if(action.type == "start") {
- text = `Start ${action.crop.name} indoors.`;
+ prefix = "Start ";
+ suffix = " indoors.";
} else if(action.type == "sow") {
- text = `Sow ${action.crop.name} outdoors.`;
+ prefix = "Sow ";
+ suffix = " outdoors.";
} else if(action.type == "transplant") {
- text = `Transplant ${action.crop.name} outdoors.`;
+ prefix = "Transplant ";
+ suffix = " outdoors.";
}
- p.appendChild(document.createTextNode(text));
+ p.appendChild(document.createTextNode(prefix));
+ p.appendChild(makeDetailLink(action.crop));
+ p.appendChild(document.createTextNode(suffix));
weekDiv.appendChild(p);
});
instructionsDiv.appendChild(weekDiv);
@@ -583,64 +664,6 @@ function refreshView() {
}
}
-function viewCropDetails(crop) {
- function close() {
- container.removeChild(overlay);
- }
-
- function addDetail(name, detail) {
- const p = document.createElement("p");
- p.appendChild(document.createTextNode(`${name}: ${detail}`));
- modal.appendChild(p);
- }
-
- const container = document.getElementById("container");
- const overlay = document.createElement("div");
- const modal = document.createElement("div");
- const heading = document.createElement("h2");
- const subheading = document.createElement("h4");
- const speciesDetail = `(${crop.species.join(", ")})`;
- heading.appendChild(document.createTextNode(crop.name));
- subheading.appendChild(document.createTextNode(speciesDetail));
- subheading.classList.add("detail-subheading");
- modal.classList.add("modal");
- modal.appendChild(heading);
- modal.appendChild(subheading);
- if(crop.spacing >= 1) {
- addDetail("Spacing", `${crop.spacing} per square foot`);
- } else {
- addDetail("Spacing", `1 per ${Math.floor(1 / crop.spacing)} square feet`);
- }
- addDetail("Average time to maturity",
- `${crop.maturity} weeks from ${crop.transplant ? "transplant" : "seed"}`);
- if(crop.springPlant < 0) {
- addDetail("Earliest planting time",
- `${Math.abs(crop.springPlant)} weeks before last frost`);
- } else if(crop.springPlant > 0) {
- addDetail("Earliest planting time",
- `${crop.springPlant} weeks after last frost`);
- } else {
- addDetail("Earliest planting time", "week of last frost");
- }
- addDetail("Planting method", crop.transplant ? "Transplant" : "Direct sow");
- if(crop.transplant) {
- addDetail("Start indoors", `${crop.headStart} weeks before planting`);
- }
- if(crop.multisow > 1) {
- addDetail("Multisow", `${crop.multisow} seeds per module`);
- } else {
- addDetail("Multisow", "No");
- }
- addDetail("Needs a trellis", crop.trellis ? "Yes" : "No");
- if(crop.interval > 0) {
- addDetail("Succession planting interval", `Every ${crop.interval} weeks`);
- }
- overlay.classList.add("overlay");
- overlay.appendChild(modal);
- container.appendChild(overlay);
- overlay.addEventListener("click", event => close());
-}
-
function getLastFrostDateInput() {
return document.querySelector("input[name='last-frost-date']");
}