This repository has been archived on 2020-12-10. You can view files and clone it, but cannot push or open issues or pull requests.
IRProject/ui/carrotsearch.foamtree.util.loading.js

162 lines
5.6 KiB
JavaScript
Raw Normal View History

2020-11-18 22:44:51 +00:00
/**
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Copyright 2002-2019, Carrot Search s.c, All Rights Reserved.
*
*
* A simple utility for attaching showing and hiding a
* data loading and preparation progress indicator. The utility
* will create and attach all the necessary HTML to the page.
*
* Please see demos/loading.html for the usage example.
*
* @param foamtree the FoamTree instance whose loading and
* layout preparation progress should be monitored
* @param indicatorHtml the HTML representing the loading message
*/
window.CarrotSearchFoamTree.loader = function(foamtree, indicatorHtml) {
var deferDataObjectChange = false, dataObjectToSet = undefined;
var dataObjectToSetProvided = false;
// Duration of the loading element CSS transition. You may
// need to modify this value if you modified the default CSS transitions.
var duration = 350;
// On Webkit CSS transitions seem to continue running during JS processing.
// Other browsers need to wait for the transition to complete.
var waitForTransition = !/chrome|webkit/.test(navigator.userAgent.toLowerCase());
// Create the indicator element
var indicator = document.createElement("div");
indicator.className = "visualization-loading fadeout";
indicator.innerHTML = indicatorHtml;
foamtree.get("element").appendChild(indicator);
// Hide the indicator when rollout starts
foamtree.on("rolloutStart", hideIndicator);
return {
/**
* Call this method before data loading is initiated to
* show the loading indicator.
*
* If FoamTree is set to perform a pullback animation,
* the loading indicator will show after pullback is complete.
*/
started: function() {
dataObjectToSetProvided = false;
if (isPullbackEnabled()) {
// We'll defer setting of the new data object
// until pullback completes. FoamTree does that
// internally too, but we need to show the indicator
// before we set the new data object. If we didn't
// do that, the element would actually show after
// the diagram computation completes, which wouldn't
// make much sense.
deferDataObjectChange = true;
once("modelChanged", showIndicatorAndSetDataObject);
// Set an empty data object to trigger a pullback
foamtree.set("dataObject", null);
} else {
deferDataObjectChange = false;
showIndicator();
}
},
/**
* Call this method when data loading completes. This method
* will take care of setting the new data object on FoamTree
* and hiding the indicator when the diagram is ready to show.
*
* @param dataObject new data object to set
*/
complete: function (dataObject) {
dataObjectToSetProvided = true;
if (deferDataObjectChange) {
// Just remember the new data object, we'll set it
// after the pullback completes and the loading indicator
// is made visible.
dataObjectToSet = dataObject;
} else {
// Defer the update to give the browser a chance
// to show the loading indicator.
setTimeout(function() {
foamtree.set("dataObject", dataObject);
hideIndicatorIfDataObjectEmpty(dataObjectToSet);
}, 1 + (waitForTransition ? duration + 50 : 1));
}
}
};
function showIndicatorAndSetDataObject() {
showIndicator();
if (dataObjectToSetProvided && deferDataObjectChange) {
// Defer the update to give the browser a chance
// to show the loading indicator.
setTimeout(function() {
foamtree.set("dataObject", dataObjectToSet);
hideIndicatorIfDataObjectEmpty(dataObjectToSet);
}, 5 + (waitForTransition ? duration + 50 : 1));
}
deferDataObjectChange = false;
}
function hideIndicatorIfDataObjectEmpty(dataObject) {
if (!dataObject || !dataObject.groups || dataObject.groups.length == 0) {
hideIndicator();
}
}
function hideIndicator() {
addClass(indicator, "fadeout");
}
function showIndicator() {
// It would be good to defer showing of the indicator a bit
// so that it's not shown when the loading process completes
// very quickly. However, it's not currently possible to implement
// because FoamTree diagram computation is performed in one
// go and blocks until the computation completes. In the future,
// it would be good to split the computation into chunks between
// which FoamTree would yield to the UI thread to redraw the
// DOM updates.
removeClass(indicator, "fadeout");
}
function addClass(element, clazz) {
var classes = element.className.split(/\s+/);
if (classes.indexOf(clazz) < 0) {
classes.push(clazz);
element.className = classes.join(" ");
}
}
function removeClass(element, clazz) {
element.className = element.className.split(/\s+/).filter(function (c) {
return c != clazz;
}).join(" ");
}
function isPullbackEnabled() {
return foamtree.get("pullbackDuration") > 0 || foamtree.get("fadeDuration") > 0;
}
function once(event, fn) {
foamtree.on(event, function() {
foamtree.off(event);
fn();
});
}
};