mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-01 19:30:31 +00:00
ed24ec27b9
git-svn-id: https://svn.fhem.de/fhem/trunk@15561 2b470e98-0d58-463d-a4d8-8e2adae1ed80
375 lines
12 KiB
JavaScript
375 lines
12 KiB
JavaScript
|
|
function loadGoogleApi(success) {
|
|
|
|
if(window.google)
|
|
{
|
|
// Load the Visualization API library
|
|
google.charts.load('current', {'packages':['corechart','geochart','table'], callback: success} );
|
|
}
|
|
else
|
|
{
|
|
success();
|
|
}
|
|
}
|
|
|
|
function json2array(json){
|
|
var result = [];
|
|
var keys = Object.keys(json);
|
|
keys.forEach(function(key){
|
|
result.push([key,json[key]]);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function rand(length) {
|
|
var text = "";
|
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
for(var i = 0; i < length; i++) {
|
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
}
|
|
return text;
|
|
}
|
|
|
|
function drawGooglePieChart(data, el, subst, sort, threshold) {
|
|
|
|
sort = (sort == undefined ? "byKey" : sort);
|
|
var id = rand(5);
|
|
|
|
el.append("");
|
|
el.append("<div id='"+id+"' class='googlepiechart'></div>");
|
|
|
|
var result = [];
|
|
|
|
for(var i in data) {
|
|
result.push([((subst && i in subst) ? subst[i] : i)+" ("+data[i]+")", parseInt(data[i])]);
|
|
}
|
|
|
|
if(sort === "byKey") {
|
|
result.sort();
|
|
result.reverse();
|
|
}
|
|
else if(sort === "byValue")
|
|
{
|
|
result.sort(function(a,b) {return b[1] - a[1]});
|
|
}
|
|
|
|
var array = new google.visualization.DataTable();
|
|
|
|
array.addColumn("string","Topping");
|
|
array.addColumn("number","Slices");
|
|
|
|
array.addRows(result);
|
|
|
|
var options = { is3D: true,
|
|
chartArea : { height:'80%',width:'95%' },
|
|
tooltip: { trigger: 'selection' },
|
|
width: 600,
|
|
legend: {position: 'right',labeledValueText: 'both'},
|
|
pieSliceText: 'none',
|
|
height: 450,
|
|
sliceVisibilityThreshold: threshold
|
|
};
|
|
|
|
var container = document.getElementById(id);
|
|
var chart = new google.visualization.PieChart(document.getElementById(id));
|
|
|
|
chart.draw(array,options);
|
|
}
|
|
|
|
// helper method in string for replacement
|
|
String.prototype.replaceAll = function(search, replacement) {
|
|
var target = this;
|
|
return target.replace(new RegExp("^"+search+"$", 'g'), replacement);
|
|
};
|
|
|
|
function replaceAll(str, map){
|
|
for(key in map){
|
|
str = str.replaceAll(key, map[key]);
|
|
}
|
|
return str;
|
|
}
|
|
|
|
|
|
function drawGoogleGermanyMap(data, el) {
|
|
|
|
var id = rand(5);
|
|
|
|
el.append("");
|
|
el.append("<div id='"+id+"' class='googlemap'></div>");
|
|
|
|
var result = [];
|
|
|
|
var mapTextToCode = {
|
|
"Baden-Wurttemberg": "DE-BW",
|
|
"Bayern": "DE-BY",
|
|
"Berlin": "DE-BE",
|
|
"Brandenburg": "DE-BB",
|
|
"Bremen": "DE-HB",
|
|
"Hamburg": "DE-HH",
|
|
"Hessen": "DE-HE",
|
|
"Mecklenburg-Vorpommern": "DE-MV",
|
|
"Niedersachsen":"DE-NI",
|
|
"Nordrhein-Westfalen": "DE-NW",
|
|
"Rheinland-Pfalz": "DE-RP",
|
|
"Saarland":"DE-SL",
|
|
"Sachsen":"DE-SN",
|
|
"Sachsen-Anhalt":"DE-ST",
|
|
"Schleswig-Holstein":"DE-SH",
|
|
"Thuringen":"DE-TH"
|
|
};
|
|
|
|
var mapTextToEnglish = {
|
|
"Baden-Wurttemberg": "Baden-Württemberg",
|
|
"Bayern": "Bavaria",
|
|
"Hessen": "Hesse",
|
|
"Niedersachsen":"Lower Saxony",
|
|
"Nordrhein-Westfalen": "North Rhine-Westphalia",
|
|
"Rheinland-Pfalz": "Rhineland-Palatinate",
|
|
"Sachsen":"Saxony",
|
|
"Sachsen-Anhalt":"Saxony-Anhalt",
|
|
"Thuringen":"Thuringia"
|
|
};
|
|
|
|
for(var i in data) {
|
|
result.push([replaceAll(i, mapTextToCode), data [i], replaceAll(i, mapTextToEnglish)+": "+data[i]]);
|
|
}
|
|
|
|
var array = new google.visualization.DataTable();
|
|
|
|
array.addColumn("string","Country");
|
|
array.addColumn("number","Installations");
|
|
array.addColumn({type: 'string', role: 'tooltip', p:{'html': true}});
|
|
array.addRows(result);
|
|
|
|
var options = { region: 'DE',
|
|
colorAxis: {colors: ['#A7E7A7', '#278727']},
|
|
resolution: "provinces",
|
|
backgroundColor : 'lightblue',
|
|
tooltip: {isHtml: true},
|
|
width:800
|
|
};
|
|
|
|
var chart = new google.visualization.GeoChart(document.getElementById(id));
|
|
chart.draw(array,options);
|
|
}
|
|
|
|
|
|
function drawGoogleWorldMap(data, el) {
|
|
|
|
var id = rand(5);
|
|
|
|
el.append("");
|
|
el.append("<div id='"+id+"' class='googlemap'></div>");
|
|
|
|
var result = [];
|
|
|
|
for(var i in data) {
|
|
|
|
result.push([i, data[i].count, data[i].name+": "+data[i].count]);
|
|
}
|
|
|
|
var array = new google.visualization.DataTable();
|
|
|
|
array.addColumn("string","Country");
|
|
array.addColumn("number","Installations");
|
|
array.addColumn({type: 'string', role: 'tooltip', p:{'html': true}});
|
|
array.addRows(result);
|
|
|
|
var options = {
|
|
colorAxis: {colors: ['#A7E7A7', '#A7E7A7']},
|
|
backgroundColor : 'lightblue',
|
|
tooltip: {isHtml: true},
|
|
legend: 'none',
|
|
width: 800
|
|
};
|
|
|
|
var chart = new google.visualization.GeoChart(document.getElementById(id));
|
|
chart.draw(array,options);
|
|
}
|
|
|
|
function drawGoogleEuroMap(data, el) {
|
|
|
|
var id = rand(5);
|
|
|
|
el.append("");
|
|
el.append("<div id='"+id+"' class='googlemap'></div>");
|
|
|
|
var result = [];
|
|
|
|
for(var i in data) {
|
|
result.push([i, data[i].count, data[i].name+": "+data[i].count]);
|
|
}
|
|
|
|
var array = new google.visualization.DataTable();
|
|
|
|
array.addColumn("string","Country");
|
|
array.addColumn("number","Installations");
|
|
array.addColumn({type: 'string', role: 'tooltip'});
|
|
array.addRows(result);
|
|
|
|
var options = {
|
|
region: '150',
|
|
colorAxis: {colors: ['#A7E7A7', '#A7E7A7']},
|
|
backgroundColor : 'lightblue',
|
|
legend: 'none',
|
|
width:800
|
|
};
|
|
|
|
var chart = new google.visualization.GeoChart(document.getElementById(id));
|
|
chart.draw(array,options);
|
|
}
|
|
|
|
|
|
function createModulTable(modules,models,table)
|
|
{
|
|
var tbody = table.children("tbody");
|
|
|
|
$.each(modules, function(module, moduleData) {
|
|
|
|
if(moduleData.installations > 1) {
|
|
|
|
var addon = "";
|
|
|
|
if(module in models)
|
|
{
|
|
addon = "<a href='#' class='model-link' module='"+module+"'>"+ Object.keys(models[module]).length+"</a>";
|
|
}
|
|
else
|
|
{
|
|
addon = "-";
|
|
}
|
|
|
|
tbody.append("<tr><td>"+module+"</td><td class='dt-body-center'>"+moduleData.installations+"</td><td class='dt-body-center'>"+moduleData.definitions+"</td><td class='dt-body-center'>"+addon+"</td></tr>");
|
|
}
|
|
});
|
|
|
|
|
|
table.DataTable({
|
|
order: [[ 1, "desc" ]],
|
|
responsive: true,
|
|
scrollCollapse: false,
|
|
paging: true,
|
|
lengthMenu: [ 10, 25, 50, 100, 200, 500 ],
|
|
columnDefs: [ { "orderSequence": ['desc', 'asc'], "targets":1 },
|
|
{ "orderSequence": ['desc', 'asc'], "targets":2 },
|
|
{ "orderSequence": ['desc'], "targets":3 } ]
|
|
});
|
|
|
|
$(document).on("click", "a.model-link", function (e) {
|
|
var a = $(this);
|
|
var moduleName = a.attr("module");
|
|
var div = a.parent();
|
|
|
|
$(generateModelsOverview(moduleName,models[moduleName])).dialog({
|
|
modal: true,
|
|
width:'auto',
|
|
height:'auto',
|
|
maxHeight: $(window).height(),
|
|
open:function(){
|
|
$(this).css({'max-height': $(window).height() - 200, 'overflow-y': 'auto'});
|
|
|
|
$('.ui-widget-overlay').bind('click', function()
|
|
{
|
|
$("div.model-overview").dialog('close');
|
|
});
|
|
},
|
|
buttons: { Close: function () {$(this).dialog("close");$(this).remove();} },
|
|
close: function( event, ui ) {$(this).remove();}
|
|
});
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
function convertHtmlEntities(str)
|
|
{
|
|
return $("<div />").text(str).html();
|
|
}
|
|
|
|
function generateModelsOverview(moduleName, modelData)
|
|
{
|
|
var str = '<div class="model-overview" title="Model variety for '+moduleName+'" module="'+moduleName+'">';
|
|
|
|
var models = json2array(modelData);
|
|
|
|
models.sort(function (a, b) {
|
|
return a[0].toLowerCase().localeCompare(b[0].toLowerCase());
|
|
});
|
|
|
|
str += '<table class="block modelOverview"><tr><th>Model</th><th># of installations</th><th># of definitions</th></tr>'
|
|
var cl = "odd";
|
|
$.each(models, function(index, arr) {
|
|
str += '<tr class="'+cl+'"><td class="modelName">'+convertHtmlEntities(arr[0])+'</td><td class="modelValue">'+arr[1].installations+'</td><td class="modelValue">'+arr[1].definitions+"</td></tr>";
|
|
cl = (cl == "odd" ? "even" : "odd");
|
|
});
|
|
|
|
str += "</table>";
|
|
str += "</div>"
|
|
|
|
return str;
|
|
}
|
|
|
|
function onSuccess(data, textStatus, jqXHR) {
|
|
|
|
var div = $("div#overview");
|
|
|
|
div.append("last submission: " + data.updated + " UTC<br>");
|
|
div.append("created in: " + data.generated.toFixed(3) + " seconds<br>");
|
|
div.append("number of submissions today: " + data.nodesToday + "<br>");
|
|
div.append("number of submissions (last 12 months, used for statistics): " + data.nodes12 + "<br>");
|
|
div.append("total number of submissions (since : " + data.started + "): "+data.nodesTotal+"<br><br>");
|
|
div.append("You can help us increase the quality of FHEM statistics data. Please check <a href='https://fhem.de/commandref.html#fheminfo' target='_new'>fheminfo</a> command for details.");
|
|
|
|
$("div.tabs").tabs();
|
|
|
|
loadGoogleApi(function () {
|
|
|
|
// draw google geo charts
|
|
drawGoogleEuroMap(data.data.geo.countrycode, $("div#maptab-europe"));
|
|
drawGoogleGermanyMap(data.data.geo.regionname.DE,$("div#maptab-germany"));
|
|
drawGoogleWorldMap(data.data.geo.countrycode,$("div#maptab-world"));
|
|
|
|
// draw google pie charts
|
|
drawGooglePieChart(data.data.system.os, $("div#versiontab-os"), {"linux":"Linux","MSWin32":"Windows","darwin":"macOS","cygwin":"Cygwin","freebsd":"FreeBSD"}, "byValue",0 );
|
|
drawGooglePieChart(data.data.system.perl, $("div#versiontab-perl"),false,undefined,0);
|
|
|
|
drawGooglePieChart(data.data.system.age, $("div#versiontab-update"), {"0":"≤ 1 day", "7": "1 day - 1 week", "30": "1 week - 1 month", "180": "1 month - 6 months", "365": "6 months - 1 year", "999": "> 1 year"}, false);
|
|
|
|
// create module table
|
|
createModulTable(data.data.modules,data.data.models, $("table#module-table"));
|
|
|
|
// show the result
|
|
$("div#loading").hide(0, function () {
|
|
$("div#content").show();
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
function onError(jqXHR, textStatus,errorThrown) {
|
|
|
|
console.log(jqXHR);
|
|
$("div#right").append("<b>Error while loading JSON data</b>: "+jqXHR.status+" "+jqXHR.statusText+"<br><br>");
|
|
|
|
if(jqXHR.responseText)
|
|
{
|
|
$("div#right").append("received: <pre>"+convertHtmlEntities(jqXHR.responseText)+"</pre>");
|
|
}
|
|
|
|
$("div#loading").hide(0);
|
|
}
|
|
|
|
|
|
// start the JSON request
|
|
$(function() {
|
|
|
|
$.ajax({
|
|
dataType: "json",
|
|
url: "statistics2.cgi?type=json",
|
|
success: onSuccess,
|
|
error: onError,
|
|
timeout: 30000
|
|
});
|
|
})
|
|
|