{% extends 'html.html' %} {% block title %}Statistics{% endblock %} {% block header %} {% endblock %} {% block style %} .content.header, .content.loading, .content.footer { text-align: center; } .content.loading { font-size: 3rem; } h2 { margin-top: .1rem; } .content { padding-top: 3rem; padding-bottom: 3rem; } .contentInner { padding-left: 3rem; padding-right: 3rem; } .version { margin-top: -2rem; } .visualization h2 { text-align: center; font-size: 2.4rem; margin-bottom: -1rem; } .visualization h3 { text-align: center; font-size: 1.6rem; margin-top: 4rem; } .visualization .visOuter { position: relative; text-align: center; } .visualization .visOuter .vis { position: initial; padding-right: 0; } .visualization .visOuter .vis details { position: absolute; right: -40px; top: 4px; } .textLarge { font-size: 2rem; } .text { font-size: 1.4rem; } ul.contentInner { list-style-position: inside; margin-bottom: 0; } {% endblock %} {% block script %} // STATISTICS const bundleStatisticsInSheets = statistics => { ss = [] lastKey = null lastTitle = null for (const s of statistics) { if (ss.length == 0 || s['key'] != lastKey || s['title'] != lastTitle) ss.push([]) lastKey = s['key'] lastTitle = s['title'] ss[ss.length - 1].push(s) } return ss } // HELPERS FOR THE VISUALIZATION const dataAggregate = data => { r = {} for (const d of data) { if (r[d] === undefined) r[d] = 0 r[d] += 1 } return Object.entries(r).map(x => ({'value': x[0], 'count':x[1]})) } const _dataKeyValueForList = (data, defaultKey='key') => data .filter(v => v !== null) .map(v => ((v instanceof Object) ? Object.entries(v).map((x, _) => ({key: x[0], value: x[1]})) : [{key: defaultKey, value: v}])) .flat() const dataKeyValue = data => { if (Array.isArray(data)) return _dataKeyValueForList(data) else return Object.entries(data).map((x, _) => _dataKeyValueForList(x[1], x[0])).flat() } const visVegaLite = (c, id, spec) => { $(c).append(`