summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--result/index.html10
-rw-r--r--result/krafcik.css18
-rw-r--r--result/krafcik.js156
3 files changed, 123 insertions, 61 deletions
diff --git a/result/index.html b/result/index.html
index 4a8009c..e136110 100644
--- a/result/index.html
+++ b/result/index.html
@@ -17,7 +17,7 @@
<main class="container">
- <h1>Polski Krafcik <span class="lead">2012-2020</span></h1>
+ <h1>Polski Krafcik <span class="lead">2012-2020 <small>(R.I.P.)</small></span></h1>
<form id="filters">
@@ -73,6 +73,14 @@
</div>
</div>
+ <div class="card">
+ <div class="card-body">
+ Browary o co najmniej 10.000 ocen. Piwa o co najmniej 15 ocenach, o określonym ABV i dodane w 2020 lub wcześniej.<br />
+ Liczba ocen przeliczana per miesiąc od czasu dodania; dla piw nieprodukowanych: max. 12 miesięcy.<br />
+ Dane pobrane z Untappd <time id="compile-date" datetime="2021-01-10">19 stycznia 2021</time>.<br />
+ </div>
+ </div>
+
</main><!-- /.container -->
<template id="brewery-template">
diff --git a/result/krafcik.css b/result/krafcik.css
index 55a8a98..53de009 100644
--- a/result/krafcik.css
+++ b/result/krafcik.css
@@ -30,15 +30,15 @@ html, body {
}
#brewery-filter label img {
- width: 30px;
+ width: 50px;
}
#chart-tooltip {
position: absolute;
background: rgba(255, 255, 200, 0.75);
+ border: solid 1px black;
padding: 0.5em;
font-size: 0.7em;
- border: solid 1px black;
pointer-events: none;
}
@@ -56,18 +56,20 @@ html, body {
}
#chart-tooltip dl {
- display: flex;
+ display: grid;
+ width: 100%;
+ grid-column-gap: 1em;
+ grid-template-columns: 1fr min-content;
margin: 0;
+ padding: 0 0.5em 0 0;
}
-#chart-tooltip dt {
- width: 80%;
+#chart-tooltip dt,
+#chart-tooltip dd {
+ margin: 0;
white-space: nowrap;
}
#chart-tooltip dd {
- margin: 0;
- width: 20%;
- min-width: 30px;
text-align: right;
}
diff --git a/result/krafcik.js b/result/krafcik.js
index cdb0b9e..d0b70a7 100644
--- a/result/krafcik.js
+++ b/result/krafcik.js
@@ -5,27 +5,40 @@ $(document).ready(function() {
$.getJSON('breweries.json'),
$.getJSON('styles.json')
).done(function(beerData, breweryData, styleData) {
+ var compileDate = Date.parse($('time#compile-date').attr('datetime'));
var beers = beerData[0];
$.each(beers, function(idx, beer) {
+ var addedDate = new Date();
+ addedDate.setYear(beer.added.year);
+ addedDate.setMonth(beer.added.month-1);
+ addedDate.setDate(beer.added.day);
+ var dateDiff = Math.ceil((compileDate - addedDate.getTime()) / (1000 * 60 * 60 * 24 * 30));
+ if (!beer.in_production) {
+ dateDiff = Math.min(dateDiff, 12);
+ }
+ beer.ratings.adjusted = beer.ratings.count / dateDiff;
beer['scatter-data'] = [
{
x: beer.abv,
- y: beer.ratings
+ y: beer.ratings.adjusted,
+ ref: beer
},
{
x: beer.abv,
- y: beer.average
+ y: beer.ratings.average,
+ reef: beer
},
{
- x: beer.ratings,
- y: beer.average
+ x: beer.ratings.adjusted,
+ y: beer.ratings.average,
+ ref: beer
}
];
});
- var minYear = Math.min.apply(null, beers.map(b => b.year));
- var maxYear = Math.max.apply(null, beers.map(b => b.year));
- var minMonth = Math.min.apply(null, beers.filter(b => (b.year == minYear)).map(b => b.month));
- var maxMonth = Math.min.apply(null, beers.filter(b => (b.year == maxYear)).map(b => b.month));
+ var minYear = Math.min.apply(null, beers.map(b => b.added.year));
+ var maxYear = Math.max.apply(null, beers.map(b => b.added.year));
+ var minMonth = Math.min.apply(null, beers.filter(b => (b.added.year == minYear)).map(b => b.added.month));
+ var maxMonth = Math.max.apply(null, beers.filter(b => (b.added.year == maxYear)).map(b => b.added.month));
var fullYears = maxYear - minYear - 1;
var dateCount = fullYears * 12 + (12 - minMonth + 1) + maxMonth;
var dateMapping = [];
@@ -114,11 +127,65 @@ $(document).ready(function() {
return {
borderColor: style.colour,
backgroundColor: Color(style.colour).alpha(0.5).rgbString(),
+ label: style.name,
data: []
};
})
};
}
+
+ var displayTooltip = function(chart, tooltip, data, contentFunction) {
+ var container = $('#chart-tooltip');
+ if (!container.length) {
+ container = $('<div id="chart-tooltip"></div>');
+ $('body').append(container);
+ }
+ if (tooltip.body) {
+ var positionY = chart.canvas.offsetTop;
+ var positionX = chart.canvas.offsetLeft;
+ container.html(contentFunction(tooltip, data)).show();
+ container.css({
+ 'top': Math.min(
+ positionY + tooltip.caretY,
+ $('body').height() - container.outerHeight()
+ ),
+ 'left': Math.min(
+ positionX + tooltip.caretX,
+ $('body').width() - container.outerWidth()
+ )
+ }).addClass(chart.canvas.id).show();
+ } else {
+ container.html('').removeAttr('class').hide();
+ }
+ };
+ var scatterTooltip = function(tooltip, data) {
+ var content = $('<div>');
+ var datasets = data.datasets;
+ $.each(tooltip.dataPoints, function(d, dataPoint) {
+ var beer = datasets[dataPoint.datasetIndex].data[dataPoint.index].ref;
+ content.append(
+ $('<div>').append($('<strong>').text(beer.name)),
+ $('<div>').append($('<span>').text(breweries[beer.brewery].name)),
+ $('<div>').append($('<em>').text(beer.style.join(' - '))),
+ $('<dl>').append(
+ $('<dt>').text('ABV'),
+ $('<dd>').text(`${beer.abv}%`),
+ $('<dt>').text('L. ocen'),
+ $('<dd>').text(beer.ratings.count),
+ $('<dt>').text('Śr. ocen'),
+ $('<dd>').text(beer.ratings.average),
+ $('<dt>').text('Dodane'),
+ $('<dd>').text([
+ `0${beer.added.day}`.slice(-2),
+ `0${beer.added.month}`.slice(-2),
+ beer.added.year
+ ].join('-'))
+ )
+ );
+ });
+ return content;
+ };
+
var stylesChart;
$('a#styles-tab').on('shown.bs.tab', function() {
if (!stylesChart) {
@@ -129,8 +196,8 @@ $(document).ready(function() {
labels: styleNames,
datasets: [{
data: styleCounts,
- backgroundColor: styleColours,
- borderColor: '#000000',
+ backgroundColor: styleColours.map(c => Color(c).alpha(0.5).rgbString()),
+ borderColor: styleColours,
borderWidth: 1
}]
},
@@ -148,20 +215,15 @@ $(document).ready(function() {
tooltips: {
enabled: false,
custom: function(tooltip) {
- var container = $('#chart-tooltip');
- if (!container.length) {
- container = $('<div id="chart-tooltip"></div>');
- $('body').append(container);
- }
- if (tooltip.body) {
+ displayTooltip(this._chart, tooltip, this._data, function(tooltip, data) {
var content = $('<ul>');
$.each(styles[tooltip.dataPoints[0].index].styleTree, function(style, substyles) {
var getItem = function(style, substyle) {
- var count = substyleCounts[substyle ? (style + ' - ' + substyle) : style];
+ var count = substyleCounts[substyle ? (`${style} - ${substyle}`) : style];
if (count) {
var term = $('<dt>');
var value = $('<dd>');
- var item = $('<li>').append($('<dl>').append(term).append(value));
+ var item = $('<li>').append($('<dl>').append(term, value));
term.html(substyle || style);
value.html(count);
return item;
@@ -179,28 +241,14 @@ $(document).ready(function() {
}
});
if (nonZero) {
- content.append($('<li>').append(style).append(sublist));
+ content.append($('<li>').append(style, sublist));
}
} else {
content.append(getItem(style));
}
});
- var positionY = this._chart.canvas.offsetTop;
- var positionX = this._chart.canvas.offsetLeft;
- container.html(content).show();
- container.css({
- 'top': Math.min(
- positionY + tooltip.caretY,
- $('body').height() - container.outerHeight()
- ),
- 'left': Math.min(
- positionX + tooltip.caretX,
- $('body').width() - container.outerWidth()
- )
- }).show();
- } else {
- container.html('').hide();
- }
+ return content;
+ });
}
}
}
@@ -210,22 +258,20 @@ $(document).ready(function() {
var ratingAxis = {
type: 'logarithmic',
ticks: {
- min: 15,
- max: Math.ceil(Math.max.apply(null, beers.map(b => b.ratings)) / 1000) * 1000,
- callback: value => value.toLocaleString()
+ min: 0,
+ callback: value => value.toLocaleString(),
+ autoSkipPadding: 20
}
};
var averageAxis = {
ticks: {
- min: Math.floor(Math.min.apply(null, beers.map(b => b.average)) * 2) * 0.5,
+ min: Math.floor(Math.min.apply(null, beers.map(b => b.ratings.average)) * 2) * 0.5,
max: 5
}
};
var abvAxis = {
ticks: {
- beginAtZero: true,
- min: 0,
- max: Math.ceil(Math.max.apply(null, beers.map(b => b.abv)) * 2) * 0.5
+ min: 0
}
};
var abvRatingsChart;
@@ -240,7 +286,6 @@ $(document).ready(function() {
yAxes: [ratingAxis]
}
}
-
});
}
});
@@ -269,6 +314,12 @@ $(document).ready(function() {
scales: {
xAxes: [ratingAxis],
yAxes: [averageAxis]
+ },
+ tooltips: {
+ enabled: false,
+ custom: function(tooltip) {
+ displayTooltip(this._chart, tooltip, this._data, scatterTooltip);
+ }
}
}
});
@@ -279,7 +330,7 @@ $(document).ready(function() {
var dates = $('#date-filter input[name="date"]').val().split(',').map(d => dateMapping[parseInt(d)]);
var breweries = $('#brewery-filter input:checked').map(function(i, input) { return input.value; }).toArray();
return beers.filter(function(beer) {
- var added = beer.year + '-' + ('0' + beer.month).slice(-2);
+ var added = beer.added.year + '-' + `0${beer.added.month}`.slice(-2);
return (breweries.indexOf(beer.brewery) > -1)
&& (added >= dates[0] && added <= dates[1]);
});
@@ -288,8 +339,8 @@ $(document).ready(function() {
var updateCharts = function() {
var filtered = getFilteredBeers(beers);
var bySubstyle = {};
- for (var style in substyleCounts) {
- substyleCounts[style] = 0;
+ for (var s in substyleCounts) {
+ substyleCounts[s] = 0;
}
for (var beer in filtered) {
var style = filtered[beer].style.join(' - ');
@@ -311,8 +362,8 @@ $(document).ready(function() {
var substyle = styleSubstyles[s][ss];
if (substyleCounts[substyle]) {
styleCounts[s] += substyleCounts[substyle];
- for (var i = 0; i < 3; i++) {
- scatterChartData[i].datasets[s].data = scatterChartData[i].datasets[s].data.concat(bySubstyle[substyle].map(d => d[i]));
+ for (var j = 0; j < 3; j++) {
+ scatterChartData[j].datasets[s].data = scatterChartData[j].datasets[s].data.concat(bySubstyle[substyle].map(d => d[j]));
}
}
}
@@ -337,12 +388,13 @@ $(document).ready(function() {
changeTimeout = setTimeout(updateCharts, 500);
});
- $('a#styles-tab').trigger('shown.bs.tab');
+ var pageHash = location.hash.replace('#', '') || 'styles';
+ $(`a#${pageHash}-tab`).click().trigger('shown.bs.tab');
updateCharts();
});
$('#tab-menu a').on('click', function (e) {
- e.preventDefault()
- $(this).tab('show')
- })
+ e.preventDefault();
+ $(this).tab('show');
+ });
});