|
|
@ -805,7 +805,7 @@ define([
|
|
|
|
return total;
|
|
|
|
return total;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var getEmpty = function (empty) {
|
|
|
|
var getEmpty = function (empty) { // XXX don't include this in the scrollable area
|
|
|
|
if (empty) {
|
|
|
|
if (empty) {
|
|
|
|
return UI.setHTML(h('div.cp-form-results-type-text-empty'), Messages._getKey('form_notAnswered', [empty]));
|
|
|
|
return UI.setHTML(h('div.cp-form-results-type-text-empty'), Messages._getKey('form_notAnswered', [empty]));
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -959,7 +959,45 @@ define([
|
|
|
|
return Array.isArray(A)? Math.max.apply(null, A): NaN;
|
|
|
|
return Array.isArray(A)? Math.max.apply(null, A): NaN;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var TYPES = { // XXX hackathon insert useful charts for each of type of answer
|
|
|
|
var CLASSIC_MODE = true;
|
|
|
|
|
|
|
|
var renderTally = function (tally, empty, caption) {
|
|
|
|
|
|
|
|
var rows = [];
|
|
|
|
|
|
|
|
if (CLASSIC_MODE) {
|
|
|
|
|
|
|
|
Object.keys(tally).forEach(function (value) {
|
|
|
|
|
|
|
|
rows.push(h('div.cp-form-results-type-radio-data', [ // XXX
|
|
|
|
|
|
|
|
h('span.cp-value', value),
|
|
|
|
|
|
|
|
h('span.cp-count', tally[value])
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
if (empty) { rows.push(getEmpty(empty)); }
|
|
|
|
|
|
|
|
return rows;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var counts = Util.values(tally);
|
|
|
|
|
|
|
|
var max = arrayMax(counts);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object.keys(tally).forEach(function (answer) {
|
|
|
|
|
|
|
|
rows.push(Charts.row(answer, tally[answer] / max, tally[answer]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
var hasCaption = typeof(caption) !== 'undefined';
|
|
|
|
|
|
|
|
var table = Charts.table([
|
|
|
|
|
|
|
|
hasCaption ? h('caption', caption): undefined,
|
|
|
|
|
|
|
|
h('tbody', rows)
|
|
|
|
|
|
|
|
], [
|
|
|
|
|
|
|
|
'charts-css',
|
|
|
|
|
|
|
|
'bar',
|
|
|
|
|
|
|
|
hasCaption? 'show-heading': undefined,
|
|
|
|
|
|
|
|
'show-labels',
|
|
|
|
|
|
|
|
'show-data-on-hover',
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
|
|
table,
|
|
|
|
|
|
|
|
empty? getEmpty(empty): undefined,
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var TYPES = {
|
|
|
|
input: {
|
|
|
|
input: {
|
|
|
|
defaultOpts: {
|
|
|
|
defaultOpts: {
|
|
|
|
type: 'text'
|
|
|
|
type: 'text'
|
|
|
@ -993,7 +1031,7 @@ define([
|
|
|
|
reset: function () { $tag.val(''); }
|
|
|
|
reset: function () { $tag.val(''); }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid) { // XXX hackathon each question format has a 'printResults' method
|
|
|
|
printResults: function (answers, uid) {
|
|
|
|
var results = [];
|
|
|
|
var results = [];
|
|
|
|
var empty = 0;
|
|
|
|
var empty = 0;
|
|
|
|
var tally = {};
|
|
|
|
var tally = {};
|
|
|
@ -1007,7 +1045,7 @@ define([
|
|
|
|
var counts = Util.values(tally);
|
|
|
|
var counts = Util.values(tally);
|
|
|
|
var max = arrayMax(counts);
|
|
|
|
var max = arrayMax(counts);
|
|
|
|
|
|
|
|
|
|
|
|
if (max < 2) { // there are no duplicates, so just return text
|
|
|
|
if (CLASSIC_MODE || max < 2) { // there are no duplicates, so just return text
|
|
|
|
Object.keys(answers).forEach(function (author) {
|
|
|
|
Object.keys(answers).forEach(function (author) {
|
|
|
|
var obj = answers[author];
|
|
|
|
var obj = answers[author];
|
|
|
|
var answer = obj.msg[uid];
|
|
|
|
var answer = obj.msg[uid];
|
|
|
@ -1018,30 +1056,8 @@ define([
|
|
|
|
return h('div.cp-form-results-type-text', results);
|
|
|
|
return h('div.cp-form-results-type-text', results);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// increase the scale of the bar chart if there are more empty answers than anything else
|
|
|
|
var rendered = renderTally(tally, empty /*, caption */);
|
|
|
|
max = Math.max(max, empty);
|
|
|
|
return h('div.cp-form-results-type-text', rendered);
|
|
|
|
|
|
|
|
|
|
|
|
// there are duplicates, so return a bar chart
|
|
|
|
|
|
|
|
var rows = []; // XXX
|
|
|
|
|
|
|
|
Object.keys(tally).forEach(function (answer) {
|
|
|
|
|
|
|
|
rows.push(Charts.row(answer, tally[answer] / max, tally[answer]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var table = Charts.table([
|
|
|
|
|
|
|
|
//h('caption', ''), // XXX
|
|
|
|
|
|
|
|
h('tbody', rows)
|
|
|
|
|
|
|
|
], [
|
|
|
|
|
|
|
|
'charts-css',
|
|
|
|
|
|
|
|
'bar',
|
|
|
|
|
|
|
|
'show-heading',
|
|
|
|
|
|
|
|
'show-labels',
|
|
|
|
|
|
|
|
'show-data-on-hover',
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-text', [
|
|
|
|
|
|
|
|
table,
|
|
|
|
|
|
|
|
empty? getEmpty(empty): undefined,
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
icon: h('i.cptools.cptools-form-text')
|
|
|
|
icon: h('i.cptools.cptools-form-text')
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -1096,12 +1112,9 @@ define([
|
|
|
|
reset: function () { $text.val(''); }
|
|
|
|
reset: function () { $text.val(''); }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid) {
|
|
|
|
printResults: function (answers, uid) { // results textarea
|
|
|
|
var results = [];
|
|
|
|
var results = [];
|
|
|
|
var empty = 0;
|
|
|
|
var empty = 0;
|
|
|
|
// XXX hackathon like text inputs, charts are only useful if we tally duplicates
|
|
|
|
|
|
|
|
// (or if there are duplicates)
|
|
|
|
|
|
|
|
// https://chartscss.org/charts/bar/
|
|
|
|
|
|
|
|
Object.keys(answers).forEach(function (author) { // TODO deduplicate these
|
|
|
|
Object.keys(answers).forEach(function (author) { // TODO deduplicate these
|
|
|
|
var obj = answers[author];
|
|
|
|
var obj = answers[author];
|
|
|
|
var answer = obj.msg[uid];
|
|
|
|
var answer = obj.msg[uid];
|
|
|
@ -1169,8 +1182,7 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid) {
|
|
|
|
printResults: function (answers, uid) {
|
|
|
|
// XXX hackathon radio https://chartscss.org/charts/bar/
|
|
|
|
// results radio
|
|
|
|
//var results = [];
|
|
|
|
|
|
|
|
var empty = 0;
|
|
|
|
var empty = 0;
|
|
|
|
var count = {};
|
|
|
|
var count = {};
|
|
|
|
Object.keys(answers).forEach(function (author) {
|
|
|
|
Object.keys(answers).forEach(function (author) {
|
|
|
@ -1180,38 +1192,10 @@ define([
|
|
|
|
Util.inc(count, answer);
|
|
|
|
Util.inc(count, answer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
var counts = Util.values(count);
|
|
|
|
var rendered = renderTally(count, empty/*, caption */);
|
|
|
|
var max = arrayMax(counts);
|
|
|
|
|
|
|
|
var rows = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object.keys(count).forEach(function (text) {
|
|
|
|
|
|
|
|
rows.push(Charts.row(text, count[text] / max, count[text]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var table = Charts.table([
|
|
|
|
|
|
|
|
h('tbody', rows)
|
|
|
|
|
|
|
|
], [
|
|
|
|
|
|
|
|
'charts-css',
|
|
|
|
|
|
|
|
'bar',
|
|
|
|
|
|
|
|
'show-labels',
|
|
|
|
|
|
|
|
//'show-heading',
|
|
|
|
|
|
|
|
'show-data-on-hover',
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
style: 'width: 100%',
|
|
|
|
style: CLASSIC_MODE? '': 'width: 100%',
|
|
|
|
}, table);
|
|
|
|
}, rendered);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Object.keys(count).forEach(function (value) {
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', value),
|
|
|
|
|
|
|
|
h('span.cp-count', count[value])
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(getEmpty(empty)); // XXX show number of empty answers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', results);
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
icon: h('i.cptools.cptools-form-list-radio')
|
|
|
|
icon: h('i.cptools.cptools-form-list-radio')
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -1288,7 +1272,7 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid, form) {
|
|
|
|
printResults: function (answers, uid, form) {
|
|
|
|
// XXX hackathon multiradio https://chartscss.org/components/stacked/
|
|
|
|
// results multiradio
|
|
|
|
var structure = form[uid];
|
|
|
|
var structure = form[uid];
|
|
|
|
if (!structure) { return; }
|
|
|
|
if (!structure) { return; }
|
|
|
|
var opts = structure.opts || TYPES.multiradio.defaultOpts;
|
|
|
|
var opts = structure.opts || TYPES.multiradio.defaultOpts;
|
|
|
@ -1320,6 +1304,21 @@ define([
|
|
|
|
var q = findItem(opts.items, q_uid);
|
|
|
|
var q = findItem(opts.items, q_uid);
|
|
|
|
var c = count[q_uid];
|
|
|
|
var c = count[q_uid];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (CLASSIC_MODE) {
|
|
|
|
|
|
|
|
var values = Object.keys(c).map(function (res) {
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', res),
|
|
|
|
|
|
|
|
h('span.cp-count', c[res])
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', [
|
|
|
|
|
|
|
|
h('span.cp-mr-q', q),
|
|
|
|
|
|
|
|
h('span.cp-mr-value', values)
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var table = Charts.table([
|
|
|
|
var table = Charts.table([
|
|
|
|
h('caption', {
|
|
|
|
h('caption', {
|
|
|
|
style: 'color: var(--msg-color)', // XXX light/dark modes
|
|
|
|
style: 'color: var(--msg-color)', // XXX light/dark modes
|
|
|
@ -1333,29 +1332,16 @@ define([
|
|
|
|
'show-heading',
|
|
|
|
'show-heading',
|
|
|
|
'show-data-on-hover',
|
|
|
|
'show-data-on-hover',
|
|
|
|
'show-labels',
|
|
|
|
'show-labels',
|
|
|
|
|
|
|
|
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', {
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', {
|
|
|
|
style: 'width: 100%',
|
|
|
|
style: 'width: 100%',
|
|
|
|
}, table));
|
|
|
|
}, table));
|
|
|
|
/*
|
|
|
|
|
|
|
|
var values = Object.keys(c).map(function (res) {
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', res),
|
|
|
|
|
|
|
|
h('span.cp-count', c[res])
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', [
|
|
|
|
|
|
|
|
h('span.cp-mr-q', q),
|
|
|
|
|
|
|
|
h('span.cp-mr-value', values)
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
results.push(getEmpty(empty));
|
|
|
|
results.push(getEmpty(empty));
|
|
|
|
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
style: 'width: 100%',
|
|
|
|
style: CLASSIC_MODE? '': 'width: 100%',
|
|
|
|
}, results);
|
|
|
|
}, results);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exportCSV: function (answer, form) {
|
|
|
|
exportCSV: function (answer, form) {
|
|
|
@ -1439,8 +1425,7 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid) {
|
|
|
|
printResults: function (answers, uid) {
|
|
|
|
// XXX hackathon radio https://chartscss.org/charts/bar/
|
|
|
|
// results checkbox
|
|
|
|
var results = [];
|
|
|
|
|
|
|
|
var empty = 0;
|
|
|
|
var empty = 0;
|
|
|
|
var count = {};
|
|
|
|
var count = {};
|
|
|
|
Object.keys(answers).forEach(function (author) {
|
|
|
|
Object.keys(answers).forEach(function (author) {
|
|
|
@ -1451,15 +1436,9 @@ define([
|
|
|
|
Util.inc(count, val);
|
|
|
|
Util.inc(count, val);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Object.keys(count).forEach(function (value) {
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', value),
|
|
|
|
|
|
|
|
h('span.cp-count', count[value])
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(getEmpty(empty));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', results);
|
|
|
|
var rendered = renderTally(count, empty /*, caption */);
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', rendered);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
icon: h('i.cptools.cptools-form-list-check')
|
|
|
|
icon: h('i.cptools.cptools-form-list-check')
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -1548,9 +1527,7 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid, form) {
|
|
|
|
printResults: function (answers, uid, form) {
|
|
|
|
// XXX hackathon multicheck
|
|
|
|
// results multicheckbox
|
|
|
|
// stacked: https://chartscss.org/components/stacked/
|
|
|
|
|
|
|
|
// or multiple bars: https://chartscss.org/charts/bar/#multiple-datasets
|
|
|
|
|
|
|
|
var structure = form[uid];
|
|
|
|
var structure = form[uid];
|
|
|
|
if (!structure) { return; }
|
|
|
|
if (!structure) { return; }
|
|
|
|
var opts = structure.opts || TYPES.multicheck.defaultOpts;
|
|
|
|
var opts = structure.opts || TYPES.multicheck.defaultOpts;
|
|
|
@ -1583,6 +1560,21 @@ define([
|
|
|
|
var q = findItem(opts.items, q_uid);
|
|
|
|
var q = findItem(opts.items, q_uid);
|
|
|
|
var c = count[q_uid];
|
|
|
|
var c = count[q_uid];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (CLASSIC_MODE) {
|
|
|
|
|
|
|
|
var values = Object.keys(c).map(function (res) {
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', res),
|
|
|
|
|
|
|
|
h('span.cp-count', c[res])
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', [
|
|
|
|
|
|
|
|
h('span.cp-mr-q', q),
|
|
|
|
|
|
|
|
h('span.cp-mr-value', values)
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var table = Charts.table([
|
|
|
|
var table = Charts.table([
|
|
|
|
h('caption', {
|
|
|
|
h('caption', {
|
|
|
|
style: 'color: var(--msg-color)', // XXX light/dark modes
|
|
|
|
style: 'color: var(--msg-color)', // XXX light/dark modes
|
|
|
@ -1601,23 +1593,11 @@ define([
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', {
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', {
|
|
|
|
style: 'width: 100%',
|
|
|
|
style: 'width: 100%',
|
|
|
|
}, table));
|
|
|
|
}, table));
|
|
|
|
/*
|
|
|
|
|
|
|
|
var values = Object.keys(c).map(function (res) {
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', res),
|
|
|
|
|
|
|
|
h('span.cp-count', c[res])
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-multiradio-data', [
|
|
|
|
|
|
|
|
h('span.cp-mr-q', q),
|
|
|
|
|
|
|
|
h('span.cp-mr-value', values)
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
results.push(getEmpty(empty));
|
|
|
|
results.push(getEmpty(empty));
|
|
|
|
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
style: 'width: 100%',
|
|
|
|
style: CLASSIC_MODE? '': 'width: 100%',
|
|
|
|
}, results);
|
|
|
|
}, results);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exportCSV: function (answer, form) {
|
|
|
|
exportCSV: function (answer, form) {
|
|
|
@ -1725,8 +1705,7 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid, form) {
|
|
|
|
printResults: function (answers, uid, form) {
|
|
|
|
// XXX hackathon sortable list
|
|
|
|
// results sort
|
|
|
|
// bars again? https://chartscss.org/charts/bar/
|
|
|
|
|
|
|
|
var opts = form[uid].opts || TYPES.sort.defaultOpts;
|
|
|
|
var opts = form[uid].opts || TYPES.sort.defaultOpts;
|
|
|
|
var l = (opts.values || []).length;
|
|
|
|
var l = (opts.values || []).length;
|
|
|
|
//var results = [];
|
|
|
|
//var results = [];
|
|
|
@ -1741,41 +1720,11 @@ define([
|
|
|
|
Util.inc(count, el, score);
|
|
|
|
Util.inc(count, el, score);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
var counts = Util.values(count);
|
|
|
|
|
|
|
|
var max = arrayMax(counts);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var rows = [];
|
|
|
|
|
|
|
|
Object.keys(count).forEach(function (text) {
|
|
|
|
|
|
|
|
rows.push(Charts.row(text, count[text] / max, count[text]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var table = Charts.table([
|
|
|
|
|
|
|
|
h('tbody', rows),
|
|
|
|
|
|
|
|
], [
|
|
|
|
|
|
|
|
'charts-css',
|
|
|
|
|
|
|
|
'bar',
|
|
|
|
|
|
|
|
'show-labels',
|
|
|
|
|
|
|
|
'show-data-on-hover',
|
|
|
|
|
|
|
|
//'show-heading',
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var rendered = renderTally(count, empty /*, caption */);
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
return h('div.cp-form-results-type-radio', {
|
|
|
|
style: 'width: 100%',
|
|
|
|
style: CLASSIC_MODE? '': 'width: 100%',
|
|
|
|
}, table);
|
|
|
|
}, rendered);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
var sorted = Object.keys(count).sort(function (a, b) {
|
|
|
|
|
|
|
|
return count[b] - count[a];
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
sorted.forEach(function (value) {
|
|
|
|
|
|
|
|
results.push(h('div.cp-form-results-type-radio-data', [
|
|
|
|
|
|
|
|
h('span.cp-value', value),
|
|
|
|
|
|
|
|
h('span.cp-count', count[value])
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
results.push(getEmpty(empty));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return h('div.cp-form-results-type-radio', results); */
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
icon: h('i.cptools.cptools-form-list-ordered')
|
|
|
|
icon: h('i.cptools.cptools-form-list-ordered')
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -1875,7 +1824,6 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
printResults: function (answers, uid, form, content) {
|
|
|
|
printResults: function (answers, uid, form, content) {
|
|
|
|
// XXX hackathon: not really anything to do here?
|
|
|
|
|
|
|
|
var opts = form[uid].opts || TYPES.poll.defaultOpts;
|
|
|
|
var opts = form[uid].opts || TYPES.poll.defaultOpts;
|
|
|
|
var _answers = getBlockAnswers(answers, uid);
|
|
|
|
var _answers = getBlockAnswers(answers, uid);
|
|
|
|
|
|
|
|
|
|
|
@ -1920,31 +1868,77 @@ define([
|
|
|
|
icon: h('i.cptools.cptools-form-poll')
|
|
|
|
icon: h('i.cptools.cptools-form-poll')
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var getDay = function (d) {
|
|
|
|
|
|
|
|
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var ONE_DAY = 1000 * 60 * 60 * 24;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var getDayArray = function (a, b) {
|
|
|
|
|
|
|
|
// coerce inputs to numbers
|
|
|
|
|
|
|
|
var r_a = +getDay(new Date(a));
|
|
|
|
|
|
|
|
var r_b = +getDay(new Date(b));
|
|
|
|
|
|
|
|
var A = [ r_a ];
|
|
|
|
|
|
|
|
var next = r_a + ONE_DAY;
|
|
|
|
|
|
|
|
while (next <= r_b) {
|
|
|
|
|
|
|
|
A.push(next);
|
|
|
|
|
|
|
|
next += ONE_DAY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return A;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var makeTimeline = APP.makeTimeline = function (answers) {
|
|
|
|
var makeTimeline = APP.makeTimeline = function (answers) {
|
|
|
|
|
|
|
|
|
|
|
|
// Randomly changing date of answers to get a more realistic example of timeline
|
|
|
|
// Randomly changing date of answers to get a more realistic example of timeline
|
|
|
|
Object.keys(answers).forEach(function (k) { // XXX
|
|
|
|
var tally = {};
|
|
|
|
answers[k].time += Math.floor(Math.random() * 10 - 5) * 24 * 3600 * 1000;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var answersByTime = {};
|
|
|
|
//var answersByTime = {};
|
|
|
|
Object.keys(answers).forEach(function (curve) {
|
|
|
|
Object.keys(answers).forEach(function (curve) {
|
|
|
|
var obj = answers[curve];
|
|
|
|
var obj = answers[curve];
|
|
|
|
// Used to get rid of the milliseconds and get unique date to map counts
|
|
|
|
var day = getDay(new Date(obj.time));
|
|
|
|
var key = new Date(obj.time).toLocaleDateString();
|
|
|
|
Util.inc(tally, +day);
|
|
|
|
if (!answersByTime[key]) {
|
|
|
|
|
|
|
|
// Original time kept to ensure a good sort order later
|
|
|
|
|
|
|
|
answersByTime[key] = {date: obj.time, count: 1};
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
answersByTime[key].count++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var times = Object.keys(tally).map(Number).filter(Boolean);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var max_count = arrayMax(Util.values(tally));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var min_day = Math.min.apply(null, times);
|
|
|
|
|
|
|
|
var max_day = arrayMax(times);
|
|
|
|
|
|
|
|
var days = getDayArray(new Date(min_day), new Date(max_day));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return Charts.table(h('tbody', days.map(function (time) {
|
|
|
|
|
|
|
|
var count = tally[time] || 0;
|
|
|
|
|
|
|
|
var percent = count / max_count;
|
|
|
|
|
|
|
|
var date = new Date(time).toLocaleDateString();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var bar = h('td.cp-bar', {
|
|
|
|
|
|
|
|
style: '--size: ' + Number(percent).toFixed(2),
|
|
|
|
|
|
|
|
"data-tippy-placement": "top",
|
|
|
|
|
|
|
|
title: [count, date].join(' - '), // XXX
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
var dateEl = h('th', { scope: "row" }, date);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return h('tr', bar, dateEl );
|
|
|
|
|
|
|
|
})), [
|
|
|
|
|
|
|
|
"charts-css",
|
|
|
|
|
|
|
|
"cp-chart-table",
|
|
|
|
|
|
|
|
"column",
|
|
|
|
|
|
|
|
//"data-spacing-2",
|
|
|
|
|
|
|
|
//"show-labels",
|
|
|
|
|
|
|
|
//"labels-align-center"
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var max = arrayMax(times);
|
|
|
|
|
|
|
|
var min = Math.min.apply(null, times);
|
|
|
|
|
|
|
|
|
|
|
|
var dates = Object.keys(answersByTime).sort(function (a, b) {
|
|
|
|
var dates = Object.keys(answersByTime).sort(function (a, b) {
|
|
|
|
var a = answersByTime[a].time;
|
|
|
|
var a_time = answersByTime[a].time;
|
|
|
|
var b = answersByTime[b].time;
|
|
|
|
var b_time = answersByTime[b].time;
|
|
|
|
return b - a;
|
|
|
|
return b_time - a_time;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
var maxCount = 0;
|
|
|
|
var maxCount = 0;
|
|
|
@ -1978,10 +1972,10 @@ define([
|
|
|
|
var dateEl = h('th', { scope: "row" }, date);
|
|
|
|
var dateEl = h('th', { scope: "row" }, date);
|
|
|
|
|
|
|
|
|
|
|
|
return h('tr', bar, dateEl );
|
|
|
|
return h('tr', bar, dateEl );
|
|
|
|
})), ["charts-css", "cp-chart-table", "column", "data-spacing-2", "show-labels", "labels-align-center"]);
|
|
|
|
})), ["charts-css", "cp-chart-table", "column", "data-spacing-2", "show-labels", "labels-align-center"]); */
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var renderResults = APP.renderResults = function (content, answers, showUser) { // XXX hackathon
|
|
|
|
var renderResults = APP.renderResults = function (content, answers, showUser) {
|
|
|
|
var $container = $('div.cp-form-creator-results').empty();
|
|
|
|
var $container = $('div.cp-form-creator-results').empty();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1996,10 +1990,6 @@ define([
|
|
|
|
DiffMd.apply(DiffMd.render(content.answers.msg), $desc, APP.common);
|
|
|
|
DiffMd.apply(DiffMd.render(content.answers.msg), $desc, APP.common);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// XXX hackathon display answer times as column bar chart with first and last date indicated
|
|
|
|
|
|
|
|
// https://chartscss.org/charts/column/
|
|
|
|
|
|
|
|
// XXX hackathon set column colours with the cryptpad brand color in app-form.less
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var heading = h('h2#cp-title', 'Total answers count: ' + Object.keys(answers).length); // XXX
|
|
|
|
var heading = h('h2#cp-title', 'Total answers count: ' + Object.keys(answers).length); // XXX
|
|
|
|
$(heading).appendTo($container);
|
|
|
|
$(heading).appendTo($container);
|
|
|
|
var timeline = h('div.cp-form-creator-results-timeline');
|
|
|
|
var timeline = h('div.cp-form-creator-results-timeline');
|
|
|
|