diff --git a/README.md b/README.md index 862a352..fdce38a 100755 --- a/README.md +++ b/README.md @@ -2,15 +2,15 @@ Tree.js [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Tree.js%2C%20a%20free%20JavaScript%data%20tree&url=https://github.com/williamtroup/Tree.js&hashtags=javascript,tree,data) -[![npm](https://img.shields.io/badge/npmjs-v0.1.0-blue)](https://www.npmjs.com/package/jtree.js) -[![nuget](https://img.shields.io/badge/nuget-v0.1.0-purple)](https://www.nuget.org/packages/jTree.js/) +[![npm](https://img.shields.io/badge/npmjs-v0.2.0-blue)](https://www.npmjs.com/package/jtree.js) +[![nuget](https://img.shields.io/badge/nuget-v0.2.0-purple)](https://www.nuget.org/packages/jTree.js/) [![license](https://img.shields.io/badge/license-MIT-green)](https://github.com/williamtroup/Tree.js/blob/main/LICENSE.txt) [![discussions Welcome](https://img.shields.io/badge/discussions-Welcome-red)](https://github.com/williamtroup/Tree.js/discussions) [![coded by William Troup](https://img.shields.io/badge/coded_by-William_Troup-yellow)](https://william-troup.com/) ->

🌲 A lightweight JavaScript library that generates customizable trees views to visualize numerical data.

->

v0.1.0

+>

🌲 A lightweight JavaScript library that allows you to create responsive and customizable interactive tree diagrams from an array of JS objects.

+>

v0.2.0


![Tree.js - Gaps](docs/images/main-1.png) @@ -29,7 +29,7 @@ Tree.js - Fully configurable per DOM element. - Toggling data on/off support. - Customizable tooltips. -- Expanding/Contract data items. +- Expand/Contract data items. - Configurable colors for boxes!

diff --git a/README_NUGET.md b/README_NUGET.md index 95cbb75..4367193 100755 --- a/README_NUGET.md +++ b/README_NUGET.md @@ -1,13 +1,13 @@ -# Tree.js v0.1.0 +# Tree.js v0.2.0 [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Tree.js%2C%20a%20free%20JavaScript%data%20tree&url=https://github.com/williamtroup/Tree.js&hashtags=javascript,tree,data) -[![npm](https://img.shields.io/badge/npmjs-v0.1.0-blue)](https://www.npmjs.com/package/jtree.js) -[![nuget](https://img.shields.io/badge/nuget-v0.1.0-purple)](https://www.nuget.org/packages/jTree.js/) +[![npm](https://img.shields.io/badge/npmjs-v0.2.0-blue)](https://www.npmjs.com/package/jtree.js) +[![nuget](https://img.shields.io/badge/nuget-v0.2.0-purple)](https://www.nuget.org/packages/jTree.js/) [![license](https://img.shields.io/badge/license-MIT-green)](https://github.com/williamtroup/Tree.js/blob/main/LICENSE.txt) [![discussions Welcome](https://img.shields.io/badge/discussions-Welcome-red)](https://github.com/williamtroup/Tree.js/discussions) [![coded by William Troup](https://img.shields.io/badge/coded_by-William_Troup-yellow)](https://william-troup.com/) -> 🌲 A lightweight JavaScript library that generates customizable trees views to visualize numerical data. +> 🌲 A lightweight JavaScript library that allows you to create responsive and customizable interactive tree diagrams from an array of JS objects. ## What features does Tree.js have? @@ -19,7 +19,7 @@ - Fully configurable per DOM element. - Toggling data on/off support. - Customizable tooltips. -- Expanding/Contract data items. +- Expand/Contract data items. - Configurable colors for boxes! diff --git a/dist/tree.js b/dist/tree.js index 8b3d5e1..bc01eb1 100755 --- a/dist/tree.js +++ b/dist/tree.js @@ -1,93 +1,94 @@ -/*! Tree.js v0.1.0 | (c) Bunoon 2024 | MIT License */ +/*! Tree.js v0.2.0 | (c) Bunoon 2024 | MIT License */ (function() { - function render() { - var tagTypes = _configuration.domElementTypes; - var tagTypesLength = tagTypes.length; - var tagTypeIndex = 0; - for (; tagTypeIndex < tagTypesLength; tagTypeIndex++) { - var domElements = _parameter_Document.getElementsByTagName(tagTypes[tagTypeIndex]); - var elements = [].slice.call(domElements); - var elementsLength = elements.length; - var elementIndex = 0; - for (; elementIndex < elementsLength; elementIndex++) { - if (!renderElement(elements[elementIndex])) { - break; - } + function render() { + var tagTypes = _configuration.domElementTypes; + var tagTypesLength = tagTypes.length; + var tagTypeIndex = 0; + for (; tagTypeIndex < tagTypesLength; tagTypeIndex++) { + var domElements = _parameter_Document.getElementsByTagName(tagTypes[tagTypeIndex]); + var elements = [].slice.call(domElements); + var elementsLength = elements.length; + var elementIndex = 0; + for (; elementIndex < elementsLength; elementIndex++) { + if (!renderElement(elements[elementIndex])) { + break; } } } - function renderElement(element) { - var result = true; - if (isDefined(element) && element.hasAttribute(_attribute_Name_Options)) { - var bindingOptionsData = element.getAttribute(_attribute_Name_Options); - if (isDefinedString(bindingOptionsData)) { - var bindingOptions = getObjectFromString(bindingOptionsData); - if (bindingOptions.parsed && isDefinedObject(bindingOptions.result)) { - renderControl(renderBindingOptions(bindingOptions.result, element)); - } else { - if (!_configuration.safeMode) { - console.error("The attribute '" + _attribute_Name_Options + "' is not a valid object."); - result = false; - } - } + } + function renderElement(element) { + var result = true; + if (isDefined(element) && element.hasAttribute(_attribute_Name_Options)) { + var bindingOptionsData = element.getAttribute(_attribute_Name_Options); + if (isDefinedString(bindingOptionsData)) { + var bindingOptions = getObjectFromString(bindingOptionsData); + if (bindingOptions.parsed && isDefinedObject(bindingOptions.result)) { + renderControl(renderBindingOptions(bindingOptions.result, element)); } else { if (!_configuration.safeMode) { - console.error("The attribute '" + _attribute_Name_Options + "' has not been set correctly."); + console.error("The attribute '" + _attribute_Name_Options + "' is not a valid object."); result = false; } } + } else { + if (!_configuration.safeMode) { + console.error("The attribute '" + _attribute_Name_Options + "' has not been set correctly."); + result = false; + } } - return result; - } - function renderBindingOptions(data, element) { - var bindingOptions = buildAttributeOptions(data); - var categories = getCategories(bindingOptions); - bindingOptions.currentView = {}; - bindingOptions.currentView.element = element; - bindingOptions.currentView.tooltip = null; - bindingOptions.currentView.tooltipTimer = null; - bindingOptions.currentView.category = categories.length > 0 ? categories[0] : null; - bindingOptions.currentView.categories = categories; - bindingOptions.currentView.categoryText = null; - bindingOptions.currentView.categoryIndex = 0; - bindingOptions.currentView.fullScreenBoxId = null; - bindingOptions.currentView.fullScreenBoxHeight = null; - return bindingOptions; - } - function renderControl(bindingOptions) { - fireCustomTrigger(bindingOptions.onBeforeRender, bindingOptions.element); - if (!isDefinedString(bindingOptions.currentView.element.id)) { - bindingOptions.currentView.element.id = newGuid(); - } - bindingOptions.currentView.element.removeAttribute(_attribute_Name_Options); - bindingOptions.currentView.rows = null; - bindingOptions.currentView.element.className = "tree-js"; - if (!_elements_Data.hasOwnProperty(bindingOptions.currentView.element.id)) { - _elements_Data[bindingOptions.currentView.element.id] = bindingOptions.data; - delete bindingOptions.data; - } - renderControlContainer(bindingOptions); - fireCustomTrigger(bindingOptions.onRenderComplete, bindingOptions.currentView.element); - } - function renderControlContainer(bindingOptions) { - bindingOptions.currentView.element.innerHTML = _string.empty; - hideToolTip(bindingOptions); - renderControlToolTip(bindingOptions); - renderControlTitleBar(bindingOptions); - renderControlRows(bindingOptions); - renderControlRowsAndBoxes(bindingOptions, bindingOptions.currentView.rows, _elements_Data[bindingOptions.currentView.element.id]); - renderControlFooter(bindingOptions); - _parameter_Window.addEventListener("resize", function() { - renderControlRowsAndBoxes(bindingOptions, bindingOptions.currentView.rows, _elements_Data[bindingOptions.currentView.element.id]); - }); } - function renderControlTitleBar(bindingOptions) { - var titleBar = createElement(bindingOptions.currentView.element, "div", "title-bar"); - if (bindingOptions.showTitle) { - createElementWithHTML(titleBar, "div", "title", bindingOptions.titleText); - } - if (bindingOptions.currentView.categories.length > 1) { - var controls = createElement(titleBar, "div", "controls"); + return result; + } + function renderBindingOptions(data, element) { + var bindingOptions = buildAttributeOptions(data); + var categories = getCategories(bindingOptions); + bindingOptions.currentView = {}; + bindingOptions.currentView.element = element; + bindingOptions.currentView.tooltip = null; + bindingOptions.currentView.tooltipTimer = null; + bindingOptions.currentView.category = categories.length > 0 ? categories[0] : null; + bindingOptions.currentView.categories = categories; + bindingOptions.currentView.categoryText = null; + bindingOptions.currentView.categoryIndex = 0; + bindingOptions.currentView.fullScreenBoxId = null; + bindingOptions.currentView.fullScreenBoxHeight = null; + return bindingOptions; + } + function renderControl(bindingOptions) { + fireCustomTrigger(bindingOptions.onBeforeRender, bindingOptions.element); + if (!isDefinedString(bindingOptions.currentView.element.id)) { + bindingOptions.currentView.element.id = newGuid(); + } + bindingOptions.currentView.element.removeAttribute(_attribute_Name_Options); + bindingOptions.currentView.rows = null; + bindingOptions.currentView.element.className = "tree-js"; + if (!_elements_Data.hasOwnProperty(bindingOptions.currentView.element.id)) { + _elements_Data[bindingOptions.currentView.element.id] = bindingOptions.data; + delete bindingOptions.data; + } + renderControlContainer(bindingOptions); + fireCustomTrigger(bindingOptions.onRenderComplete, bindingOptions.currentView.element); + } + function renderControlContainer(bindingOptions) { + bindingOptions.currentView.element.innerHTML = _string.empty; + hideToolTip(bindingOptions); + renderControlToolTip(bindingOptions); + renderControlTitleBar(bindingOptions); + renderControlRows(bindingOptions); + renderControlRowsAndBoxes(bindingOptions, bindingOptions.currentView.rows, _elements_Data[bindingOptions.currentView.element.id]); + renderControlFooter(bindingOptions); + _parameter_Window.addEventListener("resize", function() { + renderControlRowsAndBoxes(bindingOptions, bindingOptions.currentView.rows, _elements_Data[bindingOptions.currentView.element.id]); + }); + } + function renderControlTitleBar(bindingOptions) { + var titleBar = createElement(bindingOptions.currentView.element, "div", "title-bar"); + if (bindingOptions.showTitle) { + createElementWithHTML(titleBar, "div", "title", bindingOptions.titleText); + } + if (bindingOptions.currentView.categories.length > 1) { + var controls = createElement(titleBar, "div", "controls"); + if (bindingOptions.showCategorySelector) { var back = createElementWithHTML(controls, "button", "back", _configuration.backButtonText); back.onclick = function() { if (bindingOptions.currentView.categoryIndex > 0) { @@ -98,25 +99,29 @@ } }; bindingOptions.currentView.categoryText = createElementWithHTML(controls, "div", "category-text", bindingOptions.currentView.category); - createElement(bindingOptions.currentView.categoryText, "div", "down-arrow"); - var categoriesList = createElement(bindingOptions.currentView.categoryText, "div", "categories-list"); - var categories = createElement(categoriesList, "div", "categories"); - var activeCategory = null; - var categoriesLength = bindingOptions.currentView.categories.length; - categoriesList.style.display = "block"; - categoriesList.style.visibility = "hidden"; - var categoryIndex = 0; - for (; categoryIndex < categoriesLength; categoryIndex++) { - var category = renderControlTitleBarCategory(bindingOptions, categories, bindingOptions.currentView.categories[categoryIndex]); - if (!isDefined(activeCategory)) { - activeCategory = category; + if (bindingOptions.showCategorySelectionDropDown) { + createElement(bindingOptions.currentView.categoryText, "div", "down-arrow"); + var categoriesList = createElement(bindingOptions.currentView.categoryText, "div", "categories-list"); + var categories = createElement(categoriesList, "div", "categories"); + var activeCategory = null; + var categoriesLength = bindingOptions.currentView.categories.length; + categoriesList.style.display = "block"; + categoriesList.style.visibility = "hidden"; + var categoryIndex = 0; + for (; categoryIndex < categoriesLength; categoryIndex++) { + var category = renderControlTitleBarCategory(bindingOptions, categories, bindingOptions.currentView.categories[categoryIndex]); + if (!isDefined(activeCategory)) { + activeCategory = category; + } } + if (isDefined(activeCategory)) { + categories.scrollTop = activeCategory.offsetTop - categories.offsetHeight / 2; + } + categoriesList.style.display = "none"; + categoriesList.style.visibility = "visible"; + } else { + addClass(bindingOptions.currentView.categoryText, "no-click"); } - if (isDefined(activeCategory)) { - categories.scrollTop = activeCategory.offsetTop - categories.offsetHeight / 2; - } - categoriesList.style.display = "none"; - categoriesList.style.visibility = "visible"; var next = createElementWithHTML(controls, "button", "next", _configuration.nextButtonText); next.onclick = function() { if (bindingOptions.currentView.categoryIndex < categoriesLength - 1) { @@ -128,523 +133,544 @@ }; } } - function renderControlTitleBarCategory(bindingOptions, categories, currentCategory) { - var result = null; - var category = createElementWithHTML(categories, "div", "category", currentCategory); - if (bindingOptions.currentView.category !== currentCategory) { - category.onclick = function() { - bindingOptions.currentView.category = currentCategory; - bindingOptions.currentView.categoryIndex = bindingOptions.currentView.categories.indexOf(currentCategory); - renderControlContainer(bindingOptions); - fireCustomTrigger(bindingOptions.onSetCategory, bindingOptions.currentView.category); - }; - } else { - addClass(category, "category-active"); - result = category; - } - return result; - } - function renderControlRows(bindingOptions) { - bindingOptions.currentView.rows = createElement(bindingOptions.currentView.element, "div", "box-rows"); - } - function renderControlRowsAndBoxes(bindingOptions, container, data, isChildren) { - isChildren = isDefined(isChildren) ? isChildren : false; - var rowData = getRowsAndBoxes(bindingOptions, data, isChildren); + } + function renderControlTitleBarCategory(bindingOptions, categories, currentCategory) { + var result = null; + var category = createElementWithHTML(categories, "div", "category", currentCategory); + if (bindingOptions.currentView.category !== currentCategory) { + category.onclick = function() { + bindingOptions.currentView.category = currentCategory; + bindingOptions.currentView.categoryIndex = bindingOptions.currentView.categories.indexOf(currentCategory); + renderControlContainer(bindingOptions); + fireCustomTrigger(bindingOptions.onSetCategory, bindingOptions.currentView.category); + }; + } else { + addClass(category, "category-active"); + result = category; + } + return result; + } + function renderControlRows(bindingOptions) { + bindingOptions.currentView.rows = createElement(bindingOptions.currentView.element, "div", "box-rows"); + } + function renderControlRowsAndBoxes(bindingOptions, container, data, isChildren) { + isChildren = isDefined(isChildren) ? isChildren : false; + var rowData = getRowsAndBoxes(bindingOptions, data, isChildren); + if (!isChildren) { + container.innerHTML = _string.empty; + } + if (rowData.totalRows === 0) { if (!isChildren) { - container.innerHTML = _string.empty; - } - if (rowData.totalRows === 0) { - if (!isChildren) { - createElementWithHTML(container, "div", "no-data", _configuration.noDataMessage); - } - } else { - var boxWidth = null; - var rowIndex = !bindingOptions.swapSizes ? rowData.totalRows : 1; - var dividedBoxHeight = bindingOptions.maximumBoxHeight / rowData.totalRows; - var rowKey; - for (rowKey in rowData.boxesPerRow) { + createElementWithHTML(container, "div", "no-data", _configuration.noDataMessage); + } + } else { + var boxWidth = null; + var rowIndex = !bindingOptions.swapSizes ? rowData.totalRows : 1; + var dividedBoxHeight = bindingOptions.maximumBoxHeight / rowData.totalRows; + var rowKey; + for (rowKey in rowData.boxesPerRow) { + if (rowData.boxesPerRow.hasOwnProperty(rowKey)) { + var boxHeight = dividedBoxHeight * rowIndex; if (rowData.boxesPerRow.hasOwnProperty(rowKey)) { - var boxHeight = dividedBoxHeight * rowIndex; - if (rowData.boxesPerRow.hasOwnProperty(rowKey)) { - var boxRow = createElement(container, "div", "box-row"); - var boxesLength = rowData.boxesPerRow[rowKey].length; - if (!isChildren && !bindingOptions.showBoxGaps || isChildren && !bindingOptions.showBoxGapsForChildren) { - addClass(boxRow, "box-row-no-spacing"); - } else { - if (!isDefinedNumber(boxWidth)) { - boxWidth = boxRow.offsetWidth / rowData.largestAmountOfBoxesOnARow - bindingOptions.spacing; - } - } - var boxIndex = 0; - for (; boxIndex < boxesLength; boxIndex++) { - renderBox(bindingOptions, boxRow, boxHeight, boxWidth, rowData.boxesPerRow[rowKey][boxIndex], isChildren); + var boxRow = createElement(container, "div", "box-row"); + var boxesLength = rowData.boxesPerRow[rowKey].length; + if (!isChildren && !bindingOptions.showBoxGaps || isChildren && !bindingOptions.showBoxGapsForChildren) { + addClass(boxRow, "box-row-no-spacing"); + } else { + if (!isDefinedNumber(boxWidth)) { + boxWidth = boxRow.offsetWidth / rowData.largestAmountOfBoxesOnARow - bindingOptions.spacing; } } - if (!bindingOptions.swapSizes) { - rowIndex--; - } else { - rowIndex++; + var boxIndex = 0; + for (; boxIndex < boxesLength; boxIndex++) { + renderBox(bindingOptions, boxRow, boxHeight, boxWidth, rowData.boxesPerRow[rowKey][boxIndex], isChildren); } } - } - if (bindingOptions.reverseOrder) { - reverseElementsOrder(container); - } - } - return container.children.length > 0; - } - function renderBox(bindingOptions, boxRow, boxHeight, boxWidth, boxDetails, isChild) { - var box = createElement(boxRow, "div", "box"); - var boxChildrenAdded = false; - box.id = boxDetails.id; - if (bindingOptions.currentView.fullScreenBoxId === boxDetails.id) { - box.style.height = bindingOptions.currentView.fullScreenBoxHeight + "px"; - } else { - box.style.height = boxHeight + "px"; - } - if (isDefinedFunction(bindingOptions.onBoxClick)) { - box.onclick = function(e) { - cancelBubble(e); - fireCustomTrigger(bindingOptions.onBoxClick, boxDetails); - }; - } else { - addClass(box, "no-click"); - } - if (isDefinedNumber(boxWidth)) { - box.style.width = boxWidth + "px"; - } - if (isDefinedString(boxDetails.backgroundColor)) { - box.style.backgroundColor = boxDetails.backgroundColor; - } - if (isDefinedString(boxDetails.textColor)) { - box.style.color = boxDetails.textColor; - } - if (isDefinedString(boxDetails.borderColor)) { - box.style.borderColor = boxDetails.borderColor; - } - if (isDefinedString(boxDetails.name) || isDefinedBoolean(boxDetails.showValue) && boxDetails.showValue) { - var titleBar = createElement(box, "div", "box-title-bar"); - createElementWithHTML(titleBar, "div", "box-title", boxDetails.name); - var value = createElement(titleBar, "div", "box-value"); - if (isDefinedBoolean(boxDetails.showValue) && boxDetails.showValue && isDefinedNumber(boxDetails.value)) { - createElementWithHTML(value, "span", null, boxDetails.value); - } - if (!isChild && bindingOptions.allowBoxExpanding) { - var expandFunc = function(e) { - cancelBubble(e); - if (isDefined(bindingOptions.currentView.fullScreenBoxId)) { - bindingOptions.currentView.fullScreenBoxId = null; - bindingOptions.currentView.fullScreenBoxHeight = null; - } else { - bindingOptions.currentView.fullScreenBoxId = boxDetails.id; - bindingOptions.currentView.fullScreenBoxHeight = boxRow.parentNode.offsetHeight; - } - renderControlContainer(bindingOptions); - }; - if (bindingOptions.currentView.fullScreenBoxId !== boxDetails.id) { - var expand = createElement(value, "div", "expand"); - expand.onclick = expandFunc; - addToolTip(expand, bindingOptions, _configuration.expandToolTipText); - if (isDefinedString(boxDetails.textColor)) { - expand.style.borderColor = boxDetails.textColor; - } + if (!bindingOptions.swapSizes) { + rowIndex--; } else { - var contract = createElement(value, "div", "contract"); - contract.onclick = expandFunc; - addToolTip(contract, bindingOptions, _configuration.contractToolTipText); - if (isDefinedString(boxDetails.textColor)) { - contract.style.setProperty("--tree-js-color-black", boxDetails.textColor); - } + rowIndex++; } } } - if (isDefinedString(boxDetails.description) && bindingOptions.showDescriptions) { - createElementWithHTML(box, "p", "description", boxDetails.description); - } - if (!isChild && isDefinedArray(boxDetails.children) && boxDetails.children.length > 0 && bindingOptions.showChildren) { - var boxRows = createElement(box, "div", "box-rows children"); - boxChildrenAdded = renderControlRowsAndBoxes(bindingOptions, boxRows, boxDetails.children, true); - } - if (!boxChildrenAdded && isDefinedString(boxDetails.content) && bindingOptions.showContents) { - createElementWithHTML(box, "div", null, boxDetails.content); - } - } - function renderControlFooter(bindingOptions) { - var footer = createElement(bindingOptions.currentView.element, "div", "footer"); - var onClick = function() { - bindingOptions.showChildren = showChildren.checked; - bindingOptions.showDescriptions = showDescriptions.checked; - bindingOptions.showContents = showContents.checked; - renderControlContainer(bindingOptions); + if (bindingOptions.reverseOrder) { + reverseElementsOrder(container); + } + } + return container.children.length > 0; + } + function renderBox(bindingOptions, boxRow, boxHeight, boxWidth, boxDetails, isChild) { + var box = createElement(boxRow, "div", "box"); + var boxChildrenAdded = false; + box.id = boxDetails.id; + if (bindingOptions.currentView.fullScreenBoxId === boxDetails.id) { + box.style.height = bindingOptions.currentView.fullScreenBoxHeight + "px"; + } else { + box.style.height = boxHeight + "px"; + } + if (isDefinedFunction(bindingOptions.onBoxClick)) { + box.onclick = function(e) { + cancelBubble(e); + fireCustomTrigger(bindingOptions.onBoxClick, boxDetails); }; - var showChildren = buildCheckBox(footer, _configuration.showChildrenLabelText, bindingOptions.showChildren, onClick)[0]; - var showDescriptions = buildCheckBox(footer, _configuration.showDescriptionsLabelText, bindingOptions.showDescriptions, onClick)[0]; - var showContents = buildCheckBox(footer, _configuration.showContentsLabelText, bindingOptions.showContents, onClick)[0]; + } else { + addClass(box, "no-click"); } - function renderControlToolTip(bindingOptions) { - if (!isDefined(bindingOptions.currentView.tooltip)) { - bindingOptions.currentView.tooltip = createElement(_parameter_Document.body, "div", "tree-js-tooltip"); - bindingOptions.currentView.tooltip.style.display = "none"; - _parameter_Document.body.addEventListener("mousemove", function() { - hideToolTip(bindingOptions); - }); - _parameter_Document.addEventListener("scroll", function() { - hideToolTip(bindingOptions); - }); - } + if (isDefinedNumber(boxWidth)) { + box.style.width = boxWidth + "px"; } - function addToolTip(element, bindingOptions, text) { - if (element !== null) { - element.onmousemove = function(e) { - showToolTip(e, bindingOptions, text); - }; - } + if (isDefinedString(boxDetails.backgroundColor)) { + box.style.backgroundColor = boxDetails.backgroundColor; } - function showToolTip(e, bindingOptions, text) { - cancelBubble(e); - hideToolTip(bindingOptions); - bindingOptions.currentView.tooltipTimer = setTimeout(function() { - bindingOptions.currentView.tooltip.innerHTML = text; - bindingOptions.currentView.tooltip.style.display = "block"; - showElementAtMousePosition(e, bindingOptions.currentView.tooltip); - }, bindingOptions.tooltipDelay); - } - function hideToolTip(bindingOptions) { - if (isDefined(bindingOptions.currentView.tooltip)) { - if (isDefined(bindingOptions.currentView.tooltipTimer)) { - clearTimeout(bindingOptions.currentView.tooltipTimer); - bindingOptions.currentView.tooltipTimer = null; - } - if (bindingOptions.currentView.tooltip.style.display === "block") { - bindingOptions.currentView.tooltip.style.display = "none"; - } - } + if (isDefinedString(boxDetails.textColor)) { + box.style.color = boxDetails.textColor; } - function getRowsAndBoxes(bindingOptions, data, isChildren) { - var boxesDetails = getBoxesAndMaximumPerRow(bindingOptions, data, isChildren); - var boxesPerRow = {}; - var largestAmountOfBoxesOnARow = 0; - var rowNumber = 0; - if (boxesDetails.maximum > 0) { - rowNumber = 1; - boxesDetails.boxes = boxesDetails.boxes.sort(function(a, b) { - return b.value - a.value; - }); - var startIndex = 0; - var endIndex = boxesDetails.maximum; - var dataLength = boxesDetails.boxes.length; - for (; true;) { - var breakOnceProcessed = false; - boxesPerRow[rowNumber] = []; - if (endIndex > dataLength) { - endIndex = dataLength; - breakOnceProcessed = true; - } - var arrayIndex = startIndex; - for (; arrayIndex < endIndex; arrayIndex++) { - boxesPerRow[rowNumber].push(boxesDetails.boxes[arrayIndex]); - } - largestAmountOfBoxesOnARow = _parameter_Math.max(boxesPerRow[rowNumber].length, largestAmountOfBoxesOnARow); - if (breakOnceProcessed) { - break; + if (isDefinedString(boxDetails.borderColor)) { + box.style.borderColor = boxDetails.borderColor; + } + if (isDefinedString(boxDetails.name) || isDefinedBoolean(boxDetails.showValue) && boxDetails.showValue) { + var titleBar = createElement(box, "div", "box-title-bar"); + createElementWithHTML(titleBar, "div", "box-title", boxDetails.name); + var value = createElement(titleBar, "div", "box-value"); + if (isDefinedBoolean(boxDetails.showValue) && boxDetails.showValue && isDefinedNumber(boxDetails.value)) { + createElementWithHTML(value, "span", null, boxDetails.value); + } + if (!isChild && bindingOptions.allowBoxExpanding) { + var expandFunc = function(e) { + cancelBubble(e); + if (isDefined(bindingOptions.currentView.fullScreenBoxId)) { + bindingOptions.currentView.fullScreenBoxId = null; + bindingOptions.currentView.fullScreenBoxHeight = null; } else { - startIndex = endIndex; - endIndex = endIndex + (boxesDetails.maximum + rowNumber * 2); - rowNumber++; + bindingOptions.currentView.fullScreenBoxId = boxDetails.id; + bindingOptions.currentView.fullScreenBoxHeight = boxRow.parentNode.offsetHeight; } - } - } - return {boxesPerRow:boxesPerRow, largestAmountOfBoxesOnARow:largestAmountOfBoxesOnARow, totalRows:rowNumber}; - } - function getBoxesAndMaximumPerRow(bindingOptions, data, isChildren) { - var boxes = []; - var maximumBoxes = 0; - var dataLength = data.length; - if (dataLength > 1) { - var dataIndex = 0; - for (; dataIndex < dataLength; dataIndex++) { - var dataItem = data[dataIndex]; - if (!isDefinedString(dataItem.id)) { - dataItem.id = newGuid(); + renderControlContainer(bindingOptions); + }; + if (bindingOptions.currentView.fullScreenBoxId !== boxDetails.id) { + var expand = createElement(value, "div", "expand"); + expand.onclick = expandFunc; + addToolTip(expand, bindingOptions, _configuration.expandToolTipText); + if (isDefinedString(boxDetails.textColor)) { + expand.style.borderColor = boxDetails.textColor; } - if (!isChildren && isDefined(bindingOptions.currentView.fullScreenBoxId)) { - if (dataItem.id === bindingOptions.currentView.fullScreenBoxId) { - boxes.push(dataItem); - } - } else { - if (isChildren || !isDefinedString(dataItem.category) || !isDefinedString(bindingOptions.currentView.category) || bindingOptions.currentView.category === dataItem.category) { - boxes.push(dataItem); - } + } else { + var contract = createElement(value, "div", "contract"); + contract.onclick = expandFunc; + addToolTip(contract, bindingOptions, _configuration.contractToolTipText); + if (isDefinedString(boxDetails.textColor)) { + contract.style.setProperty("--tree-js-color-black", boxDetails.textColor); } } - var totalItems = boxes.length; - var totalRows = bindingOptions.maximumRows; - maximumBoxes = totalItems / totalRows; - for (; maximumBoxes < 1.0;) { - totalRows--; - maximumBoxes = totalItems / totalRows; - } } - return {maximum:_parameter_Math.round(maximumBoxes), boxes:boxes}; } - function getCategories(bindingOptions) { - var categories = []; - var dataLength = bindingOptions.data.length; - var dataIndex = 0; - for (; dataIndex < dataLength; dataIndex++) { - var data = bindingOptions.data[dataIndex]; - if (isDefinedString(data.category) && categories.indexOf(data.category) === -1) { - categories.push(data.category); - } - } - return categories; - } - function buildAttributeOptions(newOptions) { - var options = !isDefinedObject(newOptions) ? {} : newOptions; - options.data = getDefaultArray(options.data, []); - options.maximumRows = getDefaultNumber(options.maximumRows, 10); - options.spacing = getDefaultNumber(options.spacing, 10); - options.maximumBoxHeight = getDefaultNumber(options.maximumBoxHeight, 200); - options.reverseOrder = getDefaultBoolean(options.reverseOrder, false); - options.showBoxGaps = getDefaultBoolean(options.showBoxGaps, true); - options.swapSizes = getDefaultBoolean(options.swapSizes, false); - options.showBoxGapsForChildren = getDefaultBoolean(options.showBoxGapsForChildren, false); - options.allowBoxExpanding = getDefaultBoolean(options.allowBoxExpanding, true); - options.showTitle = getDefaultBoolean(options.showTitle, true); - options.showChildren = getDefaultBoolean(options.showChildren, true); - options.showDescriptions = getDefaultBoolean(options.showDescriptions, true); - options.showContents = getDefaultBoolean(options.showContents, true); - options.tooltipDelay = getDefaultNumber(options.tooltipDelay, 750); - options = buildAttributeOptionCustomTriggers(options); - options = buildAttributeOptionStrings(options); - return options; - } - function buildAttributeOptionStrings(options) { - options.titleText = getDefaultString(options.titleText, "Tree.js"); - return options; - } - function buildAttributeOptionCustomTriggers(options) { - options.onBeforeRender = getDefaultFunction(options.onBeforeRender, null); - options.onRenderComplete = getDefaultFunction(options.onRenderComplete, null); - options.onBoxClick = getDefaultFunction(options.onBoxClick, null); - options.onBackCategory = getDefaultFunction(options.onBackCategory, null); - options.onNextCategory = getDefaultFunction(options.onNextCategory, null); - options.onSetCategory = getDefaultFunction(options.onSetCategory, null); - return options; - } - function createElement(container, type, className) { - var result = null; - var nodeType = type.toLowerCase(); - var isText = nodeType === "text"; - if (!_elements_Type.hasOwnProperty(nodeType)) { - _elements_Type[nodeType] = isText ? _parameter_Document.createTextNode(_string.empty) : _parameter_Document.createElement(nodeType); - } - result = _elements_Type[nodeType].cloneNode(false); - if (isDefined(className)) { - result.className = className; - } - container.appendChild(result); - return result; - } - function createElementWithHTML(container, type, className, html) { - var element = createElement(container, type, className); - element.innerHTML = html; - return element; - } - function getScrollPosition() { - var doc = _parameter_Document.documentElement; - var left = (_parameter_Window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0); - var top = (_parameter_Window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); - return {left:left, top:top}; - } - function showElementAtMousePosition(e, element) { - var left = e.pageX; - var top = e.pageY; - var scrollPosition = getScrollPosition(); - element.style.display = "block"; - if (left + element.offsetWidth > _parameter_Window.innerWidth) { - left = left - element.offsetWidth; - } else { - left++; - } - if (top + element.offsetHeight > _parameter_Window.innerHeight) { - top = top - element.offsetHeight; - } else { - top++; - } - if (left < scrollPosition.left) { - left = e.pageX + 1; - } - if (top < scrollPosition.top) { - top = e.pageY + 1; - } - element.style.left = left + "px"; - element.style.top = top + "px"; - } - function reverseElementsOrder(parent) { - var children = parent.children; - var childrenLength = children.length - 1; - for (; childrenLength--;) { - parent.appendChild(children[childrenLength]); - } + if (isDefinedString(boxDetails.description) && bindingOptions.showDescriptions) { + createElementWithHTML(box, "p", "description", boxDetails.description); } - function addClass(element, className) { - element.className += _string.space + className; + if (!isChild && isDefinedArray(boxDetails.children) && boxDetails.children.length > 0 && bindingOptions.showChildren) { + var boxRows = createElement(box, "div", "box-rows children"); + boxChildrenAdded = renderControlRowsAndBoxes(bindingOptions, boxRows, boxDetails.children, true); } - function cancelBubble(e) { - e.preventDefault(); - e.cancelBubble = true; + if (!boxChildrenAdded && isDefinedString(boxDetails.content) && bindingOptions.showContents) { + createElementWithHTML(box, "div", null, boxDetails.content); } - function buildCheckBox(container, labelText, checked, onClick) { - var label = createElement(container, "label", "checkbox"); - var input = createElement(label, "input"); - input.type = "checkbox"; - if (isDefined(onClick)) { - input.onclick = onClick; + } + function renderControlFooter(bindingOptions) { + var footer = createElement(bindingOptions.currentView.element, "div", "footer"); + var showChildren = null; + var showDescriptions = null; + var showContents = null; + var onClick = function() { + if (isDefined(showChildren)) { + bindingOptions.showChildren = showChildren.checked; } - if (isDefined(checked)) { - input.checked = checked; + if (isDefined(showDescriptions)) { + bindingOptions.showDescriptions = showDescriptions.checked; } - createElement(label, "span", "check-mark"); - createElementWithHTML(label, "span", "text", labelText); - return [input, label]; - } - function isDefined(value) { - return value !== null && value !== undefined && value !== _string.empty; - } - function isDefinedObject(object) { - return isDefined(object) && typeof object === "object"; - } - function isDefinedBoolean(object) { - return isDefined(object) && typeof object === "boolean"; - } - function isDefinedString(object) { - return isDefined(object) && typeof object === "string"; - } - function isDefinedFunction(object) { - return isDefined(object) && typeof object === "function"; - } - function isDefinedNumber(object) { - return isDefined(object) && typeof object === "number"; - } - function isDefinedArray(object) { - return isDefinedObject(object) && object instanceof Array; - } - function fireCustomTrigger(triggerFunction) { - if (isDefinedFunction(triggerFunction)) { - triggerFunction.apply(null, [].slice.call(arguments, 1)); + if (isDefined(showContents)) { + bindingOptions.showContents = showContents.checked; } + renderControlContainer(bindingOptions); + }; + if (bindingOptions.showChildrenToggle) { + showChildren = buildCheckBox(footer, _configuration.showChildrenLabelText, bindingOptions.showChildren, onClick)[0]; + } + if (bindingOptions.showDescriptionsToggle) { + showDescriptions = buildCheckBox(footer, _configuration.showDescriptionsLabelText, bindingOptions.showDescriptions, onClick)[0]; + } + if (bindingOptions.showContentsToggle) { + showContents = buildCheckBox(footer, _configuration.showContentsLabelText, bindingOptions.showContents, onClick)[0]; + } + } + function renderControlToolTip(bindingOptions) { + if (!isDefined(bindingOptions.currentView.tooltip)) { + bindingOptions.currentView.tooltip = createElement(_parameter_Document.body, "div", "tree-js-tooltip"); + bindingOptions.currentView.tooltip.style.display = "none"; + _parameter_Document.body.addEventListener("mousemove", function() { + hideToolTip(bindingOptions); + }); + _parameter_Document.addEventListener("scroll", function() { + hideToolTip(bindingOptions); + }); } - function getDefaultString(value, defaultValue) { - return isDefinedString(value) ? value : defaultValue; - } - function getDefaultBoolean(value, defaultValue) { - return isDefinedBoolean(value) ? value : defaultValue; - } - function getDefaultFunction(value, defaultValue) { - return isDefinedFunction(value) ? value : defaultValue; - } - function getDefaultArray(value, defaultValue) { - return isDefinedArray(value) ? value : defaultValue; + } + function addToolTip(element, bindingOptions, text) { + if (element !== null) { + element.onmousemove = function(e) { + showToolTip(e, bindingOptions, text); + }; } - function getDefaultNumber(value, defaultValue) { - return isDefinedNumber(value) ? value : defaultValue; + } + function showToolTip(e, bindingOptions, text) { + cancelBubble(e); + hideToolTip(bindingOptions); + bindingOptions.currentView.tooltipTimer = setTimeout(function() { + bindingOptions.currentView.tooltip.innerHTML = text; + bindingOptions.currentView.tooltip.style.display = "block"; + showElementAtMousePosition(e, bindingOptions.currentView.tooltip); + }, bindingOptions.tooltipDelay); + } + function hideToolTip(bindingOptions) { + if (isDefined(bindingOptions.currentView.tooltip)) { + if (isDefined(bindingOptions.currentView.tooltipTimer)) { + clearTimeout(bindingOptions.currentView.tooltipTimer); + bindingOptions.currentView.tooltipTimer = null; + } + if (bindingOptions.currentView.tooltip.style.display === "block") { + bindingOptions.currentView.tooltip.style.display = "none"; + } } - function getDefaultStringOrArray(value, defaultValue) { - if (isDefinedString(value)) { - value = value.split(_string.space); - if (value.length === 0) { - value = defaultValue; + } + function getRowsAndBoxes(bindingOptions, data, isChildren) { + var boxesDetails = getBoxesAndMaximumPerRow(bindingOptions, data, isChildren); + var boxesPerRow = {}; + var largestAmountOfBoxesOnARow = 0; + var rowNumber = 0; + if (boxesDetails.maximum > 0) { + rowNumber = 1; + boxesDetails.boxes = boxesDetails.boxes.sort(function(a, b) { + return b.value - a.value; + }); + var startIndex = 0; + var endIndex = boxesDetails.maximum; + var dataLength = boxesDetails.boxes.length; + for (; true;) { + var breakOnceProcessed = false; + boxesPerRow[rowNumber] = []; + if (endIndex > dataLength) { + endIndex = dataLength; + breakOnceProcessed = true; + } + var arrayIndex = startIndex; + for (; arrayIndex < endIndex; arrayIndex++) { + boxesPerRow[rowNumber].push(boxesDetails.boxes[arrayIndex]); + } + largestAmountOfBoxesOnARow = _parameter_Math.max(boxesPerRow[rowNumber].length, largestAmountOfBoxesOnARow); + if (breakOnceProcessed) { + break; + } else { + startIndex = endIndex; + endIndex = endIndex + (boxesDetails.maximum + rowNumber * 2); + rowNumber++; } - } else { - value = getDefaultArray(value, defaultValue); } - return value; } - function getObjectFromString(objectString) { - var parsed = true; - var result = null; - try { - if (isDefinedString(objectString)) { - result = _parameter_JSON.parse(objectString); + return {boxesPerRow:boxesPerRow, largestAmountOfBoxesOnARow:largestAmountOfBoxesOnARow, totalRows:rowNumber}; + } + function getBoxesAndMaximumPerRow(bindingOptions, data, isChildren) { + var boxes = []; + var maximumBoxes = 0; + var dataLength = data.length; + if (dataLength > 1) { + var dataIndex = 0; + for (; dataIndex < dataLength; dataIndex++) { + var dataItem = data[dataIndex]; + if (!isDefinedString(dataItem.id)) { + dataItem.id = newGuid(); } - } catch (e1) { - try { - result = eval("(" + objectString + ")"); - if (isDefinedFunction(result)) { - result = result(); + if (!isChildren && isDefined(bindingOptions.currentView.fullScreenBoxId)) { + if (dataItem.id === bindingOptions.currentView.fullScreenBoxId) { + boxes.push(dataItem); } - } catch (e2) { - if (!_configuration.safeMode) { - console.error("Errors in object: " + e1.message + ", " + e2.message); - parsed = false; + } else { + if (isChildren || !isDefinedString(dataItem.category) || !isDefinedString(bindingOptions.currentView.category) || bindingOptions.currentView.category === dataItem.category) { + boxes.push(dataItem); } - result = null; } } - return {parsed:parsed, result:result}; - } - function newGuid() { - var result = []; - var charIndex = 0; - for (; charIndex < 32; charIndex++) { - if (charIndex === 8 || charIndex === 12 || charIndex === 16 || charIndex === 20) { - result.push("-"); - } - var character = _parameter_Math.floor(_parameter_Math.random() * 16).toString(16); - result.push(character); + var totalItems = boxes.length; + var totalRows = bindingOptions.maximumRows; + maximumBoxes = totalItems / totalRows; + for (; maximumBoxes < 1.0;) { + totalRows--; + maximumBoxes = totalItems / totalRows; } - return result.join(_string.empty); - } - function buildDefaultConfiguration(newConfiguration) { - _configuration = !isDefinedObject(newConfiguration) ? {} : newConfiguration; - _configuration.safeMode = getDefaultBoolean(_configuration.safeMode, true); - _configuration.domElementTypes = getDefaultStringOrArray(_configuration.domElementTypes, ["*"]); - buildDefaultConfigurationStrings(); - } - function buildDefaultConfigurationStrings() { - _configuration.backButtonText = getDefaultString(_configuration.backButtonText, "Back"); - _configuration.nextButtonText = getDefaultString(_configuration.nextButtonText, "Next"); - _configuration.showChildrenLabelText = getDefaultString(_configuration.showChildrenLabelText, "Show Children"); - _configuration.showDescriptionsLabelText = getDefaultString(_configuration.showDescriptionsLabelText, "Show Descriptions"); - _configuration.showContentsLabelText = getDefaultString(_configuration.showContentsLabelText, "Show Contents"); - _configuration.noDataMessage = getDefaultString(_configuration.noDataMessage, "There is currently no data to view."); - _configuration.expandToolTipText = getDefaultString(_configuration.expandToolTipText, "Expand"); - _configuration.contractToolTipText = getDefaultString(_configuration.contractToolTipText, "Contract"); - } - var _parameter_Document = null; - var _parameter_Window = null; - var _parameter_Math = null; - var _parameter_JSON = null; - var _configuration = {}; - var _string = {empty:"", space:" "}; - var _elements_Type = {}; - var _elements_Data = {}; - var _attribute_Name_Options = "data-tree-options"; - this.setConfiguration = function(newConfiguration) { - var propertyName; - for (propertyName in newConfiguration) { - if (newConfiguration.hasOwnProperty(propertyName)) { - _configuration[propertyName] = newConfiguration[propertyName]; + } + return {maximum:_parameter_Math.round(maximumBoxes), boxes:boxes}; + } + function getCategories(bindingOptions) { + var categories = []; + var dataLength = bindingOptions.data.length; + var dataIndex = 0; + for (; dataIndex < dataLength; dataIndex++) { + var data = bindingOptions.data[dataIndex]; + if (isDefinedString(data.category) && categories.indexOf(data.category) === -1) { + categories.push(data.category); + } + } + return categories; + } + function buildAttributeOptions(newOptions) { + var options = !isDefinedObject(newOptions) ? {} : newOptions; + options.data = getDefaultArray(options.data, []); + options.maximumRows = getDefaultNumber(options.maximumRows, 10); + options.spacing = getDefaultNumber(options.spacing, 10); + options.maximumBoxHeight = getDefaultNumber(options.maximumBoxHeight, 200); + options.reverseOrder = getDefaultBoolean(options.reverseOrder, false); + options.showBoxGaps = getDefaultBoolean(options.showBoxGaps, true); + options.swapSizes = getDefaultBoolean(options.swapSizes, false); + options.showBoxGapsForChildren = getDefaultBoolean(options.showBoxGapsForChildren, false); + options.allowBoxExpanding = getDefaultBoolean(options.allowBoxExpanding, true); + options.showTitle = getDefaultBoolean(options.showTitle, true); + options.showChildren = getDefaultBoolean(options.showChildren, true); + options.showDescriptions = getDefaultBoolean(options.showDescriptions, true); + options.showContents = getDefaultBoolean(options.showContents, true); + options.tooltipDelay = getDefaultNumber(options.tooltipDelay, 750); + options.showChildrenToggle = getDefaultBoolean(options.showChildrenToggle, true); + options.showDescriptionsToggle = getDefaultBoolean(options.showDescriptionsToggle, true); + options.showContentsToggle = getDefaultBoolean(options.showContentsToggle, true); + options.showCategorySelector = getDefaultBoolean(options.showCategorySelector, true); + options.showCategorySelectionDropDown = getDefaultBoolean(options.showCategorySelectionDropDown, true); + options = buildAttributeOptionCustomTriggers(options); + options = buildAttributeOptionStrings(options); + return options; + } + function buildAttributeOptionStrings(options) { + options.titleText = getDefaultString(options.titleText, "Tree.js"); + return options; + } + function buildAttributeOptionCustomTriggers(options) { + options.onBeforeRender = getDefaultFunction(options.onBeforeRender, null); + options.onRenderComplete = getDefaultFunction(options.onRenderComplete, null); + options.onBoxClick = getDefaultFunction(options.onBoxClick, null); + options.onBackCategory = getDefaultFunction(options.onBackCategory, null); + options.onNextCategory = getDefaultFunction(options.onNextCategory, null); + options.onSetCategory = getDefaultFunction(options.onSetCategory, null); + return options; + } + function createElement(container, type, className) { + var result = null; + var nodeType = type.toLowerCase(); + var isText = nodeType === "text"; + if (!_elements_Type.hasOwnProperty(nodeType)) { + _elements_Type[nodeType] = isText ? _parameter_Document.createTextNode(_string.empty) : _parameter_Document.createElement(nodeType); + } + result = _elements_Type[nodeType].cloneNode(false); + if (isDefined(className)) { + result.className = className; + } + container.appendChild(result); + return result; + } + function createElementWithHTML(container, type, className, html) { + var element = createElement(container, type, className); + element.innerHTML = html; + return element; + } + function getScrollPosition() { + var doc = _parameter_Document.documentElement; + var left = (_parameter_Window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0); + var top = (_parameter_Window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); + return {left:left, top:top}; + } + function showElementAtMousePosition(e, element) { + var left = e.pageX; + var top = e.pageY; + var scrollPosition = getScrollPosition(); + element.style.display = "block"; + if (left + element.offsetWidth > _parameter_Window.innerWidth) { + left = left - element.offsetWidth; + } else { + left++; + } + if (top + element.offsetHeight > _parameter_Window.innerHeight) { + top = top - element.offsetHeight; + } else { + top++; + } + if (left < scrollPosition.left) { + left = e.pageX + 1; + } + if (top < scrollPosition.top) { + top = e.pageY + 1; + } + element.style.left = left + "px"; + element.style.top = top + "px"; + } + function reverseElementsOrder(parent) { + var children = parent.children; + var childrenLength = children.length - 1; + for (; childrenLength--;) { + parent.appendChild(children[childrenLength]); + } + } + function addClass(element, className) { + element.className += _string.space + className; + } + function cancelBubble(e) { + e.preventDefault(); + e.cancelBubble = true; + } + function buildCheckBox(container, labelText, checked, onClick) { + var label = createElement(container, "label", "checkbox"); + var input = createElement(label, "input"); + input.type = "checkbox"; + if (isDefined(onClick)) { + input.onclick = onClick; + } + if (isDefined(checked)) { + input.checked = checked; + } + createElement(label, "span", "check-mark"); + createElementWithHTML(label, "span", "text", labelText); + return [input, label]; + } + function isDefined(value) { + return value !== null && value !== undefined && value !== _string.empty; + } + function isDefinedObject(object) { + return isDefined(object) && typeof object === "object"; + } + function isDefinedBoolean(object) { + return isDefined(object) && typeof object === "boolean"; + } + function isDefinedString(object) { + return isDefined(object) && typeof object === "string"; + } + function isDefinedFunction(object) { + return isDefined(object) && typeof object === "function"; + } + function isDefinedNumber(object) { + return isDefined(object) && typeof object === "number"; + } + function isDefinedArray(object) { + return isDefinedObject(object) && object instanceof Array; + } + function fireCustomTrigger(triggerFunction) { + if (isDefinedFunction(triggerFunction)) { + triggerFunction.apply(null, [].slice.call(arguments, 1)); + } + } + function getDefaultString(value, defaultValue) { + return isDefinedString(value) ? value : defaultValue; + } + function getDefaultBoolean(value, defaultValue) { + return isDefinedBoolean(value) ? value : defaultValue; + } + function getDefaultFunction(value, defaultValue) { + return isDefinedFunction(value) ? value : defaultValue; + } + function getDefaultArray(value, defaultValue) { + return isDefinedArray(value) ? value : defaultValue; + } + function getDefaultNumber(value, defaultValue) { + return isDefinedNumber(value) ? value : defaultValue; + } + function getDefaultStringOrArray(value, defaultValue) { + if (isDefinedString(value)) { + value = value.split(_string.space); + if (value.length === 0) { + value = defaultValue; + } + } else { + value = getDefaultArray(value, defaultValue); + } + return value; + } + function getObjectFromString(objectString) { + var parsed = true; + var result = null; + try { + if (isDefinedString(objectString)) { + result = _parameter_JSON.parse(objectString); + } + } catch (e1) { + try { + result = eval("(" + objectString + ")"); + if (isDefinedFunction(result)) { + result = result(); } - } - buildDefaultConfiguration(_configuration); - return this; - }; - this.getVersion = function() { - return "0.1.0"; - }; - (function(documentObject, windowObject, mathObject, jsonObject) { - _parameter_Document = documentObject; - _parameter_Window = windowObject; - _parameter_Math = mathObject; - _parameter_JSON = jsonObject; - buildDefaultConfiguration(); - _parameter_Document.addEventListener("DOMContentLoaded", function() { - render(); - }); - if (!isDefined(_parameter_Window.$tree)) { - _parameter_Window.$tree = this; - } - })(document, window, Math, JSON); - })(); \ No newline at end of file + } catch (e2) { + if (!_configuration.safeMode) { + console.error("Errors in object: " + e1.message + ", " + e2.message); + parsed = false; + } + result = null; + } + } + return {parsed:parsed, result:result}; + } + function newGuid() { + var result = []; + var charIndex = 0; + for (; charIndex < 32; charIndex++) { + if (charIndex === 8 || charIndex === 12 || charIndex === 16 || charIndex === 20) { + result.push("-"); + } + var character = _parameter_Math.floor(_parameter_Math.random() * 16).toString(16); + result.push(character); + } + return result.join(_string.empty); + } + function buildDefaultConfiguration(newConfiguration) { + _configuration = !isDefinedObject(newConfiguration) ? {} : newConfiguration; + _configuration.safeMode = getDefaultBoolean(_configuration.safeMode, true); + _configuration.domElementTypes = getDefaultStringOrArray(_configuration.domElementTypes, ["*"]); + buildDefaultConfigurationStrings(); + } + function buildDefaultConfigurationStrings() { + _configuration.backButtonText = getDefaultString(_configuration.backButtonText, "Back"); + _configuration.nextButtonText = getDefaultString(_configuration.nextButtonText, "Next"); + _configuration.showChildrenLabelText = getDefaultString(_configuration.showChildrenLabelText, "Show Children"); + _configuration.showDescriptionsLabelText = getDefaultString(_configuration.showDescriptionsLabelText, "Show Descriptions"); + _configuration.showContentsLabelText = getDefaultString(_configuration.showContentsLabelText, "Show Contents"); + _configuration.noDataMessage = getDefaultString(_configuration.noDataMessage, "There is currently no data to view."); + _configuration.expandToolTipText = getDefaultString(_configuration.expandToolTipText, "Expand"); + _configuration.contractToolTipText = getDefaultString(_configuration.contractToolTipText, "Contract"); + } + var _parameter_Document = null; + var _parameter_Window = null; + var _parameter_Math = null; + var _parameter_JSON = null; + var _configuration = {}; + var _string = {empty:"", space:" "}; + var _elements_Type = {}; + var _elements_Data = {}; + var _attribute_Name_Options = "data-tree-options"; + this.setConfiguration = function(newConfiguration) { + var propertyName; + for (propertyName in newConfiguration) { + if (newConfiguration.hasOwnProperty(propertyName)) { + _configuration[propertyName] = newConfiguration[propertyName]; + } + } + buildDefaultConfiguration(_configuration); + return this; + }; + this.getVersion = function() { + return "0.2.0"; + }; + (function(documentObject, windowObject, mathObject, jsonObject) { + _parameter_Document = documentObject; + _parameter_Window = windowObject; + _parameter_Math = mathObject; + _parameter_JSON = jsonObject; + buildDefaultConfiguration(); + _parameter_Document.addEventListener("DOMContentLoaded", function() { + render(); + }); + if (!isDefined(_parameter_Window.$tree)) { + _parameter_Window.$tree = this; + } + })(document, window, Math, JSON); +})(); \ No newline at end of file diff --git a/dist/tree.js.css b/dist/tree.js.css index d49d045..2e55a4a 100755 --- a/dist/tree.js.css +++ b/dist/tree.js.css @@ -1,5 +1,5 @@ /* - * Tree.js Library v0.1.0 + * Tree.js Library v0.2.0 * * Copyright 2024 Bunoon * Released under the MIT License diff --git a/dist/tree.js.min.css b/dist/tree.js.min.css index f54b862..4dfeda8 100755 --- a/dist/tree.js.min.css +++ b/dist/tree.js.min.css @@ -1,2 +1,2 @@ -/* Tree.js v0.1.0 | (c) Bunoon 2024 | MIT License */ +/* Tree.js v0.2.0 | (c) Bunoon 2024 | MIT License */ :root{--tree-js-default-font:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--tree-js-text-bold-weight:400;--tree-js-title-bold-weight:900;--tree-js-text-bold-weight-active:900;--tree-js-color-black:#3b3a3a;--tree-js-color-white:#F5F5F5;--tree-js-color-snow-white:#F5F5F5;--tree-js-container-background-color:#22272e;--tree-js-container-border-color:#454c56;--tree-js-tooltip-background-color:var(--tree-js-container-background-color);--tree-js-tooltip-border-color:var(--tree-js-container-border-color);--tree-js-tooltip-text-color:var(--tree-js-color-white);--tree-js-categories-opener-text-color-hover:var(--tree-js-color-gray);--tree-js-categories-background-color:var(--tree-js-container-background-color);--tree-js-categories-border-color:var(--tree-js-container-border-color);--tree-js-categories-text-color:var(--tree-js-color-white);--tree-js-categories-background-color-hover:var(--tree-js-button-background-color-hover);--tree-js-categories-text-color-hover:var(--tree-js-color-snow-white);--tree-js-button-background-color:#2d333b;--tree-js-button-border-color:var(--tree-js-container-border-color);--tree-js-button-text-color:var(--tree-js-color-white);--tree-js-button-background-color-hover:var(--tree-js-container-border-color);--tree-js-button-text-color-hover:var(--tree-js-color-snow-white);--tree-js-button-background-color-active:#616b79;--tree-js-button-text-color-active:var(--tree-js-color-snow-white);--tree-js-border-radius:.5rem;--tree-js-border-control-radius:.25rem;--tree-js-border-style-scrollbar:inset 0 0 6px var(--tree-js-color-dark-gray);--tree-js-border-size:.5px;--tree-js-checkbox-background-color-checked:rgba(80,200,120,1);--tree-js-checkbox-background-color:var(--tree-js-color-black);--tree-js-checkbox-border-color-checked:--tree-js-checkbox-background-color-checked;--tree-js-checkbox-border-color:rgba(80,200,120,.55);--tree-js-box-size:12.5px;--tree-js-box-border-size:3.5px;--tree-js-spacing:10px;--tree-js-spacing-font-size:.85rem;--tree-js-transition:all .3s;--tree-js-animation-length:0.5s}div.tree-js{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;cursor:default;box-sizing:border-box;line-height:normal;font-family:var(--tree-js-default-font);display:inline-block;position:relative;border-radius:var(--tree-js-border-radius);background-color:var(--tree-js-container-background-color);color:var(--tree-js-color-white);border:var(--tree-js-border-size) solid var(--tree-js-container-border-color);padding:var(--tree-js-spacing);font-size:var(--tree-js-spacing-font-size);width:100%;overflow:hidden;margin:0!important}div.tree-js div.no-click{pointer-events:none!important}div.tree-js *{box-sizing:border-box;line-height:normal}div.tree-js *::before,div.tree-js *::after{box-sizing:border-box;line-height:normal}div.tree-js div.title-bar{display:flex;margin-bottom:calc(var(--tree-js-spacing) / 2)}div.tree-js div.title-bar div.title{text-align:left;width:auto;font-weight:var(--tree-js-title-bold-weight);font-size:1.2rem}div.tree-js div.title-bar div.controls{margin-left:var(--tree-js-spacing);flex-grow:1;text-align:right}div.tree-js div.title-bar div.controls button{background-color:var(--tree-js-button-background-color);border:var(--tree-js-border-size) solid var(--tree-js-button-border-color);color:var(--tree-js-button-text-color);border-radius:var(--tree-js-border-radius);padding-top:5px;padding-bottom:5px;padding-left:9px;padding-right:9px;outline:none;transition:var(--tree-js-transition)}div.tree-js div.title-bar div.controls button:not(.active):active{background:var(--tree-js-button-background-color-active)!important;color:var(--tree-js-button-text-color-active)!important}div.tree-js div.title-bar div.controls button:not(.active):hover{cursor:pointer;background:var(--tree-js-button-background-color-hover);color:var(--tree-js-button-text-color-hover)}div.tree-js div.title-bar div.controls button.active{cursor:default;background:var(--tree-js-button-background-color-hover);color:var(--tree-js-button-text-color-hover);transition:var(--tree-js-transition);font-weight:var(--tree-js-text-bold-weight-active)}div.tree-js div.title-bar div.controls div.category-text{margin-left:var(--tree-js-spacing);margin-right:var(--tree-js-spacing);display:inline-block;font-weight:var(--tree-js-title-bold-weight);position:relative;padding-top:5px;padding-bottom:5px;transition:var(--tree-js-transition);cursor:pointer}div.tree-js div.title-bar div.controls div.category-text:hover{color:var(--tree-js-categories-opener-text-color-hover)}div.tree-js div.title-bar div.controls div.category-text:hover div.down-arrow{border-top-color:var(--tree-js-categories-opener-text-color-hover)}div.tree-js div.title-bar div.controls div.category-text:hover div.categories-list{display:block!important}div.tree-js div.title-bar div.controls div.category-text div.down-arrow{display:inline-block;width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:9px solid var(--tree-js-color-white);transition:var(--tree-js-transition);margin-left:calc(var(--tree-js-spacing) / 2)}div.tree-js div.title-bar div.controls div.category-text div.categories-list{animation:fade-in-animation var(--tree-js-animation-length);padding-top:5px;display:none;position:absolute;width:150px;left:50%;transform:translateX(-50%);margin-top:5px;z-index:1000}div.tree-js div.title-bar div.controls div.category-text div.categories-list div.categories{border-radius:var(--tree-js-border-radius);background-color:var(--tree-js-categories-background-color);border:var(--tree-js-border-size) solid var(--tree-js-categories-border-color);color:var(--tree-js-categories-text-color);max-height:183px;overflow-y:scroll;scroll-snap-type:y mandatory}div.tree-js div.title-bar div.controls div.category-text div.categories-list div.categories div.category{color:var(--tree-js-color-white);font-weight:var(--tree-js-text-bold-weight);border-bottom:var(--tree-js-border-size) dashed var(--tree-js-container-border-color);padding:var(--tree-js-spacing);text-align:center;width:100%;transition:var(--tree-js-transition);scroll-snap-align:start}div.tree-js div.title-bar div.controls div.category-text div.categories-list div.categories div.category:not(.category-active):active{opacity:0.5!important}div.tree-js div.title-bar div.controls div.category-text div.categories-list div.categories div.category:not(.category-active):hover{cursor:pointer;background-color:var(--tree-js-categories-background-color-hover);color:var(--tree-js-categories-text-color-hover)}div.tree-js div.title-bar div.controls div.category-text div.categories-list div.categories div.category:last-child{border-bottom:none}div.tree-js div.title-bar div.controls div.category-text div.categories-list div.categories div.category-active{background-color:var(--tree-js-categories-background-color-hover);color:var(--tree-js-categories-text-color-hover);font-weight:var(--tree-js-text-bold-weight-active);cursor:default!important}div.tree-js div.box-rows div.no-data{text-align:center;padding:30px}div.tree-js div.box-rows div.box-row-no-spacing{display:flex;justify-content:space-between}div.tree-js div.box-rows div.box-row{text-align:center}div.tree-js div.box-rows div.box-row div.box{display:inline-block;position:relative;border-radius:var(--tree-js-border-radius);background-color:rgb(80,200,120);color:var(--tree-js-color-black);border:var(--tree-js-border-size) solid rgba(80,200,120,.75);padding:var(--tree-js-spacing);margin:calc(var(--tree-js-spacing) / 2);flex-basis:100%;transition:opacity 0.3s;white-space:wrap;text-align:left;overflow-y:scroll;overflow-x:hidden}div.tree-js div.box-rows div.box-row div.box div.children div.box{background-color:rgb(210,43,43);color:var(--tree-js-color-white);border:var(--tree-js-border-size) solid rgba(210,43,43,.75)}div.tree-js div.box-rows div.box-row div.box div.box-title-bar{display:flex;font-size:1rem!important;align-items:center!important;margin-bottom:calc(var(--tree-js-spacing) / 2)}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.box-title{text-align:left;font-weight:var(--tree-js-title-bold-weight)!important;margin-right:var(--tree-js-spacing)}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.box-value{flex-grow:1;text-align:right;font-weight:var(--tree-js-text-bold-weight)!important}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.expand,div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.contract{display:inline-block;height:var(--tree-js-box-size);width:var(--tree-js-box-size);transition:var(--tree-js-transition);margin-left:calc(var(--tree-js-spacing) / 2)}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.expand:hover,div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.contract:hover{opacity:.7}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.expand{border-radius:var(--tree-js-border-control-radius);border:var(--tree-js-box-border-size) solid var(--tree-js-color-black)}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.contract{position:relative}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.contract::before{content:"";position:absolute;left:0;height:var(--tree-js-box-border-size);width:var(--tree-js-box-size);background-color:var(--tree-js-color-black);top:50%;transform:translate(0,-50%)}div.tree-js div.box-rows div.box-row div.box div.box-title-bar div.contract:hover{opacity:.7}div.tree-js div.box-rows div.box-row div.box p.description{margin:0!important;padding:0!important;margin-bottom:var(--tree-js-spacing)!important}div.tree-js div.box-rows div.box-row div.box:first-child{margin-left:0}div.tree-js div.box-rows div.box-row div.box:last-child{margin-right:0}div.tree-js div.box-rows div.box-row div.box:hover{cursor:pointer;opacity:.8}div.tree-js div.footer{text-align:center}@media (min-width:768px){div.tree-js div.footer{text-align:right}}div.tree-js div.footer label.checkbox{margin:calc(var(--tree-js-spacing) / 2);margin-right:var(--tree-js-spacing)}div.tree-js div.footer label.checkbox:last-child{margin-right:calc(var(--tree-js-spacing) / 2)}div.tree-js label.checkbox{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;cursor:default;display:inline-block;position:relative;padding-left:25px;padding-top:1px;color:var(--tree-js-color-white)}div.tree-js label.checkbox input{display:none!important}div.tree-js label.checkbox input:checked~span.check-mark{background-color:var(--tree-js-checkbox-background-color-checked);border:var(--tree-js-border-size) solid var(--tree-js-checkbox-border-color-checked)}div.tree-js label.checkbox input:checked~span.check-mark::before{display:block}div.tree-js label.checkbox input:disabled~span.check-mark,div.tree-js label.checkbox input:disabled~span.text{opacity:.5}div.tree-js label.checkbox input:disabled~span.check-mark{border:var(--tree-js-border-size) solid var(--tree-js-color-black)!important}div.tree-js label.checkbox span.check-mark{position:absolute;top:1px;left:0;height:15px;width:15px;background-color:var(--tree-js-checkbox-background-color);border-radius:var(--tree-js-border-control-radius);border:var(--tree-js-border-size) solid var(--tree-js-checkbox-border-color);transition:var(--tree-js-transition)}div.tree-js label.checkbox span.check-mark::before{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg);content:"";position:absolute;display:none;left:4.5px;top:1px;width:6px;height:10px;border:solid var(--tree-js-color-black);border-width:0 2px 2px 0}.custom-scroll-bars::-webkit-scrollbar{width:12px}.custom-scroll-bars::-webkit-scrollbar-track{-webkit-box-shadow:var(--tree-js-border-style-scrollbar);box-shadow:var(--tree-js-border-style-scrollbar)}.custom-scroll-bars::-webkit-scrollbar-thumb{-webkit-box-shadow:var(--tree-js-border-style-scrollbar);box-shadow:var(--tree-js-border-style-scrollbar);background:var(--tree-js-color-white)}.custom-scroll-bars::-webkit-scrollbar-thumb:hover{background-color:var(--tree-js-color-white)}.custom-scroll-bars::-webkit-scrollbar-thumb:active{background-color:var(--tree-js-color-lighter-gray)}div.tree-js-tooltip{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;cursor:default;box-sizing:border-box;line-height:normal;font-family:var(--tree-js-default-font);animation:fade-in-animation var(--tree-js-animation-length);position:absolute;background-color:var(--tree-js-tooltip-background-color);border:var(--tree-js-border-size) solid var(--tree-js-tooltip-border-color);color:var(--tree-js-tooltip-text-color);border-radius:var(--tree-js-border-radius);z-index:2000;max-width:300px;padding:var(--tree-js-spacing);font-size:var(--tree-js-spacing-font-size);font-weight:var(--tree-js-text-bold-weight);display:none}@keyframes fade-in-animation{0%{opacity:0}100%{opacity:1}} \ No newline at end of file diff --git a/dist/tree.min.js b/dist/tree.min.js index 8500f1e..5f25e21 100755 --- a/dist/tree.min.js +++ b/dist/tree.min.js @@ -1,22 +1,23 @@ -/*! Tree.js v0.1.0 | (c) Bunoon 2024 | MIT License */ -(function(){function C(a){a.currentView.element.innerHTML=u.empty;H(a);aa(a);ba(a);a.currentView.rows=m(a.currentView.element,"div","box-rows");N(a,a.currentView.rows,I[a.currentView.element.id]);ca(a);y.addEventListener("resize",function(){N(a,a.currentView.rows,I[a.currentView.element.id])})}function ba(a){var b=m(a.currentView.element,"div","title-bar");a.showTitle&&q(b,"div","title",a.titleText);if(1y.innerWidth?d-=f.offsetWidth:d++;k+f.offsetHeight>y.innerHeight?k-=f.offsetHeight:k++;dg&&(k=g,l=!0);for(;dd;)a--,d=b/a}return{maximum:G.round(d),boxes:f}}function m(a,b,e){b=b.toLowerCase();var f="text"===b;S.hasOwnProperty(b)||(S[b]=f?w.createTextNode(u.empty):w.createElement(b));b=S[b].cloneNode(!1);n(e)&& -(b.className=e);a.appendChild(b);return b}function q(a,b,e,f){a=m(a,b,e);a.innerHTML=f;return a}function O(a){a.preventDefault();a.cancelBubble=!0}function R(a,b,e,f){a=m(a,"label","checkbox");var d=m(a,"input");d.type="checkbox";n(f)&&(d.onclick=f);n(e)&&(d.checked=e);m(a,"span","check-mark");q(a,"span","text",b);return[d,a]}function n(a){return null!==a&&void 0!==a&&a!==u.empty}function L(a){return n(a)&&"object"===typeof a}function P(a){return n(a)&&"boolean"===typeof a}function p(a){return n(a)&& -"string"===typeof a}function K(a){return n(a)&&"function"===typeof a}function J(a){return n(a)&&"number"===typeof a}function Q(a){return L(a)&&a instanceof Array}function D(a){K(a)&&a.apply(null,[].slice.call(arguments,1))}function x(a,b){return p(a)?a:b}function t(a,b){return P(a)?a:b}function F(a,b){return K(a)?a:b}function M(a,b){return J(a)?a:b}function ja(a){var b=!0,e=null;try{p(a)&&(e=Y.parse(a))}catch(f){try{e=eval("("+a+")"),K(e)&&(e=e())}catch(d){h.safeMode||(console.error("Errors in object: "+ -f.message+", "+d.message),b=!1),e=null}}return{parsed:b,result:e}}function X(){for(var a=[],b=0;32>b;b++){8!==b&&12!==b&&16!==b&&20!==b||a.push("-");var e=G.floor(16*G.random()).toString(16);a.push(e)}return a.join(u.empty)}function Z(a){h=L(a)?a:{};h.safeMode=t(h.safeMode,!0);a=h;var b=h.domElementTypes,e=["*"];p(b)?(b=b.split(u.space),0===b.length&&(b=e)):b=Q(b)?b:e;a.domElementTypes=b;h.backButtonText=x(h.backButtonText,"Back");h.nextButtonText=x(h.nextButtonText,"Next");h.showChildrenLabelText= -x(h.showChildrenLabelText,"Show Children");h.showDescriptionsLabelText=x(h.showDescriptionsLabelText,"Show Descriptions");h.showContentsLabelText=x(h.showContentsLabelText,"Show Contents");h.noDataMessage=x(h.noDataMessage,"There is currently no data to view.");h.expandToolTipText=x(h.expandToolTipText,"Expand");h.contractToolTipText=x(h.contractToolTipText,"Contract")}var w=null,y=null,G=null,Y=null,h={},u={empty:"",space:" "},S={},I={};this.setConfiguration=function(a){for(var b in a)a.hasOwnProperty(b)&& -(h[b]=a[b]);Z(h);return this};this.getVersion=function(){return"0.1.0"};(function(a,b,e,f){w=a;y=b;G=e;Y=f;Z();w.addEventListener("DOMContentLoaded",function(){for(var d=h.domElementTypes,k=d.length,g=0;g +y.innerWidth?d-=e.offsetWidth:d++;k+e.offsetHeight>y.innerHeight?k-=e.offsetHeight:k++;dg&&(k=g,m=!0);for(;dd;)a--,d=b/a}return{maximum:G.round(d),boxes:e}}function n(a,b,f){b=b.toLowerCase();var e="text"===b;S.hasOwnProperty(b)||(S[b]=e?w.createTextNode(t.empty):w.createElement(b));b=S[b].cloneNode(!1);l(f)&&(b.className=f);a.appendChild(b);return b}function r(a,b,f,e){a=n(a,b,f);a.innerHTML=e;return a}function O(a){a.preventDefault();a.cancelBubble=!0}function R(a,b,f,e){a=n(a,"label","checkbox");var d=n(a,"input");d.type="checkbox";l(e)&&(d.onclick= +e);l(f)&&(d.checked=f);n(a,"span","check-mark");r(a,"span","text",b);return[d,a]}function l(a){return null!==a&&void 0!==a&&a!==t.empty}function L(a){return l(a)&&"object"===typeof a}function P(a){return l(a)&&"boolean"===typeof a}function p(a){return l(a)&&"string"===typeof a}function K(a){return l(a)&&"function"===typeof a}function J(a){return l(a)&&"number"===typeof a}function Q(a){return L(a)&&a instanceof Array}function D(a){K(a)&&a.apply(null,[].slice.call(arguments,1))}function x(a,b){return p(a)? +a:b}function q(a,b){return P(a)?a:b}function F(a,b){return K(a)?a:b}function M(a,b){return J(a)?a:b}function ja(a){var b=!0,f=null;try{p(a)&&(f=Y.parse(a))}catch(e){try{f=eval("("+a+")"),K(f)&&(f=f())}catch(d){h.safeMode||(console.error("Errors in object: "+e.message+", "+d.message),b=!1),f=null}}return{parsed:b,result:f}}function X(){for(var a=[],b=0;32>b;b++){8!==b&&12!==b&&16!==b&&20!==b||a.push("-");var f=G.floor(16*G.random()).toString(16);a.push(f)}return a.join(t.empty)}function Z(a){h=L(a)? +a:{};h.safeMode=q(h.safeMode,!0);a=h;var b=h.domElementTypes,f=["*"];p(b)?(b=b.split(t.space),0===b.length&&(b=f)):b=Q(b)?b:f;a.domElementTypes=b;h.backButtonText=x(h.backButtonText,"Back");h.nextButtonText=x(h.nextButtonText,"Next");h.showChildrenLabelText=x(h.showChildrenLabelText,"Show Children");h.showDescriptionsLabelText=x(h.showDescriptionsLabelText,"Show Descriptions");h.showContentsLabelText=x(h.showContentsLabelText,"Show Contents");h.noDataMessage=x(h.noDataMessage,"There is currently no data to view."); +h.expandToolTipText=x(h.expandToolTipText,"Expand");h.contractToolTipText=x(h.contractToolTipText,"Contract")}var w=null,y=null,G=null,Y=null,h={},t={empty:"",space:" "},S={},I={};this.setConfiguration=function(a){for(var b in a)a.hasOwnProperty(b)&&(h[b]=a[b]);Z(h);return this};this.getVersion=function(){return"0.2.0"};(function(a,b,f,e){w=a;y=b;G=f;Y=e;Z();w.addEventListener("DOMContentLoaded",function(){for(var d=h.domElementTypes,k=d.length,g=0;g + + ## Version 0.1.0: - Everything :) \ No newline at end of file diff --git a/docs/DATA_FORMAT.md b/docs/binding/DATA.md similarity index 89% rename from docs/DATA_FORMAT.md rename to docs/binding/DATA.md index 2af1478..dc59ece 100644 --- a/docs/DATA_FORMAT.md +++ b/docs/binding/DATA.md @@ -1,6 +1,6 @@ -# Tree.js - Data Format: +# Tree.js - Binding Options - Data: -Below is the format that is expected for a data item that is used when applying data via the "data-tree-options" binding attribute on a DOM element. +Below is a list of all the options supported for the property "data" used in the "data-tree-options" binding attribute for DOM elements.

diff --git a/docs/binding/OPTIONS.md b/docs/binding/OPTIONS.md index 77ad8ad..9ecb4d5 100755 --- a/docs/binding/OPTIONS.md +++ b/docs/binding/OPTIONS.md @@ -8,7 +8,7 @@ Below are all the JSON properties that can be passed in the "data-tree-options" | Type: | Name: | Description: | | --- | --- | --- | -| *Object[]* | data | The data that should be shown in the display (see ["Data Format"](../DATA_FORMAT.md) for details, defaults to []). | +| *Object[]* | data | The data that should be shown in the display (see ["Data Format"](DATA.md) for details, defaults to []). | | *number* | maximumRows | States the maximum rows that can be shown (defaults to 10). | | *number* | spacing | States the spacing that should be used around the row boxes (defaults to 10 pixels). | | *number* | maximumBoxHeight | States the maximum height a row box can be (defaults to 200 pixels). | @@ -22,6 +22,11 @@ Below are all the JSON properties that can be passed in the "data-tree-options" | *boolean* | showDescriptions | States if the descriptions for the boxes should be shown (defaults to true). | | *boolean* | showContents | States if additional box contents should be shown (when no children are available, defaults to true). | | *number* | tooltipDelay | States how long the tooltip should wait (in milliseconds) until it's shown (defaults to 750). | +| *boolean* | showChildrenToggle | States if the "Show Children" toggle check box should be shown (defaults to true). | +| *boolean* | showDescriptionsToggle | States if the "Show Descriptions" toggle check box should be shown (defaults to true). | +| *boolean* | showContentsToggle | States if the "Show Contents" toggle check box should be shown (defaults to true). | +| *boolean* | showCategorySelector | States if the category selector (and buttons) is shown (defaults to true). | +| *boolean* | showCategorySelectionDropDown | States if the category selection drop-down menu is shown (defaults to true). |
diff --git a/package.json b/package.json index f61f1fc..ed7c204 100755 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "jtree.js", "title": "Tree.js", - "description": "A lightweight JavaScript library that generates customizable trees views to visualize numerical data.", - "version": "0.1.0", + "description": "A lightweight JavaScript library that allows you to create responsive and customizable interactive tree diagrams from an array of JS objects.", + "version": "0.2.0", "main": "dist/tree.js", "homepage": "https://www.william-troup.com/tree-js/", "author": { diff --git a/src/tree.js b/src/tree.js index 4c549c0..76f193a 100755 --- a/src/tree.js +++ b/src/tree.js @@ -1,10 +1,10 @@ /** * Tree.js * - * A lightweight JavaScript library that generates customizable trees views to visualize numerical data. + * A lightweight JavaScript library that allows you to create responsive and customizable interactive tree diagrams from an array of JS objects. * * @file tree.js - * @version v0.1.0 + * @version v0.2.0 * @author Bunoon * @license MIT License * @copyright Bunoon 2024 @@ -158,57 +158,65 @@ } if ( bindingOptions.currentView.categories.length > 1 ) { - var controls = createElement( titleBar, "div", "controls" ), - back = createElementWithHTML( controls, "button", "back", _configuration.backButtonText ); - - back.onclick = function() { - if ( bindingOptions.currentView.categoryIndex > 0 ) { - bindingOptions.currentView.categoryIndex--; - bindingOptions.currentView.category = bindingOptions.currentView.categories[ bindingOptions.currentView.categoryIndex ]; - - renderControlContainer( bindingOptions ); - fireCustomTrigger( bindingOptions.onBackCategory, bindingOptions.currentView.category ); - } - }; - - bindingOptions.currentView.categoryText = createElementWithHTML( controls, "div", "category-text", bindingOptions.currentView.category ); - - createElement( bindingOptions.currentView.categoryText, "div", "down-arrow" ); + var controls = createElement( titleBar, "div", "controls" ); - var categoriesList = createElement( bindingOptions.currentView.categoryText, "div", "categories-list" ), - categories = createElement( categoriesList, "div", "categories" ), - activeCategory = null, - categoriesLength = bindingOptions.currentView.categories.length; - - categoriesList.style.display = "block"; - categoriesList.style.visibility = "hidden"; - - for ( var categoryIndex = 0; categoryIndex < categoriesLength; categoryIndex++ ) { - var category = renderControlTitleBarCategory( bindingOptions, categories, bindingOptions.currentView.categories[ categoryIndex ] ); - - if ( !isDefined( activeCategory ) ) { - activeCategory = category; + if ( bindingOptions.showCategorySelector ) { + var back = createElementWithHTML( controls, "button", "back", _configuration.backButtonText ); + + back.onclick = function() { + if ( bindingOptions.currentView.categoryIndex > 0 ) { + bindingOptions.currentView.categoryIndex--; + bindingOptions.currentView.category = bindingOptions.currentView.categories[ bindingOptions.currentView.categoryIndex ]; + + renderControlContainer( bindingOptions ); + fireCustomTrigger( bindingOptions.onBackCategory, bindingOptions.currentView.category ); + } + }; + + bindingOptions.currentView.categoryText = createElementWithHTML( controls, "div", "category-text", bindingOptions.currentView.category ); + + if ( bindingOptions.showCategorySelectionDropDown ) { + createElement( bindingOptions.currentView.categoryText, "div", "down-arrow" ); + + var categoriesList = createElement( bindingOptions.currentView.categoryText, "div", "categories-list" ), + categories = createElement( categoriesList, "div", "categories" ), + activeCategory = null, + categoriesLength = bindingOptions.currentView.categories.length; + + categoriesList.style.display = "block"; + categoriesList.style.visibility = "hidden"; + + for ( var categoryIndex = 0; categoryIndex < categoriesLength; categoryIndex++ ) { + var category = renderControlTitleBarCategory( bindingOptions, categories, bindingOptions.currentView.categories[ categoryIndex ] ); + + if ( !isDefined( activeCategory ) ) { + activeCategory = category; + } + } + + if ( isDefined( activeCategory ) ) { + categories.scrollTop = activeCategory.offsetTop - ( categories.offsetHeight / 2 ); + } + + categoriesList.style.display = "none"; + categoriesList.style.visibility = "visible"; + + } else { + addClass( bindingOptions.currentView.categoryText, "no-click" ); } + + var next = createElementWithHTML( controls, "button", "next", _configuration.nextButtonText ); + + next.onclick = function() { + if ( bindingOptions.currentView.categoryIndex < categoriesLength - 1 ) { + bindingOptions.currentView.categoryIndex++; + bindingOptions.currentView.category = bindingOptions.currentView.categories[ bindingOptions.currentView.categoryIndex ]; + + renderControlContainer( bindingOptions ); + fireCustomTrigger( bindingOptions.onNextCategory, bindingOptions.currentView.category ); + } + }; } - - if ( isDefined( activeCategory ) ) { - categories.scrollTop = activeCategory.offsetTop - ( categories.offsetHeight / 2 ); - } - - categoriesList.style.display = "none"; - categoriesList.style.visibility = "visible"; - - var next = createElementWithHTML( controls, "button", "next", _configuration.nextButtonText ); - - next.onclick = function() { - if ( bindingOptions.currentView.categoryIndex < categoriesLength - 1 ) { - bindingOptions.currentView.categoryIndex++; - bindingOptions.currentView.category = bindingOptions.currentView.categories[ bindingOptions.currentView.categoryIndex ]; - - renderControlContainer( bindingOptions ); - fireCustomTrigger( bindingOptions.onNextCategory, bindingOptions.currentView.category ); - } - }; } } @@ -410,19 +418,38 @@ */ function renderControlFooter( bindingOptions ) { - var footer = createElement( bindingOptions.currentView.element, "div", "footer" ); + var footer = createElement( bindingOptions.currentView.element, "div", "footer" ), + showChildren = null, + showDescriptions = null, + showContents = null; var onClick = function() { - bindingOptions.showChildren = showChildren.checked; - bindingOptions.showDescriptions = showDescriptions.checked; - bindingOptions.showContents = showContents.checked; + if ( isDefined( showChildren ) ) { + bindingOptions.showChildren = showChildren.checked; + } + + if ( isDefined( showDescriptions ) ) { + bindingOptions.showDescriptions = showDescriptions.checked; + } + + if ( isDefined( showContents ) ) { + bindingOptions.showContents = showContents.checked; + } renderControlContainer( bindingOptions ); }; - var showChildren = buildCheckBox( footer, _configuration.showChildrenLabelText, bindingOptions.showChildren, onClick )[ 0 ], - showDescriptions = buildCheckBox( footer, _configuration.showDescriptionsLabelText, bindingOptions.showDescriptions, onClick )[ 0 ], + if ( bindingOptions.showChildrenToggle ) { + showChildren = buildCheckBox( footer, _configuration.showChildrenLabelText, bindingOptions.showChildren, onClick )[ 0 ]; + } + + if ( bindingOptions.showDescriptionsToggle ) { + showDescriptions = buildCheckBox( footer, _configuration.showDescriptionsLabelText, bindingOptions.showDescriptions, onClick )[ 0 ]; + } + + if ( bindingOptions.showContentsToggle ) { showContents = buildCheckBox( footer, _configuration.showContentsLabelText, bindingOptions.showContents, onClick )[ 0 ]; + } } @@ -618,6 +645,11 @@ options.showDescriptions = getDefaultBoolean( options.showDescriptions, true ); options.showContents = getDefaultBoolean( options.showContents, true ); options.tooltipDelay = getDefaultNumber( options.tooltipDelay, 750 ); + options.showChildrenToggle = getDefaultBoolean( options.showChildrenToggle, true ); + options.showDescriptionsToggle = getDefaultBoolean( options.showDescriptionsToggle, true ); + options.showContentsToggle = getDefaultBoolean( options.showContentsToggle, true ); + options.showCategorySelector = getDefaultBoolean( options.showCategorySelector, true ); + options.showCategorySelectionDropDown = getDefaultBoolean( options.showCategorySelectionDropDown, true ); options = buildAttributeOptionCustomTriggers( options ); options = buildAttributeOptionStrings( options ); @@ -968,7 +1000,7 @@ * @returns {string} The version number. */ this.getVersion = function() { - return "0.1.0"; + return "0.2.0"; }; diff --git a/src/tree.js.scss b/src/tree.js.scss index 44c89e2..3578d18 100755 --- a/src/tree.js.scss +++ b/src/tree.js.scss @@ -1,5 +1,5 @@ /* - * Tree.js Library v0.1.0 + * Tree.js Library v0.2.0 * * Copyright 2024 Bunoon * Released under the MIT License diff --git a/tree.js.nuspec b/tree.js.nuspec index ab3d15a..9620068 100755 --- a/tree.js.nuspec +++ b/tree.js.nuspec @@ -2,9 +2,9 @@ jTree.js - 0.1.0 + 0.2.0 Tree.js - A lightweight JavaScript library that generates customizable trees views to visualize numerical data. + A lightweight JavaScript library that allows you to create responsive and customizable interactive tree diagrams from an array of JS objects. William Troup https://www.william-troup.com/tree-js/