@@ -252,6 +252,9 @@ const FULL_ANGLE = 360; | |||||
// More colors are difficult to parse visually | // More colors are difficult to parse visually | ||||
const HEATMAP_DISTRIBUTION_SIZE = 5; | const HEATMAP_DISTRIBUTION_SIZE = 5; | ||||
const HEATMAP_SQUARE_SIZE = 10; | |||||
const HEATMAP_GUTTER_SIZE = 2; | |||||
const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | ||||
const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | ||||
'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | 'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | ||||
@@ -2131,6 +2134,13 @@ class PieChart extends AggregationChart { | |||||
// Playing around with dates | // Playing around with dates | ||||
const NO_OF_YEAR_MONTHS = 12; | |||||
const NO_OF_DAYS_IN_WEEK = 7; | |||||
const NO_OF_MILLIS = 1000; | |||||
const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | |||||
"July", "August", "September", "October", "November", "December"]; | |||||
// https://stackoverflow.com/a/11252167/6495043 | // https://stackoverflow.com/a/11252167/6495043 | ||||
function treatAsUtc(dateStr) { | function treatAsUtc(dateStr) { | ||||
let result = new Date(dateStr); | let result = new Date(dateStr); | ||||
@@ -2162,6 +2172,11 @@ function addDays(date, numberOfDays) { | |||||
date.setDate(date.getDate() + numberOfDays); | date.setDate(date.getDate() + numberOfDays); | ||||
} | } | ||||
function getMonthName(i, short=false) { | |||||
let monthName = MONTH_NAMES[i]; | |||||
return short ? monthName.slice(0, 3) : monthName; | |||||
} | |||||
function normalize(x) { | function normalize(x) { | ||||
// Calculates mantissa and exponent of a number | // Calculates mantissa and exponent of a number | ||||
// Returns normalized number and exponent | // Returns normalized number and exponent | ||||
@@ -2373,30 +2388,24 @@ function getMaxCheckpoint(value, distribution) { | |||||
return distribution.filter(d => d < value).length; | return distribution.filter(d => d < value).length; | ||||
} | } | ||||
const COL_SIZE = HEATMAP_SQUARE_SIZE + HEATMAP_GUTTER_SIZE; | |||||
class Heatmap extends BaseChart { | class Heatmap extends BaseChart { | ||||
constructor(parent, options) { | constructor(parent, options) { | ||||
super(parent, options); | super(parent, options); | ||||
this.type = 'heatmap'; | this.type = 'heatmap'; | ||||
this.data = options.data || {}; | |||||
this.dataPoints = options.data.dataPoints || {}; | |||||
this.discreteDomains = options.discreteDomains === 0 ? 0 : 1; | this.discreteDomains = options.discreteDomains === 0 ? 0 : 1; | ||||
this.countLabel = options.countLabel || ''; | this.countLabel = options.countLabel || ''; | ||||
let today = new Date(); | |||||
this.start = options.start || addDays(today, 365); | |||||
this.translateX = 0; | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
setMargins() { | |||||
super.setMargins(); | |||||
this.leftMargin = 10; | |||||
this.translateY = 10; | |||||
} | |||||
configure(args) { | configure(args) { | ||||
super.configure(args); | super.configure(args); | ||||
this.start = args.data.start; | |||||
this.today = new Date(); | this.today = new Date(); | ||||
if(!this.start) { | if(!this.start) { | ||||
@@ -2405,20 +2414,26 @@ class Heatmap extends BaseChart { | |||||
} | } | ||||
this.firstWeekStart = new Date(this.start.toDateString()); | this.firstWeekStart = new Date(this.start.toDateString()); | ||||
this.lastWeekStart = new Date(this.today.toDateString()); | this.lastWeekStart = new Date(this.today.toDateString()); | ||||
if(this.firstWeekStart.getDay() !== 7) { | |||||
if(this.firstWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.firstWeekStart, (-1) * this.firstWeekStart.getDay()); | addDays(this.firstWeekStart, (-1) * this.firstWeekStart.getDay()); | ||||
} | } | ||||
if(this.lastWeekStart.getDay() !== 7) { | |||||
if(this.lastWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.lastWeekStart, (-1) * this.lastWeekStart.getDay()); | addDays(this.lastWeekStart, (-1) * this.lastWeekStart.getDay()); | ||||
} | } | ||||
this.no_of_cols = getWeeksBetween(this.firstWeekStart + '', this.lastWeekStart + '') + 1; | this.no_of_cols = getWeeksBetween(this.firstWeekStart + '', this.lastWeekStart + '') + 1; | ||||
} | } | ||||
setMargins() { | |||||
super.setMargins(); | |||||
this.leftMargin = HEATMAP_SQUARE_SIZE; | |||||
this.translateY = HEATMAP_SQUARE_SIZE; | |||||
} | |||||
calcWidth() { | calcWidth() { | ||||
this.baseWidth = (this.no_of_cols + 3) * 12 ; | |||||
this.baseWidth = (this.no_of_cols) * COL_SIZE; | |||||
if(this.discreteDomains) { | if(this.discreteDomains) { | ||||
this.baseWidth += (12 * 12); | |||||
this.baseWidth += (COL_SIZE * NO_OF_YEAR_MONTHS); | |||||
} | } | ||||
} | } | ||||
@@ -2440,13 +2455,8 @@ class Heatmap extends BaseChart { | |||||
} | } | ||||
calc() { | calc() { | ||||
let dataValues = Object.keys(this.data).map(key => this.data[key]); | |||||
let dataValues = Object.keys(this.dataPoints).map(key => this.dataPoints[key]); | |||||
this.distribution = calcDistribution(dataValues, HEATMAP_DISTRIBUTION_SIZE); | this.distribution = calcDistribution(dataValues, HEATMAP_DISTRIBUTION_SIZE); | ||||
this.monthNames = ["January", "February", "March", "April", "May", "June", | |||||
"July", "August", "September", "October", "November", "December" | |||||
]; | |||||
} | } | ||||
render() { | render() { | ||||
@@ -2465,7 +2475,6 @@ class Heatmap extends BaseChart { | |||||
this.months = [this.currentMonth + '']; | this.months = [this.currentMonth + '']; | ||||
this.monthWeeks = {}, this.monthStartPoints = []; | this.monthWeeks = {}, this.monthStartPoints = []; | ||||
this.monthWeeks[this.currentMonth] = 0; | this.monthWeeks[this.currentMonth] = 0; | ||||
this.monthStartPoints.push(13); | |||||
for(var i = 0; i < no_of_weeks; i++) { | for(var i = 0; i < no_of_weeks; i++) { | ||||
let dataGroup, monthChange = 0; | let dataGroup, monthChange = 0; | ||||
@@ -2476,19 +2485,16 @@ class Heatmap extends BaseChart { | |||||
this.weekCol += 1 + parseInt(this.discreteDomains && monthChange); | this.weekCol += 1 + parseInt(this.discreteDomains && monthChange); | ||||
this.monthWeeks[this.currentMonth]++; | this.monthWeeks[this.currentMonth]++; | ||||
if(monthChange) { | if(monthChange) { | ||||
this.currentMonth = (this.currentMonth + 1) % 12; | |||||
this.currentMonth = (this.currentMonth + 1) % NO_OF_YEAR_MONTHS; | |||||
this.months.push(this.currentMonth + ''); | this.months.push(this.currentMonth + ''); | ||||
this.monthWeeks[this.currentMonth] = 1; | this.monthWeeks[this.currentMonth] = 1; | ||||
} | } | ||||
addDays(currentWeekSunday, 7); | |||||
addDays(currentWeekSunday, NO_OF_DAYS_IN_WEEK); | |||||
} | } | ||||
this.render_month_labels(); | this.render_month_labels(); | ||||
} | } | ||||
get_week_squares_group(currentDate, index) { | get_week_squares_group(currentDate, index) { | ||||
const noOfWeekdays = 7; | |||||
const squareSide = 10; | |||||
const cellPadding = 2; | |||||
const step = 1; | const step = 1; | ||||
const todayTime = this.today.getTime(); | const todayTime = this.today.getTime(); | ||||
@@ -2497,26 +2503,26 @@ class Heatmap extends BaseChart { | |||||
let dataGroup = makeSVGGroup(this.dataGroups, 'data-group'); | let dataGroup = makeSVGGroup(this.dataGroups, 'data-group'); | ||||
for(var y = 0, i = 0; i < noOfWeekdays; i += step, y += (squareSide + cellPadding)) { | |||||
for(var y = 0, i = 0; i < NO_OF_DAYS_IN_WEEK; i += step, y += COL_SIZE) { | |||||
let dataValue = 0; | let dataValue = 0; | ||||
let colorIndex = 0; | let colorIndex = 0; | ||||
let currentTimestamp = currentDate.getTime()/1000; | |||||
let currentTimestamp = currentDate.getTime()/NO_OF_MILLIS; | |||||
let timestamp = Math.floor(currentTimestamp - (currentTimestamp % 86400)).toFixed(1); | let timestamp = Math.floor(currentTimestamp - (currentTimestamp % 86400)).toFixed(1); | ||||
if(this.data[timestamp]) { | |||||
dataValue = this.data[timestamp]; | |||||
if(this.dataPoints[timestamp]) { | |||||
dataValue = this.dataPoints[timestamp]; | |||||
} | } | ||||
if(this.data[Math.round(timestamp)]) { | |||||
dataValue = this.data[Math.round(timestamp)]; | |||||
if(this.dataPoints[Math.round(timestamp)]) { | |||||
dataValue = this.dataPoints[Math.round(timestamp)]; | |||||
} | } | ||||
if(dataValue) { | if(dataValue) { | ||||
colorIndex = getMaxCheckpoint(dataValue, this.distribution); | colorIndex = getMaxCheckpoint(dataValue, this.distribution); | ||||
} | } | ||||
let x = 13 + (index + weekColChange) * 12; | |||||
let x = (index + weekColChange) * COL_SIZE; | |||||
let dataAttr = { | let dataAttr = { | ||||
'data-date': getDdMmYyyy(currentDate), | 'data-date': getDdMmYyyy(currentDate), | ||||
@@ -2524,7 +2530,7 @@ class Heatmap extends BaseChart { | |||||
'data-day': currentDate.getDay() | 'data-day': currentDate.getDay() | ||||
}; | }; | ||||
let heatSquare = makeHeatSquare('day', x, y, squareSide, | |||||
let heatSquare = makeHeatSquare('day', x, y, HEATMAP_SQUARE_SIZE, | |||||
this.colors[colorIndex], dataAttr); | this.colors[colorIndex], dataAttr); | ||||
dataGroup.appendChild(heatSquare); | dataGroup.appendChild(heatSquare); | ||||
@@ -2540,7 +2546,7 @@ class Heatmap extends BaseChart { | |||||
weekColChange = 1; | weekColChange = 1; | ||||
} | } | ||||
this.monthStartPoints.push(13 + (index + weekColChange) * 12); | |||||
this.monthStartPoints.push((index + weekColChange) * COL_SIZE); | |||||
} | } | ||||
currentDate = nextDate; | currentDate = nextDate; | ||||
} | } | ||||
@@ -2569,8 +2575,8 @@ class Heatmap extends BaseChart { | |||||
this.monthStartPoints.pop(); | this.monthStartPoints.pop(); | ||||
this.monthStartPoints.map((start, i) => { | this.monthStartPoints.map((start, i) => { | ||||
let month_name = this.monthNames[this.months[i]].substring(0, 3); | |||||
let text = makeText('y-value-text', start+12, 10, month_name); | |||||
let month_name = getMonthName(this.months[i], true); | |||||
let text = makeText('y-value-text', start + COL_SIZE, HEATMAP_SQUARE_SIZE, month_name); | |||||
this.domainLabelGroup.appendChild(text); | this.domainLabelGroup.appendChild(text); | ||||
}); | }); | ||||
} | } | ||||
@@ -2583,7 +2589,7 @@ class Heatmap extends BaseChart { | |||||
let count = e.target.getAttribute('data-value'); | let count = e.target.getAttribute('data-value'); | ||||
let dateParts = e.target.getAttribute('data-date').split('-'); | let dateParts = e.target.getAttribute('data-date').split('-'); | ||||
let month = this.monthNames[parseInt(dateParts[1])-1].substring(0, 3); | |||||
let month = getMonthName(parseInt(dateParts[1])-1, true); | |||||
let gOff = this.chartWrapper.getBoundingClientRect(), pOff = e.target.getBoundingClientRect(); | let gOff = this.chartWrapper.getBoundingClientRect(), pOff = e.target.getBoundingClientRect(); | ||||
@@ -449,10 +449,18 @@ for (var i = 0; i< 375; i++) { | |||||
timestamp = Math.floor(timestamp - 86400).toFixed(1); | timestamp = Math.floor(timestamp - 86400).toFixed(1); | ||||
} | } | ||||
let today = new Date(); | |||||
let start = today; | |||||
let end = ''; | |||||
start.setFullYear( start.getFullYear() - 2 ); | |||||
let heatmap = new frappe.Chart("#chart-heatmap", { | let heatmap = new frappe.Chart("#chart-heatmap", { | ||||
data: heatmapData, | |||||
data: { | |||||
dataPoints: heatmapData, | |||||
start: start, | |||||
end: end, | |||||
}, | |||||
type: 'heatmap', | type: 'heatmap', | ||||
legendScale: [0, 1, 2, 4, 5], | |||||
height: 115, | height: 115, | ||||
discreteDomains: 1, | discreteDomains: 1, | ||||
colors: ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'] | colors: ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001c'] | ||||
@@ -1,33 +1,31 @@ | |||||
import BaseChart from './BaseChart'; | import BaseChart from './BaseChart'; | ||||
import { makeSVGGroup, makeHeatSquare, makeText } from '../utils/draw'; | import { makeSVGGroup, makeHeatSquare, makeText } from '../utils/draw'; | ||||
import { addDays, getDdMmYyyy, getWeeksBetween } from '../utils/date-utils'; | |||||
import { addDays, getDdMmYyyy, getWeeksBetween, getMonthName, | |||||
NO_OF_MILLIS, NO_OF_YEAR_MONTHS, NO_OF_DAYS_IN_WEEK } from '../utils/date-utils'; | |||||
import { calcDistribution, getMaxCheckpoint } from '../utils/intervals'; | import { calcDistribution, getMaxCheckpoint } from '../utils/intervals'; | ||||
import { HEATMAP_DISTRIBUTION_SIZE } from '../utils/constants'; | |||||
import { HEATMAP_DISTRIBUTION_SIZE, HEATMAP_SQUARE_SIZE, | |||||
HEATMAP_GUTTER_SIZE } from '../utils/constants'; | |||||
const COL_SIZE = HEATMAP_SQUARE_SIZE + HEATMAP_GUTTER_SIZE; | |||||
const EXTRA_COLS = 3; | |||||
export default class Heatmap extends BaseChart { | export default class Heatmap extends BaseChart { | ||||
constructor(parent, options) { | constructor(parent, options) { | ||||
super(parent, options); | super(parent, options); | ||||
this.type = 'heatmap'; | this.type = 'heatmap'; | ||||
this.data = options.data || {}; | |||||
this.dataPoints = options.data.dataPoints || {}; | |||||
this.discreteDomains = options.discreteDomains === 0 ? 0 : 1; | this.discreteDomains = options.discreteDomains === 0 ? 0 : 1; | ||||
this.countLabel = options.countLabel || ''; | this.countLabel = options.countLabel || ''; | ||||
let today = new Date(); | |||||
this.start = options.start || addDays(today, 365); | |||||
this.translateX = 0; | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
setMargins() { | |||||
super.setMargins(); | |||||
this.leftMargin = 10; | |||||
this.translateY = 10; | |||||
} | |||||
configure(args) { | configure(args) { | ||||
super.configure(args); | super.configure(args); | ||||
this.start = args.data.start; | |||||
this.today = new Date(); | this.today = new Date(); | ||||
if(!this.start) { | if(!this.start) { | ||||
@@ -36,20 +34,26 @@ export default class Heatmap extends BaseChart { | |||||
} | } | ||||
this.firstWeekStart = new Date(this.start.toDateString()); | this.firstWeekStart = new Date(this.start.toDateString()); | ||||
this.lastWeekStart = new Date(this.today.toDateString()); | this.lastWeekStart = new Date(this.today.toDateString()); | ||||
if(this.firstWeekStart.getDay() !== 7) { | |||||
if(this.firstWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.firstWeekStart, (-1) * this.firstWeekStart.getDay()); | addDays(this.firstWeekStart, (-1) * this.firstWeekStart.getDay()); | ||||
} | } | ||||
if(this.lastWeekStart.getDay() !== 7) { | |||||
if(this.lastWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.lastWeekStart, (-1) * this.lastWeekStart.getDay()); | addDays(this.lastWeekStart, (-1) * this.lastWeekStart.getDay()); | ||||
} | } | ||||
this.no_of_cols = getWeeksBetween(this.firstWeekStart + '', this.lastWeekStart + '') + 1; | this.no_of_cols = getWeeksBetween(this.firstWeekStart + '', this.lastWeekStart + '') + 1; | ||||
} | } | ||||
setMargins() { | |||||
super.setMargins(); | |||||
this.leftMargin = HEATMAP_SQUARE_SIZE; | |||||
this.translateY = HEATMAP_SQUARE_SIZE; | |||||
} | |||||
calcWidth() { | calcWidth() { | ||||
this.baseWidth = (this.no_of_cols + 3) * 12 ; | |||||
this.baseWidth = (this.no_of_cols) * COL_SIZE; | |||||
if(this.discreteDomains) { | if(this.discreteDomains) { | ||||
this.baseWidth += (12 * 12); | |||||
this.baseWidth += (COL_SIZE * NO_OF_YEAR_MONTHS); | |||||
} | } | ||||
} | } | ||||
@@ -71,13 +75,8 @@ export default class Heatmap extends BaseChart { | |||||
} | } | ||||
calc() { | calc() { | ||||
let dataValues = Object.keys(this.data).map(key => this.data[key]); | |||||
let dataValues = Object.keys(this.dataPoints).map(key => this.dataPoints[key]); | |||||
this.distribution = calcDistribution(dataValues, HEATMAP_DISTRIBUTION_SIZE); | this.distribution = calcDistribution(dataValues, HEATMAP_DISTRIBUTION_SIZE); | ||||
this.monthNames = ["January", "February", "March", "April", "May", "June", | |||||
"July", "August", "September", "October", "November", "December" | |||||
]; | |||||
} | } | ||||
render() { | render() { | ||||
@@ -94,9 +93,9 @@ export default class Heatmap extends BaseChart { | |||||
this.currentMonth = currentWeekSunday.getMonth(); | this.currentMonth = currentWeekSunday.getMonth(); | ||||
this.months = [this.currentMonth + '']; | this.months = [this.currentMonth + '']; | ||||
this.monthWeeks = {}, this.monthStartPoints = []; | |||||
this.monthWeeks = {}, | |||||
this.monthStartPoints = []; | |||||
this.monthWeeks[this.currentMonth] = 0; | this.monthWeeks[this.currentMonth] = 0; | ||||
this.monthStartPoints.push(13); | |||||
for(var i = 0; i < no_of_weeks; i++) { | for(var i = 0; i < no_of_weeks; i++) { | ||||
let dataGroup, monthChange = 0; | let dataGroup, monthChange = 0; | ||||
@@ -107,19 +106,16 @@ export default class Heatmap extends BaseChart { | |||||
this.weekCol += 1 + parseInt(this.discreteDomains && monthChange); | this.weekCol += 1 + parseInt(this.discreteDomains && monthChange); | ||||
this.monthWeeks[this.currentMonth]++; | this.monthWeeks[this.currentMonth]++; | ||||
if(monthChange) { | if(monthChange) { | ||||
this.currentMonth = (this.currentMonth + 1) % 12; | |||||
this.currentMonth = (this.currentMonth + 1) % NO_OF_YEAR_MONTHS; | |||||
this.months.push(this.currentMonth + ''); | this.months.push(this.currentMonth + ''); | ||||
this.monthWeeks[this.currentMonth] = 1; | this.monthWeeks[this.currentMonth] = 1; | ||||
} | } | ||||
addDays(currentWeekSunday, 7); | |||||
addDays(currentWeekSunday, NO_OF_DAYS_IN_WEEK); | |||||
} | } | ||||
this.render_month_labels(); | this.render_month_labels(); | ||||
} | } | ||||
get_week_squares_group(currentDate, index) { | get_week_squares_group(currentDate, index) { | ||||
const noOfWeekdays = 7; | |||||
const squareSide = 10; | |||||
const cellPadding = 2; | |||||
const step = 1; | const step = 1; | ||||
const todayTime = this.today.getTime(); | const todayTime = this.today.getTime(); | ||||
@@ -128,26 +124,26 @@ export default class Heatmap extends BaseChart { | |||||
let dataGroup = makeSVGGroup(this.dataGroups, 'data-group'); | let dataGroup = makeSVGGroup(this.dataGroups, 'data-group'); | ||||
for(var y = 0, i = 0; i < noOfWeekdays; i += step, y += (squareSide + cellPadding)) { | |||||
for(var y = 0, i = 0; i < NO_OF_DAYS_IN_WEEK; i += step, y += COL_SIZE) { | |||||
let dataValue = 0; | let dataValue = 0; | ||||
let colorIndex = 0; | let colorIndex = 0; | ||||
let currentTimestamp = currentDate.getTime()/1000; | |||||
let currentTimestamp = currentDate.getTime()/NO_OF_MILLIS; | |||||
let timestamp = Math.floor(currentTimestamp - (currentTimestamp % 86400)).toFixed(1); | let timestamp = Math.floor(currentTimestamp - (currentTimestamp % 86400)).toFixed(1); | ||||
if(this.data[timestamp]) { | |||||
dataValue = this.data[timestamp]; | |||||
if(this.dataPoints[timestamp]) { | |||||
dataValue = this.dataPoints[timestamp]; | |||||
} | } | ||||
if(this.data[Math.round(timestamp)]) { | |||||
dataValue = this.data[Math.round(timestamp)]; | |||||
if(this.dataPoints[Math.round(timestamp)]) { | |||||
dataValue = this.dataPoints[Math.round(timestamp)]; | |||||
} | } | ||||
if(dataValue) { | if(dataValue) { | ||||
colorIndex = getMaxCheckpoint(dataValue, this.distribution); | colorIndex = getMaxCheckpoint(dataValue, this.distribution); | ||||
} | } | ||||
let x = 13 + (index + weekColChange) * 12; | |||||
let x = (index + weekColChange) * COL_SIZE; | |||||
let dataAttr = { | let dataAttr = { | ||||
'data-date': getDdMmYyyy(currentDate), | 'data-date': getDdMmYyyy(currentDate), | ||||
@@ -155,7 +151,7 @@ export default class Heatmap extends BaseChart { | |||||
'data-day': currentDate.getDay() | 'data-day': currentDate.getDay() | ||||
}; | }; | ||||
let heatSquare = makeHeatSquare('day', x, y, squareSide, | |||||
let heatSquare = makeHeatSquare('day', x, y, HEATMAP_SQUARE_SIZE, | |||||
this.colors[colorIndex], dataAttr); | this.colors[colorIndex], dataAttr); | ||||
dataGroup.appendChild(heatSquare); | dataGroup.appendChild(heatSquare); | ||||
@@ -171,7 +167,7 @@ export default class Heatmap extends BaseChart { | |||||
weekColChange = 1; | weekColChange = 1; | ||||
} | } | ||||
this.monthStartPoints.push(13 + (index + weekColChange) * 12); | |||||
this.monthStartPoints.push((index + weekColChange) * COL_SIZE); | |||||
} | } | ||||
currentDate = nextDate; | currentDate = nextDate; | ||||
} | } | ||||
@@ -200,8 +196,8 @@ export default class Heatmap extends BaseChart { | |||||
this.monthStartPoints.pop(); | this.monthStartPoints.pop(); | ||||
this.monthStartPoints.map((start, i) => { | this.monthStartPoints.map((start, i) => { | ||||
let month_name = this.monthNames[this.months[i]].substring(0, 3); | |||||
let text = makeText('y-value-text', start+12, 10, month_name); | |||||
let month_name = getMonthName(this.months[i], true); | |||||
let text = makeText('y-value-text', start + COL_SIZE, HEATMAP_SQUARE_SIZE, month_name); | |||||
this.domainLabelGroup.appendChild(text); | this.domainLabelGroup.appendChild(text); | ||||
}); | }); | ||||
} | } | ||||
@@ -214,7 +210,7 @@ export default class Heatmap extends BaseChart { | |||||
let count = e.target.getAttribute('data-value'); | let count = e.target.getAttribute('data-value'); | ||||
let dateParts = e.target.getAttribute('data-date').split('-'); | let dateParts = e.target.getAttribute('data-date').split('-'); | ||||
let month = this.monthNames[parseInt(dateParts[1])-1].substring(0, 3); | |||||
let month = getMonthName(parseInt(dateParts[1])-1, true); | |||||
let gOff = this.chartWrapper.getBoundingClientRect(), pOff = e.target.getBoundingClientRect(); | let gOff = this.chartWrapper.getBoundingClientRect(), pOff = e.target.getBoundingClientRect(); | ||||
@@ -44,6 +44,9 @@ export const FULL_ANGLE = 360; | |||||
// More colors are difficult to parse visually | // More colors are difficult to parse visually | ||||
export const HEATMAP_DISTRIBUTION_SIZE = 5; | export const HEATMAP_DISTRIBUTION_SIZE = 5; | ||||
export const HEATMAP_SQUARE_SIZE = 10; | |||||
export const HEATMAP_GUTTER_SIZE = 2; | |||||
const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | ||||
const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | ||||
'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | 'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | ||||
@@ -1,5 +1,12 @@ | |||||
// Playing around with dates | // Playing around with dates | ||||
export const NO_OF_YEAR_MONTHS = 12; | |||||
export const NO_OF_DAYS_IN_WEEK = 7; | |||||
export const NO_OF_MILLIS = 1000; | |||||
export const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | |||||
"July", "August", "September", "October", "November", "December"]; | |||||
// https://stackoverflow.com/a/11252167/6495043 | // https://stackoverflow.com/a/11252167/6495043 | ||||
function treatAsUtc(dateStr) { | function treatAsUtc(dateStr) { | ||||
let result = new Date(dateStr); | let result = new Date(dateStr); | ||||
@@ -31,9 +38,7 @@ export function addDays(date, numberOfDays) { | |||||
date.setDate(date.getDate() + numberOfDays); | date.setDate(date.getDate() + numberOfDays); | ||||
} | } | ||||
export function getMonthName(i) { | |||||
let monthNames = ["January", "February", "March", "April", "May", "June", | |||||
"July", "August", "September", "October", "November", "December" | |||||
]; | |||||
return monthNames[i]; | |||||
export function getMonthName(i, short=false) { | |||||
let monthName = MONTH_NAMES[i]; | |||||
return short ? monthName.slice(0, 3) : monthName; | |||||
} | } |