diff options
Diffstat (limited to 'result/krafcik.js')
-rw-r--r-- | result/krafcik.js | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/result/krafcik.js b/result/krafcik.js new file mode 100644 index 0000000..a65a73b --- /dev/null +++ b/result/krafcik.js @@ -0,0 +1,323 @@ +$(document).ready(function() { + + $.when( + $.getJSON('beers.json'), + $.getJSON('breweries.json'), + $.getJSON('styles.json') + ).done(function(beerData, breweryData, styleData) { + var beers = beerData[0]; + $.each(beers, function(idx, beer) { + beer['scatter-data'] = [ + { + x: beer.abv, + y: beer.ratings + }, + { + x: beer.abv, + y: beer.average + }, + { + x: beer.ratings, + y: beer.average + } + ]; + }); + 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 fullYears = maxYear - minYear - 1; + var dateCount = fullYears * 12 + (12 - minMonth + 1) + maxMonth; + var dateMapping = []; + var year = minYear; + var month = minMonth; + for (var c = 0; c < dateCount; c++) { + dateMapping[c] = year + '-' + ('0' + month).slice(-2); + month++; + if (month > 12) { + year++; + month = 1; + } + } + var valSpan = [0, dateCount-1]; + var currRange = 12-minMonth+1; + var lastRange = 'odd'; + var yearRanges = [{'start': 0, 'end': currRange-1, 'class': lastRange}]; + while (currRange < dateCount) { + lastRange = lastRange == 'odd' ? 'even' : 'odd'; + yearRanges.push({ + 'start': currRange, + 'end': Math.min(currRange+11, dateCount-1), + 'class': lastRange + }); + currRange += 12; + } + $('#date-filter input[name="date"]').slider({ + min: 0, + max: dateCount-1, + value: valSpan, + ticks: valSpan, + ticks_labels: valSpan.map(v => dateMapping[v]), + rangeHighlights: yearRanges, + formatter: function(val) { + if (isNaN(val)) { + return val.map(v => dateMapping[v]).join(' - '); + } + else { + return dateMapping[val]; + } + } + }); + + var breweries = breweryData[0]; + var breweryTemplate = $('#brewery-template').html(); + var breweryFilter = $('#brewery-filter'); + $.each(breweries, function(brewery, data) { + var fieldId = 'brewery-' + brewery; + var field = $(breweryTemplate); + field.find('input').attr('value', brewery).attr('id', fieldId); + field.find('label').attr('for', fieldId).attr('title', data['name']).find('img').attr('src', 'img/' + data['logo']); + breweryFilter.append(field); + field.find('label').tooltip(); + }); + $('#brewery-all').change(function() { + if ($(this).is(':checked')) { + $('#brewery-filter .form-check input').prop('checked', 'checked'); + } else { + $('#brewery-filter .form-check input').prop('checked', null); + } + }); + + var styles = styleData[0]; + $.each(styles, function(idx, style) { + style.styleTree = {}; + $.each(style.styles.map(s => s.split(' - ')), function(idx, splitStyle) { + if (splitStyle.length > 1) { + if (!style.styleTree[splitStyle[0]]) { + style.styleTree[splitStyle[0]] = []; + } + style.styleTree[splitStyle[0]].push(splitStyle[1]); + } else { + style.styleTree[splitStyle[0]] = null; + } + }); + }); + var styleNames = styles.map(s => s.name); + var styleCounts = styles.map(s => 0); + var substyleCounts = []; + var styleSubstyles = styles.map(s => s.styles); + var styleColours = styles.map(s => s.colour); + var scatterChartData = []; + for (var i = 0; i < 3; i++) { + scatterChartData[i] = { + datasets: styles.map(function(style) { + return { + borderColor: style.colour, + backgroundColor: Color(style.colour).alpha(0.5).rgbString(), + data: [] + }; + }) + }; + } + var stylesChart; + $('a#styles-tab').on('shown.bs.tab', function() { + if (!stylesChart) { + var ctx = $('#styles-chart')[0].getContext('2d'); + stylesChart = new Chart(ctx, { + type: 'bar', + data: { + labels: styleNames, + datasets: [{ + data: styleCounts, + backgroundColor: styleColours, + borderColor: '#000000', + borderWidth: 1 + }] + }, + options: { + legend: { + display: false + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true + } + }] + }, + 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) { + 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]; + if (count) { + var term = $('<dt>'); + var value = $('<dd>'); + var item = $('<li>').append($('<dl>').append(term).append(value)); + term.html(substyle || style); + value.html(count); + return item; + } + return null; + }; + if (substyles) { + var sublist = $('<ul>'); + var nonZero = false; + $.each(substyles, function(id, substyle) { + var item = getItem(style, substyle); + if (item) { + sublist.append(item); + nonZero = true; + } + }); + if (nonZero) { + content.append($('<li>').append(style).append(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(); + } + } + } + } + }); + } + }); + var abvRatingsChart; + $('a#abv-ratings-tab').on('shown.bs.tab', function() { + if (!abvRatingsChart) { + var ctx = $('#abv-ratings-chart')[0].getContext('2d'); + abvRatingsChart = new Chart.Scatter(ctx, { + data: scatterChartData[0], + options: { + scales: { + yAxes: [{ + type: 'logarithmic', + }] + } + } + + }); + } + }); + var abvAverageChart; + $('a#abv-average-tab').on('shown.bs.tab', function() { + if (!abvAverageChart) { + var ctx = $('#abv-average-chart')[0].getContext('2d'); + abvAverageChart = new Chart.Scatter(ctx, { + data: scatterChartData[1] + }); + } + }); + var ratingsAverageChart; + $('a#ratings-average-tab').on('shown.bs.tab', function() { + if (!ratingsAverageChart) { + var ctx = $('#ratings-average-chart')[0].getContext('2d'); + ratingsAverageChart = new Chart.Scatter(ctx, { + data: scatterChartData[2], + options: { + scales: { + xAxes: [{ + type: 'logarithmic', + }] + } + } + }); + } + }); + + var getFilteredBeers = function(beers) { + 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); + return (breweries.indexOf(beer.brewery) > -1) + && (added >= dates[0] && added <= dates[1]); + }); + }; + + var updateCharts = function() { + var filtered = getFilteredBeers(beers); + var bySubstyle = {}; + for (var style in substyleCounts) { + substyleCounts[style] = 0; + } + for (var beer in filtered) { + var style = filtered[beer].style.join(' - '); + if (!substyleCounts[style]) { + substyleCounts[style] = 0; + } + substyleCounts[style]++; + if (!bySubstyle[style]) { + bySubstyle[style] = []; + } + bySubstyle[style].push(filtered[beer]['scatter-data']); + } + for (var s in styleCounts) { + styleCounts[s] = 0; + for (var i = 0; i < 3; i++) { + scatterChartData[i].datasets[s].data = []; + } + for (var ss in styleSubstyles[s]) { + 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])); + } + } + } + } + if (stylesChart) { + stylesChart.update(); + } + if (abvRatingsChart) { + abvRatingsChart.update(); + } + if (abvAverageChart) { + abvAverageChart.update(); + } + if (ratingsAverageChart) { + ratingsAverageChart.update(); + } + }; + + var changeTimeout = null; + $('#date-filter, #brewery-filter').find('input').change(function() { + clearTimeout(changeTimeout); + changeTimeout = setTimeout(updateCharts, 500); + }); + + $('a#styles-tab').trigger('shown.bs.tab'); + updateCharts(); + }); + + $('#tab-menu a').on('click', function (e) { + e.preventDefault() + $(this).tab('show') + }) +}); |