// function to draw data we recieve from ajax requests
_lastData = [];
function drawcontents(data) {
data = data || _lastData; //Cache data so we can drawcontents without waiting for the server, for the search box.
_lastData = data;
// allow searching for multiple criteria separated by space
var searchArgs = document.querySelector("#search").value;
searchArgs = searchArgs.trim();
searchArgs = '(' + searchArgs.replace(/ +/g,")|(") + ')';
const search = new RegExp(searchArgs, 'i');
data = data.filter(function(item) {
return search.test(item.name);
})
sortByKey(data, "count");
const table = document.querySelector("#contents tbody"); //tables have tbody inserted automatically
const rows = table.children;
//update existing rows or create new ones
data.forEach(function(item, i) {
// format count to have .s in it for large number readability (1,000,000)
item.count = item.count.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
let row = rows[i];
if(!row) {
row = document.createElement('tr');
row.innerHTML = "
![]() | | | ";
table.appendChild(row);
}
const img = row.querySelector('img');
const imgName = getImageFromName(item.name);
if(img.getAttribute('src') !== imgName) {
img.setAttribute('src',imgName);
}
const name = row.querySelector('.name');
if(name.textContent !== item.name) {
name.textContent = item.name;
row.onclick = ()=>{
makeItemGraphs(item.name);
}
}
const count = row.querySelector('.count');
if(count.textContent !== ''+item.count) {
count.textContent = item.count;
}
});
//remove excess rows, for example, after filtering
while (data.length < rows.length) {
table.removeChild(rows[data.length]);
}
}
// get cluster inventory from master
function updateInventory() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
let data = JSON.parse(xmlhttp.responseText);
drawcontents(data);
}
}
xmlhttp.open("GET", "api/inventory", true);
xmlhttp.send();
}
if(JSON.parse(localStorage.settings)["Periodically update storage screen"]) {
setInterval(updateInventory, 500);
} else {
updateInventory();
}
// function to sort arrays of objects after a keys value
function sortByKey(array, key) {
array.sort(function(a, b) {
return b[key] - a[key];
});
}
document.querySelector("#search").addEventListener('input', function() {
drawcontents();
});
// Make graph of cluster IO items
/*getJSON("/api/getStats", function(err, data){
}*/
function getItemStatData(item, callback){
var xhr = new XMLHttpRequest();
var url = "/api/getStats";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.email + ", " + json.password);
callback(json);
}
};
var requestData = JSON.stringify({
"statistic": "place",
"itemName": "shit",
});
xhr.send(data);
}
function makeItemGraphs(itemName){
getJSON("/api/slaves", function(err, slaves){
if(err) throw err;
if(typeof slaves == "string"){
slaves = JSON.parse(slaves);
}
let instanceIDs = Object.keys(slaves);
let HTML = ""
// Draw in/out chart for unregistered slaves as well
instanceIDs.unshift("unknown");
instanceIDs.forEach(function(instanceID){
if(instanceID == "unknown" || Date.now() - slaves[instanceID].time < 120000 || JSON.parse(localStorage.settings)["Display offline slaves"]){
HTML += '';
["place", "remove"].forEach(statistic => {
console.log("Making chart for "+instanceID+"'s "+statistic+" statistic");
setTimeout(function(){
let xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
xmlhttp.open("POST", "/api/getStats");
xmlhttp.setRequestHeader("Content-Type", "application/json");
xmlhttp.onreadystatechange = function(){
console.log(xmlhttp.status);
if(xmlhttp.readyState === XMLHttpRequest.DONE && xmlhttp.status === 200) {
// console.log(xmlhttp.responseText);
if(isJSON(xmlhttp.responseText) && JSON.parse(xmlhttp.responseText).statusForDebugging === undefined){
let slaveDisplayName = "unknown";
try {
slaveDisplayName = slaves[instanceID].instanceName;
} catch(e) {}
let whatGraphIsIt = "Item IO from ";
// if(statistic == "remove") whatGraphIsIt = "Items taken from cluster by";
let chartData = JSON.parse(xmlhttp.response).data;
switch(statistic){
case "place":
chartData.name = "Items exported:";
break;
case "remove":
chartData.name = "Items imported:";
break;
}
drawChartWhenCalledTwice(chartData, whatGraphIsIt + " " + slaveDisplayName);
//drawChart(statistic+"contentGraph"+instanceID, [JSON.parse(xmlhttp.response).data], `${whatGraphIsIt} ${slaveDisplayName} (${instanceID}) ${itemName}`);
// console.log(JSON.parse(xmlhttp.response).data);
}
}
}
xmlhttp.send(JSON.stringify({statistic:statistic, itemName:itemName, instanceID:instanceID}));
},1);
});
let chartLines = [];
function drawChartWhenCalledTwice(data, slaveDisplayName){
chartLines.push(data);
if(chartLines.length >= 2){
drawChart("contentGraph"+instanceID, chartLines, `${slaveDisplayName} (${instanceID}) ${itemName}`);
}
}
}
});
document.querySelector("#graphDisplay > #storageGraphContainer").innerHTML = HTML;
});
}
let chartsByID = {};
function drawChart(selector, chartData, title) {
// selector is ID of element, ex "chartContainer" or "-123199123"
console.log(chartData)
chartsByID[selector] = new CanvasJS.Chart(selector, {
title:{
text: title || "Production graph"
},
toolTip:{
shared: true,
// content: "{name}: {y}",
},
zoomEnabled: true,
axisY:{
includeZero: true,
},
legend: {
cursor: "pointer",
itemclick: function (e) {
//console.log("legend click: " + e.dataPointIndex);
//console.log(e);
if (typeof (e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
e.chart.render();
}
},
data: chartData
});
chart = chartsByID[selector];
// console.log(chart)
chart.render();
return chart;
}