Skip to content

Commit

Permalink
Working on ArcTree functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
VashJuan committed Oct 23, 2024
1 parent d2a2b56 commit ba27b1a
Show file tree
Hide file tree
Showing 9 changed files with 1,400 additions and 1,343 deletions.
2 changes: 1 addition & 1 deletion content/english/resources2/2024/fema-sitemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The FEMA site is mammoth, and like eating an elephant its best to proceed a bit
- Zoom using the controls at the upper right, or using a scroll mouse wheel with the CTRL key held
- Click on the arrow icon at the upper right of each block to go to that page

<iframe title="FEMA.gov Sitemap" src="https://share.octopus.do/embed/aq1k7kiqjrs" class="border-4 h-[60vh] ml-[calc(50%-45vw)] w-[90vw]"></iframe>
<iframe title="FEMA.gov Sitemap" src="https://share.octopus.do/embed/46fwublkf88" class="border-4 h-[60vh] ml-[calc(50%-45vw)] w-[90vw]"></iframe>

### FEMA.gov Sitemap Textualized

Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions themes/eoconline/layouts/OrgChart/arc-tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
<label title="Font size in em's" id="fontSizeLabel">
Font size: <span id="fontSizeValue"></span> &nbsp;

<input type="range" step="0.5" min="0.5" value="1.0" max="5" id="fontSize" list="steplist" oninput="setFontSize(this)" />
<datalist id="steplist">
<input type="range" step="0.5" min="0.5" value="1.0" max="5" id="fontSize" list="stepList" oninput="setFontSize(this)" />
<datalist id="stepList">
<option>1.0</option>
<option>2.0</option>
<option>3.0</option>
Expand All @@ -42,6 +42,6 @@

<label> Select a JSON file to view: <input type="file" onChange="fileChange(this.files[0])" /> </label>

<ul id="unorderedList" class="tree"></ul>
<ul id="unorderedArcTree" class="tree"></ul>
</body>
</html>
239 changes: 148 additions & 91 deletions themes/eoconline/layouts/OrgChart/arc-tree.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
// or ESM/TypeScript import
import Ajv from "ajv"

document.addEventListener("DOMContentLoaded", function () {
//console.clear();
setFontSize(document.querySelector("#fontSize"));
});


/// 'Tree Options' functionality =====================
function setFontSize(el) {
let fontSize = el.value;
if (!isNumber(fontSize) || fontSize < 0.5 || fontSize > 5) {
Expand All @@ -17,7 +22,7 @@ function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}

// NOTE: Doesn't work!
// BUG: Doesn't work!
function collapseLeafs() {
var leafs = document.getElementsByClassName(".leaf");
var len = leafs.length;
Expand All @@ -28,7 +33,7 @@ function collapseLeafs() {
console.log("Collapsed all " + leafs.length + " leafs.");
}

// NOTE: Doesn't work!
// BUG: Doesn't work!
function showLeafs() {
var leafs = document.getElementsByClassName(".leaf");
var len = leafs.length;
Expand Down Expand Up @@ -58,18 +63,152 @@ function expandTree() {
}



/// Import & Validate Json functionality =====================
async function readJSONFile(file) {
return new Promise((resolve, reject) => {
let fileReader = new FileReader();
fileReader.onload = event => {
resolve(JSON.parse(event.target.result))
};
fileReader.onerror = (error => reject(error));
fileReader.readAsText(file);
});
}

async function fileChange(file) {
readJSONFile(file).then(
json => {
console.log(json);
//var baseUrl = new URL(file.name, window.location.href).href;
//var baseUrl = new URL("https:\\fema.gov").href;
validateJson(json);
clearArcTree(document.getElementById('unorderedArcTree'));
buildArcTree(json, document.getElementById('unorderedArcTree'), "https:////fema.gov");
}
);
}

function validateJson(json) {
try {
JSON.parse(json);
} catch (e) {
console.error("Invalid JSON: " + e);
return false;
}
console.log("json validated using JSON.parse")
return true;
}

// https://ajv.js.org/guide/getting-started.html#basic-data-validation
// https://www.npmjs.com/package/ajv

// Node.js require:
const Ajv = require("ajv")
const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}

const schema = {
type: "object",
properties: {
foo: { type: "integer" },
bar: { type: "string" },
},
required: ["foo"],
additionalProperties: false,
}

const schema2 = {
type: "object",
properties: {
title: { type: "string" },
url: { type: "string" },
meta: { type: "string" },
children: { type: "object" },
},
required: ["title"],
additionalProperties: false,
}

const data = {
foo: 1,
bar: "abc",
}

const data2 = {
title: "test title",
url: "test url",
meta: "test meta",
children: {
title: "test title",
url: "test url",
meta: "test meta",
children: {
title: "test title",
url: "test url",
meta: "test meta",
}
}
}

const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) {
console.error(validate.errors)
} else {
console.log("Json validated using Ajv")
}

/// Unused!
function downloadJson() {
var json = document.getElementById('unorderedArcTree').innerHTML;
var blob = new Blob([json], { type: "text/plain;charset=utf-8" });
saveAs(blob, "arcTree.json");
}

/// Unused!
function uploadJson() {
var file = document.getElementById('file').files[0];
if (file) {
fileChange(file);
}
}



/// Tree Creation functionality =====================
var expandedByDefault = true;
var cumulativeUrls = false; // If true, append child URLs to parent URL
var cumulativeUrls = true; // If true, append child URLs to parent URL
var listItemHTML = "";
var listLog = "";

function clearArcTree(treeElement) {
treeElement.innerHTML = '';
}

/// <summary>
/// Create an HTML unordered list of items from a JSON object
/// Recurse through the JSON object, building up an HTML string to display, appending them to the treeElement.
/// recurse through an 'o' JSON object & build up an HTML unordered list
/// Parameters:
/// 'o' is the JSON object to be processed, of the following form:
/***
o = {
"title": "title of web page",
"url": "relative url of web page",
"meta": "web page description",
"children": [{
"title": "title of child page",
"url": "relative url of child page",
"meta": "child page description",
"children": [{...}, {...}]
}]
}
***/
/// 'treeElement' is the HTML element to which the unordered list is to be appended
/// 'url' is this this segment of the tree's full or cumulative (N.B., see above option) url.
/// Initially it is just the base/home URL.
/// </summary>
function buildTree(o, treeElement, url) {

//console.log("buildTree: " + o?.toString());
function buildArcTree(o, treeElement, url) {
//console.log("buildArcTree: " + o?.toString());
for (var i in o) {
// console.log("processing: " + i.toString());
if (o[i] instanceof Array) {
Expand All @@ -85,15 +224,14 @@ function buildTree(o, treeElement, url) {
listLog += i + '=' + o[i] + "; ";

switch (i) {
case "name": listItemHTML += "<b>" + o[i] + "</b>"; break;
case "title": listItemHTML += "<b>" + o[i] + "</b>"; break;
case "url":
if (cumulativeUrls) {
childUrl = url + o[i];
} else {
childUrl = o[i];
}
listItemHTML += " (<a href='" + url + "'>" + o[i] + "</a>): ";

break;
case "meta": listItemHTML += "<i> Level " + o[i] + "</i>"; break;
default: listItemHTML += " [Unknown node (" + i + ")=" + o[i] + "] ";
Expand Down Expand Up @@ -130,7 +268,6 @@ function buildTree(o, treeElement, url) {
newLI.appendChild(newSpan);
}
listItemHTML = "";

treeElement.appendChild(newLI);

if (Object.keys(o[i]).length > 0) {
Expand All @@ -151,88 +288,8 @@ function buildTree(o, treeElement, url) {
}

console.group("children of " + i);
buildTree(o[i], newUL, childUrl);
buildArcTree(o[i], newUL, childUrl);
console.groupEnd();
}
}
}

async function readJSONFile(file) {
return new Promise((resolve, reject) => {
let fileReader = new FileReader();
fileReader.onload = event => {
resolve(JSON.parse(event.target.result))
};
fileReader.onerror = (error => reject(error));
fileReader.readAsText(file);
});
}

async function fileChange(file) {
readJSONFile(file).then(
json => {
console.log(json);
//var baseUrl = new URL(file.name, window.location.href).href;
//var baseUrl = new URL("https:\\fema.gov").href;
buildTree(json, document.getElementById('unorderedList'), "https:////fema.gov");
}
);
}

/*
function validateJson(jsonFile) {
try {
JSON.parse(jsonFile);
} catch (e) {
return false;
}
return true;
}
function downloadJson() {
var json = document.getElementById('unorderedList').innerHTML;
var blob = new Blob([json], { type: "text/plain;charset=utf-8" });
saveAs(blob, "orgchart.json");
}
function uploadJson() {
var file = document.getElementById('file').files[0];
if (file) {
fileChange(file);
}
}
function clearJson() {
document.getElementById('unorderedList').innerHTML = '';
}
// https://ajv.js.org/guide/getting-started.html#basic-data-validation
// https://www.npmjs.com/package/ajv
// or ESM/TypeScript import
import Ajv from "ajv"
// Node.js require:
const Ajv = require("ajv")
const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
const schema = {
type: "object",
properties: {
foo: { type: "integer" },
bar: { type: "string" },
},
required: ["foo"],
additionalProperties: false,
}
const data = {
foo: 1,
bar: "abc",
}
const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) console.log(validate.errors)
*/
Loading

0 comments on commit ba27b1a

Please sign in to comment.