Commit eeb78119 authored by Adam Rousell's avatar Adam Rousell
Browse files

Added general information to analysis, allowed for custom styling and general language updates

parent 0b9a18c7
var stats = {};
var name = 'Age';
var description = 'Information regarding the age of the features based on date/time fields.';
var texts = {
en: {
name: 'Age',
description: 'Information regarding the age of the features based on date/time fields.',
newest: 'Newest',
oldest: 'Oldest',
average: 'Average'
},
de: {
name: 'Alter',
description: 'Informationen über das Alter der Features auf der Grundlage von Datums- / Zeitfeldern.',
newest: 'Nueste',
oldest: 'Älteste',
average: 'Mittelwert'
},
it: {
name: 'Età',
description: 'Informazioni relative all\'età delle funzionalità basate sui campi data / ora.',
newest: 'i più nuovi',
oldest: 'il più vecchio',
average: 'Media'
}
};
exports.analyse = function(srcData) {
exports.analyse = function(srcData, locale) {
var data = JSON.parse(JSON.stringify(srcData));
var text = texts[locale];
if(!text) text = texts['en'];
// we need to look through the attributes to find which attributes are date/time type
// we look at the metadata and attribute information for this
//console.log(data);
......@@ -52,8 +74,8 @@ exports.analyse = function(srcData) {
// Now we need to do the analsys on them
var statsData = {
name: name,
description: description,
name: text.name,
description: text.description,
fields: []
};
......@@ -85,15 +107,15 @@ exports.analyse = function(srcData) {
field: fieldName,
metrics: [
{
name: 'Newest',
name: text.newest,
value: new Date(max)
},
{
name: 'Oldest',
name: text.oldest,
value: new Date(min)
},
{
name: 'Average',
name: text.average,
value: new Date(ave)
}
]
......
var attr_count = require('./attr_count');
var attr_data = require('./attr_data');
var age = require('./age');
var general = require('./general_info');
exports.analyse = function(tablename, data) {
exports.analyse = function(srcData, data, locale) {
var results = [];
// we want to return a json array containing the values obtained from the methods
results.push(general.analyse(srcData, locale));
results.push(attr_count.analyse(data, locale));
results.push(age.analyse(data, locale));
results.push(attr_count.analyse(data));
results.push(age.analyse(data));
results.push(attr_data.analyse(data));
results.push(attr_data.analyse(data, locale));
return results;
}
\ No newline at end of file
var stats = {};
var name = 'Attribute count';
var description = 'Information regarding the number of attributes that are associated to features.';
var texts = {
en: {
name: 'Attribute count',
description: 'Information regarding the number of attributes that are associated to features.',
maximum: 'Maximum',
minimum: 'Minimum',
average: 'Average'
},
de: {
name: 'Attributzahl',
description: 'Informationen über die Anzahl der Attribute, die mit Features verknüpft sind',
maximum: 'Maximum',
minimum: 'Minimum',
average: 'Durchschnitt'
},
it: {
name: 'Conteggio degli attributi',
description: 'Informazioni relative al numero di attributi associati alle funzionalità',
maximum: 'Massimo',
minimum: 'Minimo',
average: 'Media'
}
};
exports.analyse = function(srcData) {
exports.analyse = function(srcData, locale) {
// We need to go through the data and calculate for each record how many attributes it has
// First lets create a copy of the data
var data = JSON.parse(JSON.stringify(srcData));
var text = texts[locale];
if(!text) text = texts['en'];
// Now for each item we want to count how many attributes are present
var a = [];
......@@ -91,21 +114,21 @@ exports.analyse = function(srcData) {
}
return {
name: name,
description: description,
name: text.name,
description: text.description,
fields: [
{
metrics: [
{
name: 'Maximum',
name: text.maximum,
value: stats.max
},
{
name: 'Minimum',
name: text.minimum,
value: stats.min
},
{
name: 'Average',
name: text.average,
value: stats.average
}
],
......
var stats = {};
var name = 'Tags';
var description = 'Information about each attribute regarding the values that have been entered.';
var texts = {
en: {
name: 'Tags',
description: 'Information about each attribute regarding the values that have been entered.',
only: 'Only value(s)',
most: 'Most frequent value',
least: 'Least frequent value',
noValue: 'No value'
},
de: {
name: 'Tags',
description: 'Informationen zu jedem Attribut bezüglich der eingegebenen Werte',
only: 'Der einzige Wert(e)',
most: 'Der häufigste Wert',
least: 'Der kleinste Wert',
noValue: 'Kein Wert'
},
it: {
name: 'Tags',
description: 'Informazioni su ogni attributo riguardante i valori immessi.',
only: 'l\'unico valore(i)',
most: 'il valore più frequente',
least: 'il valore meno frequente',
noValue: 'Nessun valore'
}
};
function getAttributeName(a) {
var firstSplit = a.indexOf('_');
......@@ -28,10 +53,12 @@ function valueArrayToString(attrValues) {
return str;
}
exports.analyse = function(srcData) {
exports.analyse = function(srcData, locale) {
// Go through each attribute present and look at what values have been entered.
var data = JSON.parse(JSON.stringify(srcData));
var text = texts[locale];
if(!text) text = texts['en'];
// Get the list of attributes from the meta and properties
var attributes = [];
......@@ -78,8 +105,8 @@ exports.analyse = function(srcData) {
// The contents of attrInfo now tells us the count of each value for each attribute
var ret = {
name: name,
description: description,
name: text.name,
description: text.description,
fields: []
};
......@@ -124,8 +151,7 @@ exports.analyse = function(srcData) {
}
}
}
labels.push('No value');
labels.push(text.noValue);
counts.push(featureCount - counts.reduce(function(a,b) {
return a + b;
......@@ -133,20 +159,19 @@ exports.analyse = function(srcData) {
var metrics = [];
if(leastFrequent == mostFrequent) {
metrics.push({
name: "Only value(s)",
name: text.only,
value: valueArrayToString(mostFrequentValues) + ' (' + mostFrequent + ')'
});
} else {
metrics = [
{
name: 'Most frequent value',
name: text.most,
value: valueArrayToString(mostFrequentValues) + ' (' + mostFrequent + ')'
},
{
name: 'Least frequent value',
name: text.least,
value: valueArrayToString(leastFrequentValues) + ' (' + leastFrequent + ')'
}
];
......
// This method provides a general overview of the dataset including the number of records etc.
var stats = {};
var texts = {
en: {
name: 'General info',
description: 'General information about the dataset.',
features: 'Number of features',
datasetSize: 'Dataset size',
count: 'Count',
fileSize: 'Size (KB)',
metaValue: 'value'
},
de: {
name: 'Allgemeine Infos',
description: 'Allgemeine Informationen zum Datensatz.',
features: 'Anzahl der Features',
datasetSize: 'Dataset size',
count: 'Zählen',
fileSize: 'Größe (KB)',
metaValue: 'Wert'
},
it: {
name: 'Informazioni generali',
description: 'Informazioni generali sul set di dati.',
features: 'Numero di funzionalità',
datasetSize: 'Formato Dataset',
count: 'Contare',
fileSize: 'Dimensione (KB)',
metaValue: 'Valore'
}
};
exports.analyse = function(srcData, locale) {
var data = JSON.parse(JSON.stringify(srcData));
var text = texts[locale];
if(!text) text = texts['en'];
var ret = {
name: text.name,
description: text.description,
fields: []
};
ret.fields.push({
field: text.features,
metrics: [{
name: text.count,
value: (typeof data.features === 'undefined' ? '0' : data.features.length)
}]
});
ret.fields.push({
field: text.datasetSize,
metrics: [{
name: text.fileSize,
value: (data.fileSize/(1024)).toFixed(2)
}]
});
// First use the fields that are not features or type as metadata
var meta = [];
for (var key in srcData) {
if (srcData.hasOwnProperty(key)) {
if(key !== 'type' && key !== 'features' && key != 'fileSize') {
ret.fields.push({
field: key,
metrics: [{
name: text.metaValue,
value: srcData[key]
}
]
});
}
}
}
return ret;
};
\ No newline at end of file
......@@ -47,4 +47,9 @@
.field-metric-stats {
width: 50%;
float: left;
}
.no-data {
width: 100%;
}
\ No newline at end of file
body {
background-color: #c32630;
}
.metric-wrapper {
background-color: #ffffff;
padding: 15px;
}
\ No newline at end of file
body {
font-family: "Roboto", sans-serif;
}
.upload-form {
background-color: #c32630;
color: #ffffff;
border: 0px;
padding-top: 50px;
padding-left: 60px;
padding-right: 60px;
padding-bottom: 30px;
}
.upload-form button {
background-color: #c32630;
color: #ffffff;
border: solid 1px #ffffff;
border-radius: 3px;
cursor: pointer;
height: 50px;
text-transform: uppercase;
line-height: 30px;
font-weight: 500;
font-size: 0.7em;
padding: 0 15px;
transition: .3s linear;
}
.upload-form button:focus, .upload-form button:hover {
background-color: #ffffff;
color: #c32630;
border: solid 1px #ffffff;
border-radius: 3px;
transition: .3s linear;
}
\ No newline at end of file
#header {
margin: auto;
margin-bottom: auto;
width: 50%;
clear: both;
overflow: auto;
margin-bottom: 20px;
}
#logo {
float: left;
height: 65px;
width: 200px;
background-image: url('http://wegovnow.eu/fileadmin/wegovnow/templates/img/wegovnow-logo-icon.png');
}
#headerText {
text-align: center;
}
#headerContent {
overflow: auto;
}
#descriptionText {
width: 80%;
margin: auto;
margin-bottom: 40px;
}
\ No newline at end of file
.upload-form {
width: 400px;
width: 500px;
margin: auto;
border: 3px solid #000000;
padding: 10px;
......
var langs = {
en: {
index: {
pageTitle: 'WeGovNow Data Check',
indexHeader: 'WeGovNow Data Check',
indexFileLabel: 'File (JSON): ',
indexFileButton: 'Browse...',
indexFileNone: 'No file selected.',
indexUploadButton: 'Analyse data',
descriptionText: 'The WeGovNow data check is a tool for looking at the contents of a JSON dataset as a means of assessing the underlying dataquality. Methods are applied to the data and information such as the number of attributes, average values and number of missing values are presented. <br/><br/>To analyse the data, select a valid JSON (or GeoJSON) file using the below form and then click the &quot;Analyze&quot; button.'
},
analyse: {
pageTitle: 'WeGovNow Data Check - Analyse',
},
error: {
pageTitle: 'WeGovNow Data Check - Error',
error: 'There was an error with the analysis - make sure that the data is in a valid JSON format!',
headerText: 'WeGovNow Data Check'
}
},
de: {
index: {
pageTitle: 'WeGovNow Datenprüfung',
indexHeader: 'WeGovNow Datenprüfung',
indexFileLabel: 'Datei (JSON): ',
indexFileButton: 'Durchsuchen...',
indexFileNone: 'Keine Datei ausgewählt.',
indexUploadButton: 'Daten analysieren',
descriptionText: 'Die Datenüberprüfung von WeGovNow ist ein Werkzeug, um den Inhalt eines JSON-Datasets zu betrachten, um die zugrundeliegende Datenqualifikation zu beurteilen. Es werden Methoden auf die Daten angewendet und Informationen wie die Anzahl der Attribute, Mittelwerte und die Anzahl der fehlenden Werte dargestellt.<br/><br/>Um die Daten zu analysieren, wählen Sie eine gültige JSON (oder GeoJSON) Datei mit dem untenstehenden Formular aus und klicken Sie dann auf die Schaltfläche &quot;Analysieren&quot;.'
},
analyse: {
pageTitle: 'WeGovNow Data Check - Analysieren',
},
error: {
pageTitle: 'WeGovNow Data Check - Fehler',
error: 'Es gab einen Fehler bei der Analyse - stellen Sie sicher, dass die Daten in einem gültigen JSON-Format vorliegen!',
headerText: 'WeGovNow Datenprüfung'
}
},
it: {
index: {
pageTitle: 'WeGovNow Data Check',
indexHeader: 'WeGovNow Data Check',
indexFileLabel: 'File (JSON): ',
indexFileButton: 'Sfoglia ...',
indexFileNone: 'Nessun file selezionato.',
indexUploadButton: 'Analizza i dati',
descriptionText: 'Il controllo dati WeGovNow è uno strumento per esaminare il contenuto di un set di dati JSON come mezzo per valutare la qualità dati sottostante. I metodi vengono applicati ai dati e alle informazioni come il numero di attributi, i valori medi e il numero di valori mancanti vengono presentati.<br/><br/>Per analizzare i dati, selezionare un file JSON (o GeoJSON) valido utilizzando il modulo sottostante e fare clic sul pulsante &quot;Analizza&quot;.'
},
analyse: {
pageTitle: 'WeGovNow Data Check - Analizza',
},
error: {
pageTitle: 'WeGovNow Data Check - Errore',
error: 'Si è verificato un errore con l\'analisi - assicurati che i dati siano in un formato JSON valido!',
headerText: 'WeGovNow Data Check'
}
}
}
\ No newline at end of file
// Script for updating the display based on locale
// First get the locale from the querystring
function translate(page) {
var locale = getLocale();
var texts = null;
// and then get translations
if(locale) {
// Update the various texts
texts = langs[locale][page];
}
if(!texts) {
texts = langs['en'][page];
}
// Now change each element based on the value
$.each(texts, function(k, v) {
if(k === 'pageTitle') {
$(document).prop('title', v);
} else {
if($('#'+k))
$('#'+k).html(v);
}
});
}
function getLocale()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
if(vars.locale)
return vars.locale;
else
return 'en';
}
\ No newline at end of file
......@@ -10,19 +10,19 @@ var router = express.Router();
router.post('/', upload.single('jsonfile'), function(req, res, next) {
// First we need to read the json data
var srcData = null;
try {
srcData = JSON.parse(req.file.buffer);
} catch(err) {
// Invalid JSON data
console.log("Error");
return next(err);
}
srcData['fileSize']=req.file.buffer.byteLength;
var data = loaddata.collapse(JSON.parse(JSON.stringify(srcData)));
//console.log(data);
var aResults = analysismethods.analyse(null, data);
var locale = req.query['locale'];//'de';
var aResults = analysismethods.analyse(srcData, data, locale);
//console.log({ metrics: aResults});
res.render('analyse', { metrics: aResults });
......
......@@ -14,7 +14,7 @@ mixin analysis(item)
span.field-name= f.field
//- Loop through each metric contained in the analysis
.field-metric-stats
.field-metric-stats(class=typeof f.data === 'undefined' ? 'no-data' : '')
each m in f.metrics
.metric
span.metric-name= m.name + ': '
......@@ -33,18 +33,24 @@ mixin analysis(item)
values: [#{f.data.values}],
labels: [!{strLabels}]
});
else
block header
link(rel='Stylesheet' href='public/css/analysis.css')
link(rel='Stylesheet' href='public/css/custom/analysis.css')
title WeGovNow quality checker - analysis
link(rel='Stylesheet' href='public/css/charts.css')
script(src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js')
script(src='public/js/make-chart.js')
block content
each m in metrics
+analysis(m)
#file
= jsondata
\ No newline at end of file
.bodycontainer
.header
each m in metrics
+analysis(m)
#file
= jsondata
script.
translate('analyse');
\ No newline at end of file
......@@ -8,7 +8,9 @@ block header
block content
#header
h1 WeGovNow Data Check
h1#headerText WeGovNow Data Check
#body
.error There was an error with the analysis - make sure that the data is in a valid JSON format!
\ No newline at end of file
#error.error There was an error with the analysis - make sure that the data is in a valid JSON format!
script.
translate('error');
\ No newline at end of file
......@@ -9,13 +9,19 @@ block header
block content
#header
h1 WeGovNow Data Check
#headerContent
#logo
#headerText