aboutsummaryrefslogtreecommitdiff
path: root/assets/js/heatmap.js
diff options
context:
space:
mode:
Diffstat (limited to 'assets/js/heatmap.js')
-rw-r--r--assets/js/heatmap.js339
1 files changed, 0 insertions, 339 deletions
diff --git a/assets/js/heatmap.js b/assets/js/heatmap.js
deleted file mode 100644
index 00dab42..0000000
--- a/assets/js/heatmap.js
+++ /dev/null
@@ -1,339 +0,0 @@
-function calendarHeatmap() {
- // defaults
- var width = Number($(document).width()) - 72;
- var height = 7.5 * (Number($(document).width()) / 70 + 2);
- var legendWidth = 0;
- var selector = 'body';
- var SQUARE_LENGTH = Number($(document).width()) / 70;
- var SQUARE_PADDING = 2;
- var MONTH_LABEL_PADDING = 6;
- var now = moment().endOf('day').toDate();
- var yearAgo = moment().startOf('day').subtract(1, 'year').toDate();
- var startDate = null;
- var counterMap = {};
- var data = [];
- var max = null;
- var colorRange = ['#D8E6E7', '#218380'];
- var tooltipEnabled = true;
- var tooltipUnit = 'watched title';
- var legendEnabled = false;
- var onClick = null;
- var weekStart = 0; //0 for Sunday, 1 for Monday
- var locale = {
- months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
- No: 'No',
- on: 'on',
- Less: 'Less',
- More: 'More'
- };
- var v = Number(d3.version.split('.')[0]);
-
- // setters and getters
- chart.data = function (value) {
- if (!arguments.length) {
- return data;
- }
- data = value;
-
- counterMap = {};
-
- data.forEach(function (element, index) {
- var key = moment(element.date).format('YYYY-MM-DD');
- var counter = counterMap[key] || 0;
- counterMap[key] = counter + element.count;
- });
-
- return chart;
- };
-
- chart.max = function (value) {
- if (!arguments.length) {
- return max;
- }
- max = value;
- return chart;
- };
-
- chart.selector = function (value) {
- if (!arguments.length) {
- return selector;
- }
- selector = value;
- return chart;
- };
-
- chart.startDate = function (value) {
- if (!arguments.length) {
- return startDate;
- }
- yearAgo = value;
- now = moment(value).endOf('day').add(1, 'year').toDate();
- return chart;
- };
-
- chart.colorRange = function (value) {
- if (!arguments.length) {
- return colorRange;
- }
- colorRange = value;
- return chart;
- };
-
- chart.tooltipEnabled = function (value) {
- if (!arguments.length) {
- return tooltipEnabled;
- }
- tooltipEnabled = value;
- return chart;
- };
-
- chart.tooltipUnit = function (value) {
- if (!arguments.length) {
- return tooltipUnit;
- }
- tooltipUnit = value;
- return chart;
- };
-
- chart.legendEnabled = function (value) {
- if (!arguments.length) {
- return legendEnabled;
- }
- legendEnabled = value;
- return chart;
- };
-
- chart.onClick = function (value) {
- if (!arguments.length) {
- return onClick();
- }
- onClick = value;
- return chart;
- };
-
- chart.locale = function (value) {
- if (!arguments.length) {
- return locale;
- }
- locale = value;
- return chart;
- };
-
- function chart() {
-
- d3.select(chart.selector()).selectAll('svg.calendar-heatmap').remove(); // remove the existing chart, if it exists
-
- var dateRange = ((d3.time && d3.time.days) || d3.timeDays)(yearAgo, now); // generates an array of date objects within the specified range
- var monthRange = ((d3.time && d3.time.months) || d3.timeMonths)(moment(yearAgo).startOf('month').toDate(), now); // it ignores the first month if the 1st date is after the start of the month
- var firstDate = moment(dateRange[0]);
- if (chart.data().length == 0) {
- max = 0;
- } else if (max === null) {
- max = d3.max(chart.data(), function (d) {
- return d.count;
- }); // max data value
- }
-
- // color range
- var color = ((d3.scale && d3.scale.linear) || d3.scaleLinear)()
- .range(chart.colorRange())
- .domain([0, max]);
-
- var tooltip;
- var dayRects;
-
- drawChart();
-
- function drawChart() {
- var svg = d3.select(chart.selector())
- .style('position', 'relative')
- .append('svg')
- .attr('width', width)
- .attr('class', 'calendar-heatmap')
- .attr('height', height)
- .style('padding', '36px')
- .style('text-align', 'center');
-
- dayRects = svg.selectAll('.day-cell')
- .data(dateRange); // array of days for the last yr
-
- var enterSelection = dayRects.enter().append('rect')
- .attr('class', 'day-cell')
- .attr('width', SQUARE_LENGTH)
- .attr('height', SQUARE_LENGTH)
- .attr('fill', function (d) {
- return color(countForDate(d));
- })
- .attr('x', function (d, i) {
- var cellDate = moment(d);
- var result = cellDate.week() - firstDate.week() + (firstDate.weeksInYear() * (cellDate.weekYear() - firstDate.weekYear()));
- return result * (SQUARE_LENGTH + SQUARE_PADDING);
- })
- .attr('y', function (d, i) {
- return MONTH_LABEL_PADDING + formatWeekday(d.getDay()) * (SQUARE_LENGTH + SQUARE_PADDING);
- });
-
- if (typeof onClick === 'function') {
- (v === 3 ? enterSelection : enterSelection.merge(dayRects)).on('click', function (d) {
- var count = countForDate(d);
- onClick({
- date: d,
- count: count
- });
- });
- }
-
- if (chart.tooltipEnabled()) {
- (v === 3 ? enterSelection : enterSelection.merge(dayRects)).on('mouseover', function (d, i) {
- tooltip = d3.select(chart.selector())
- .append('div')
- .attr('class', 'day-cell-tooltip')
- .html(tooltipHTMLForDate(d))
- .style('left', function () {
- return Math.floor(i / 7) * SQUARE_LENGTH + 'px';
- })
- .style('top', function () {
- return formatWeekday(d.getDay()) * (SQUARE_LENGTH + SQUARE_PADDING) + MONTH_LABEL_PADDING * 2 + 'px';
- });
- })
- .on('mouseout', function (d, i) {
- tooltip.remove();
- });
- }
-
- if (chart.legendEnabled()) {
- var colorRange = [color(0)];
- for (var i = 3; i > 0; i--) {
- colorRange.push(color(max / i));
- }
-
- var legendGroup = svg.append('g');
- legendGroup.selectAll('.calendar-heatmap-legend')
- .data(colorRange)
- .enter()
- .append('rect')
- .attr('class', 'calendar-heatmap-legend')
- .attr('width', SQUARE_LENGTH)
- .attr('height', SQUARE_LENGTH)
- .attr('x', function (d, i) {
- return (width - legendWidth) + (i + 1) * 13;
- })
- .attr('y', height + SQUARE_PADDING)
- .attr('fill', function (d) {
- return d;
- });
-
- legendGroup.append('text')
- .attr('class', 'calendar-heatmap-legend-text calendar-heatmap-legend-text-less')
- .attr('x', width - legendWidth - 13)
- .attr('y', height + SQUARE_LENGTH)
- .text(locale.Less);
-
- legendGroup.append('text')
- .attr('class', 'calendar-heatmap-legend-text calendar-heatmap-legend-text-more')
- .attr('x', (width - legendWidth + SQUARE_PADDING) + (colorRange.length + 1) * 13)
- .attr('y', height + SQUARE_LENGTH)
- .text(locale.More);
- }
-
- dayRects.exit().remove();
- var monthLabels = svg.selectAll('.month')
- .data(monthRange)
- .enter().append('text')
- .attr('class', 'month-name')
- .text(function (d) {
- return locale.months[d.getMonth()];
- })
- .attr('x', function (d, i) {
- var matchIndex = 0;
- dateRange.find(function (element, index) {
- matchIndex = index;
- return moment(d).isSame(element, 'month') && moment(d).isSame(element, 'year');
- });
-
- return Math.floor(matchIndex / 7) * (SQUARE_LENGTH + SQUARE_PADDING);
- })
- .attr('y', 0); // fix these to the top
-
- locale.days.forEach(function (day, index) {
- index = formatWeekday(index);
- if (index % 2) {
- svg.append('text')
- .attr('class', 'day-initial')
- .attr('transform', 'translate(-8,' + (SQUARE_LENGTH + SQUARE_PADDING) * (index + 1) + ')')
- .style('text-anchor', 'middle')
- .attr('dy', '2')
- .text(day);
- }
- });
- }
-
- function pluralizedTooltipUnit(count) {
- if ('string' === typeof tooltipUnit) {
- return (tooltipUnit + (count === 1 ? '' : 's'));
- }
- for (var i in tooltipUnit) {
- var _rule = tooltipUnit[i];
- var _min = _rule.min;
- var _max = _rule.max || _rule.min;
- _max = _max === 'Infinity' ? Infinity : _max;
- if (count >= _min && count <= _max) {
- return _rule.unit;
- }
- }
- }
-
- function tooltipHTMLForDate(d) {
- var dateStr = moment(d).format('ddd, MMM Do YYYY');
- var count = countForDate(d);
- return '<span><strong>' + (count ? count : locale.No) + ' ' + pluralizedTooltipUnit(count) + '</strong> ' + locale.on + ' ' + dateStr + '</span>';
- }
-
- function countForDate(d) {
- var key = moment(d).format('YYYY-MM-DD');
- return counterMap[key] || 0;
- }
-
- function formatWeekday(weekDay) {
- if (weekStart === 1) {
- if (weekDay === 0) {
- return 6;
- } else {
- return weekDay - 1;
- }
- }
- return weekDay;
- }
-
- }
-
- return chart;
-}
-
-
-// polyfill for Array.find() method
-/* jshint ignore:start */
-if (!Array.prototype.find) {
- Array.prototype.find = function (predicate) {
- if (this === null) {
- throw new TypeError('Array.prototype.find called on null or undefined');
- }
- if (typeof predicate !== 'function') {
- throw new TypeError('predicate must be a function');
- }
- var list = Object(this);
- var length = list.length >>> 0;
- var thisArg = arguments[1];
- var value;
-
- for (var i = 0; i < length; i++) {
- value = list[i];
- if (predicate.call(thisArg, value, i, list)) {
- return value;
- }
- }
- return undefined;
- };
-}
-/* jshint ignore:end */ \ No newline at end of file