@@ -268,10 +268,6 @@ const DEFAULT_COLORS = { | |||||
heatmap: HEATMAP_COLORS | heatmap: HEATMAP_COLORS | ||||
}; | }; | ||||
/** | |||||
* Returns the value of a number upto 2 decimal places. | |||||
* @param {Number} d Any number | |||||
*/ | |||||
function floatTwo(d) { | function floatTwo(d) { | ||||
return parseFloat(d.toFixed(2)); | return parseFloat(d.toFixed(2)); | ||||
} | } | ||||
@@ -1280,8 +1276,8 @@ class BaseChart { | |||||
bindTooltip() {} | bindTooltip() {} | ||||
draw(onlyWidthChange=false, init=false) { | draw(onlyWidthChange=false, init=false) { | ||||
this.updateWidth(); | |||||
this.calc(onlyWidthChange); | this.calc(onlyWidthChange); | ||||
this.updateWidth(); | |||||
this.makeChartArea(); | this.makeChartArea(); | ||||
this.setupComponents(); | this.setupComponents(); | ||||
@@ -2143,7 +2139,9 @@ class PieChart extends AggregationChart { | |||||
const NO_OF_YEAR_MONTHS = 12; | const NO_OF_YEAR_MONTHS = 12; | ||||
const NO_OF_DAYS_IN_WEEK = 7; | const NO_OF_DAYS_IN_WEEK = 7; | ||||
const NO_OF_MILLIS = 1000; | const NO_OF_MILLIS = 1000; | ||||
const SEC_IN_DAY = 86400; | |||||
const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | ||||
"July", "August", "September", "October", "November", "December"]; | "July", "August", "September", "October", "November", "December"]; | ||||
@@ -2151,8 +2149,8 @@ const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | |||||
// https://stackoverflow.com/a/11252167/6495043 | // https://stackoverflow.com/a/11252167/6495043 | ||||
function treatAsUtc(dateStr) { | |||||
let result = new Date(dateStr); | |||||
function treatAsUtc(date) { | |||||
let result = new Date(date); | |||||
result.setMinutes(result.getMinutes() - result.getTimezoneOffset()); | result.setMinutes(result.getMinutes() - result.getTimezoneOffset()); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -2167,20 +2165,21 @@ function getDdMmYyyy(date) { | |||||
].join('-'); | ].join('-'); | ||||
} | } | ||||
function clone(date) { | |||||
return new Date(date.getTime()); | |||||
} | |||||
function getWeeksBetween(startDateStr, endDateStr) { | |||||
return Math.ceil(getDaysBetween(startDateStr, endDateStr) / 7); | |||||
} | |||||
function getDaysBetween(startDateStr, endDateStr) { | |||||
let millisecondsPerDay = 24 * 60 * 60 * 1000; | |||||
return (treatAsUtc(endDateStr) - treatAsUtc(startDateStr)) / millisecondsPerDay; | |||||
function getWeeksBetween(startDate, endDate) { | |||||
return Math.ceil(getDaysBetween(startDate, endDate) / NO_OF_DAYS_IN_WEEK); | |||||
} | } | ||||
// mutates | |||||
function addDays(date, numberOfDays) { | |||||
date.setDate(date.getDate() + numberOfDays); | |||||
function getDaysBetween(startDate, endDate) { | |||||
let millisecondsPerDay = SEC_IN_DAY * NO_OF_MILLIS; | |||||
return (treatAsUtc(endDate) - treatAsUtc(startDate)) / millisecondsPerDay; | |||||
} | } | ||||
function getMonthName(i, short=false) { | function getMonthName(i, short=false) { | ||||
@@ -2188,6 +2187,20 @@ function getMonthName(i, short=false) { | |||||
return short ? monthName.slice(0, 3) : monthName; | return short ? monthName.slice(0, 3) : monthName; | ||||
} | } | ||||
// mutates | |||||
function setDayToSunday(date) { | |||||
const day = date.getDay(); | |||||
if(day !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(date, (-1) * day); | |||||
} | |||||
return date; | |||||
} | |||||
// mutates | |||||
function addDays(date, numberOfDays) { | |||||
date.setDate(date.getDate() + numberOfDays); | |||||
} | |||||
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 | ||||
@@ -2413,30 +2426,8 @@ class Heatmap extends BaseChart { | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
configure(args) { | |||||
super.configure(args); | |||||
this.start = args.data.start; | |||||
this.today = new Date(); | |||||
if(!this.start) { | |||||
this.start = new Date(); | |||||
this.start.setFullYear( this.start.getFullYear() - 1 ); | |||||
} | |||||
this.firstWeekStart = new Date(this.start.toDateString()); | |||||
this.lastWeekStart = new Date(this.today.toDateString()); | |||||
if(this.firstWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.firstWeekStart, (-1) * this.firstWeekStart.getDay()); | |||||
} | |||||
if(this.lastWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.lastWeekStart, (-1) * this.lastWeekStart.getDay()); | |||||
} | |||||
this.no_of_cols = getWeeksBetween(this.firstWeekStart + '', this.lastWeekStart + '') + 1; | |||||
} | |||||
updateWidth() { | updateWidth() { | ||||
this.baseWidth = (this.no_of_cols + 99) * COL_SIZE; | |||||
this.baseWidth = (this.state.noOfWeeks + 99) * COL_SIZE; | |||||
if(this.discreteDomains) { | if(this.discreteDomains) { | ||||
this.baseWidth += (COL_SIZE * NO_OF_YEAR_MONTHS); | this.baseWidth += (COL_SIZE * NO_OF_YEAR_MONTHS); | ||||
@@ -2448,32 +2439,54 @@ class Heatmap extends BaseChart { | |||||
this.domainLabelGroup = makeSVGGroup(this.drawArea, | this.domainLabelGroup = makeSVGGroup(this.drawArea, | ||||
'domain-label-group chart-label'); | 'domain-label-group chart-label'); | ||||
this.dataGroups = makeSVGGroup(this.drawArea, | |||||
this.colGroups = makeSVGGroup(this.drawArea, | |||||
'data-groups', | 'data-groups', | ||||
`translate(0, 20)` | `translate(0, 20)` | ||||
); | ); | ||||
} | } | ||||
prepareData(data=this.data) { | |||||
if(data.start && data.end && data.start > data.end) { | |||||
throw new Error('Start date cannot be greater than end date.'); | |||||
} | |||||
if(!data.start) { | |||||
data.start = new Date(); | |||||
data.start.setFullYear( data.start.getFullYear() - 1 ); | |||||
} | |||||
if(!data.end) { data.end = new Date(); } | |||||
return data; | |||||
} | |||||
calc() { | calc() { | ||||
this.distribution = calcDistribution( | |||||
let s = this.state; | |||||
s.start = this.data.start; | |||||
s.end = this.data.end; | |||||
s.firstWeekStart = setDayToSunday(clone(s.start)); | |||||
s.noOfWeeks = getWeeksBetween(s.firstWeekStart, s.end); | |||||
s.distribution = calcDistribution( | |||||
Object.values(this.dataPoints), HEATMAP_DISTRIBUTION_SIZE); | Object.values(this.dataPoints), HEATMAP_DISTRIBUTION_SIZE); | ||||
} | } | ||||
update(data=this.data) { | update(data=this.data) { | ||||
this.data = this.prepareData(data); | this.data = this.prepareData(data); | ||||
this.draw(); | this.draw(); | ||||
this.bindTooltip(); | |||||
} | } | ||||
render() { | render() { | ||||
this.renderAllWeeksAndStoreXValues(this.no_of_cols); | |||||
this.renderAllWeeksAndStoreXValues(this.state.noOfWeeks); | |||||
} | } | ||||
renderAllWeeksAndStoreXValues(no_of_weeks) { | renderAllWeeksAndStoreXValues(no_of_weeks) { | ||||
// renderAllWeeksAndStoreXValues | // renderAllWeeksAndStoreXValues | ||||
this.domainLabelGroup.textContent = ''; | this.domainLabelGroup.textContent = ''; | ||||
this.dataGroups.textContent = ''; | |||||
this.colGroups.textContent = ''; | |||||
let currentWeekSunday = new Date(this.firstWeekStart); | |||||
let currentWeekSunday = new Date(this.state.firstWeekStart); | |||||
this.weekCol = 0; | this.weekCol = 0; | ||||
this.currentMonth = currentWeekSunday.getMonth(); | this.currentMonth = currentWeekSunday.getMonth(); | ||||
@@ -2482,11 +2495,11 @@ class Heatmap extends BaseChart { | |||||
this.monthWeeks[this.currentMonth] = 0; | this.monthWeeks[this.currentMonth] = 0; | ||||
for(var i = 0; i < no_of_weeks; i++) { | for(var i = 0; i < no_of_weeks; i++) { | ||||
let dataGroup, monthChange = 0; | |||||
let colGroup, monthChange = 0; | |||||
let day = new Date(currentWeekSunday); | let day = new Date(currentWeekSunday); | ||||
[dataGroup, monthChange] = this.getWeekSquaresGroup(day, this.weekCol); | |||||
this.dataGroups.appendChild(dataGroup); | |||||
[colGroup, monthChange] = this.getWeekSquaresGroup(day, this.weekCol); | |||||
this.colGroups.appendChild(colGroup); | |||||
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) { | ||||
@@ -2501,12 +2514,15 @@ class Heatmap extends BaseChart { | |||||
getWeekSquaresGroup(currentDate, index) { | getWeekSquaresGroup(currentDate, index) { | ||||
const step = 1; | const step = 1; | ||||
const todayTime = this.today.getTime(); | |||||
let today = new Date(); | |||||
const todayTime = today.getTime(); | |||||
let monthChange = 0; | let monthChange = 0; | ||||
let weekColChange = 0; | let weekColChange = 0; | ||||
let dataGroup = makeSVGGroup(this.dataGroups, 'data-group'); | |||||
let colGroup = makeSVGGroup(this.colGroups, 'data-group'); | |||||
for(var y = 0, i = 0; i < NO_OF_DAYS_IN_WEEK; i += step, y += COL_SIZE) { | for(var y = 0, i = 0; i < NO_OF_DAYS_IN_WEEK; i += step, y += COL_SIZE) { | ||||
let dataValue = 0; | let dataValue = 0; | ||||
@@ -2524,7 +2540,7 @@ class Heatmap extends BaseChart { | |||||
} | } | ||||
if(dataValue) { | if(dataValue) { | ||||
colorIndex = getMaxCheckpoint(dataValue, this.distribution); | |||||
colorIndex = getMaxCheckpoint(dataValue, this.state.distribution); | |||||
} | } | ||||
let x = (index + weekColChange) * COL_SIZE; | let x = (index + weekColChange) * COL_SIZE; | ||||
@@ -2538,7 +2554,7 @@ class Heatmap extends BaseChart { | |||||
let heatSquare = makeHeatSquare('day', x, y, HEATMAP_SQUARE_SIZE, | let heatSquare = makeHeatSquare('day', x, y, HEATMAP_SQUARE_SIZE, | ||||
this.colors[colorIndex], dataAttr); | this.colors[colorIndex], dataAttr); | ||||
dataGroup.appendChild(heatSquare); | |||||
colGroup.appendChild(heatSquare); | |||||
let nextDate = new Date(currentDate); | let nextDate = new Date(currentDate); | ||||
addDays(nextDate, 1); | addDays(nextDate, 1); | ||||
@@ -2556,12 +2572,12 @@ class Heatmap extends BaseChart { | |||||
currentDate = nextDate; | currentDate = nextDate; | ||||
} | } | ||||
return [dataGroup, monthChange]; | |||||
return [colGroup, monthChange]; | |||||
} | } | ||||
renderMonthLabels() { | renderMonthLabels() { | ||||
// this.first_month_label = 1; | // this.first_month_label = 1; | ||||
// if (this.firstWeekStart.getDate() > 8) { | |||||
// if (this.state.firstWeekStart.getDate() > 8) { | |||||
// this.first_month_label = 0; | // this.first_month_label = 0; | ||||
// } | // } | ||||
// this.last_month_label = 1; | // this.last_month_label = 1; | ||||
@@ -2609,11 +2625,6 @@ class Heatmap extends BaseChart { | |||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
update(data) { | |||||
super.update(data); | |||||
this.bindTooltip(); | |||||
} | |||||
} | } | ||||
function dataPrep(data, type) { | function dataPrep(data, type) { | ||||
@@ -3285,7 +3296,6 @@ class AxisChart extends BaseChart { | |||||
// removeDataPoint(index = 0) {} | // removeDataPoint(index = 0) {} | ||||
} | } | ||||
// import MultiAxisChart from './charts/MultiAxisChart'; | |||||
const chartTypes = { | const chartTypes = { | ||||
// multiaxis: MultiAxisChart, | // multiaxis: MultiAxisChart, | ||||
percentage: PercentageChart, | percentage: PercentageChart, | ||||
@@ -1,4 +1,4 @@ | |||||
import { MONTH_NAMES_SHORT } from '../../../src/js/utils/date-utils'; | |||||
import { DAYS_IN_YEAR, SEC_IN_DAY, MONTH_NAMES_SHORT, clone, timestampToMidnight, timestampSec } from '../../../src/js/utils/date-utils'; | |||||
// Composite Chart | // Composite Chart | ||||
// ================================================================================ | // ================================================================================ | ||||
@@ -175,18 +175,22 @@ export const moonData = { | |||||
// ================================================================================ | // ================================================================================ | ||||
let today = new Date(); | let today = new Date(); | ||||
let start = new Date(today.getTime()); | |||||
let end = new Date(today.getTime()); | |||||
let start = clone(today); | |||||
let end = clone(today); | |||||
start.setFullYear( start.getFullYear() - 2 ); | start.setFullYear( start.getFullYear() - 2 ); | ||||
end.setFullYear( start.getFullYear() - 1 ); | |||||
end.setFullYear( end.getFullYear() - 1 ); | |||||
export let dataPoints = {}; | export let dataPoints = {}; | ||||
let current_date = new Date(); | |||||
let timestamp = current_date.getTime()/1000; | |||||
timestamp = Math.floor(timestamp - (timestamp % 86400)).toFixed(1); // convert to midnight | |||||
for (var i = 0; i< 375; i++) { | |||||
dataPoints[parseInt(timestamp)] = Math.floor(Math.random() * 5); | |||||
timestamp = Math.floor(timestamp - 86400).toFixed(1); | |||||
let startTs = timestampSec(start); | |||||
let endTs = timestampSec(end); | |||||
startTs = timestampToMidnight(startTs); | |||||
endTs = timestampToMidnight(endTs, true); | |||||
while (startTs < endTs) { | |||||
dataPoints[parseInt(startTs)] = Math.floor(Math.random() * 5); | |||||
startTs += SEC_IN_DAY; | |||||
} | } | ||||
export const heatmapData = { | export const heatmapData = { | ||||
@@ -81,14 +81,33 @@ function shuffle(array) { | |||||
var NO_OF_MILLIS = 1000; | |||||
var SEC_IN_DAY = 86400; | |||||
var MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | var MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | ||||
// https://stackoverflow.com/a/11252167/6495043 | |||||
function clone(date) { | |||||
return new Date(date.getTime()); | |||||
} | |||||
function timestampSec(date) { | |||||
return date.getTime() / NO_OF_MILLIS; | |||||
} | |||||
function timestampToMidnight(timestamp) { | |||||
var roundAhead = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | |||||
var midnightTs = Math.floor(timestamp - timestamp % SEC_IN_DAY); | |||||
if (roundAhead) { | |||||
return midnightTs + SEC_IN_DAY; | |||||
} | |||||
return midnightTs; | |||||
} | |||||
@@ -97,8 +116,9 @@ var MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", | |||||
// mutates | // mutates | ||||
// Composite Chart | |||||
// ================================================================================ | |||||
// mutates | |||||
var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850]; | var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850]; | ||||
var lineCompositeData = { | var lineCompositeData = { | ||||
@@ -209,18 +229,22 @@ var moonData = { | |||||
// ================================================================================ | // ================================================================================ | ||||
var today = new Date(); | var today = new Date(); | ||||
var start = new Date(today.getTime()); | |||||
var end = new Date(today.getTime()); | |||||
var start = clone(today); | |||||
var end = clone(today); | |||||
start.setFullYear(start.getFullYear() - 2); | start.setFullYear(start.getFullYear() - 2); | ||||
end.setFullYear(start.getFullYear() - 1); | |||||
end.setFullYear(end.getFullYear() - 1); | |||||
var dataPoints = {}; | var dataPoints = {}; | ||||
var current_date = new Date(); | |||||
var timestamp = current_date.getTime() / 1000; | |||||
timestamp = Math.floor(timestamp - timestamp % 86400).toFixed(1); // convert to midnight | |||||
for (var i = 0; i < 375; i++) { | |||||
dataPoints[parseInt(timestamp)] = Math.floor(Math.random() * 5); | |||||
timestamp = Math.floor(timestamp - 86400).toFixed(1); | |||||
var startTs = timestampSec(start); | |||||
var endTs = timestampSec(end); | |||||
startTs = timestampToMidnight(startTs); | |||||
endTs = timestampToMidnight(endTs, true); | |||||
while (startTs < endTs) { | |||||
dataPoints[parseInt(startTs)] = Math.floor(Math.random() * 5); | |||||
startTs += SEC_IN_DAY; | |||||
} | } | ||||
var heatmapData = { | var heatmapData = { | ||||
@@ -112,8 +112,8 @@ export default class BaseChart { | |||||
bindTooltip() {} | bindTooltip() {} | ||||
draw(onlyWidthChange=false, init=false) { | draw(onlyWidthChange=false, init=false) { | ||||
this.updateWidth(); | |||||
this.calc(onlyWidthChange); | this.calc(onlyWidthChange); | ||||
this.updateWidth(); | |||||
this.makeChartArea(); | this.makeChartArea(); | ||||
this.setupComponents(); | this.setupComponents(); | ||||
@@ -1,6 +1,6 @@ | |||||
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, getMonthName, clone, | |||||
import { addDays, setDayToSunday, getDdMmYyyy, getWeeksBetween, getMonthName, clone, | |||||
NO_OF_MILLIS, NO_OF_YEAR_MONTHS, NO_OF_DAYS_IN_WEEK } from '../utils/date-utils'; | 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, HEATMAP_SQUARE_SIZE, | import { HEATMAP_DISTRIBUTION_SIZE, HEATMAP_SQUARE_SIZE, | ||||
@@ -20,30 +20,8 @@ export default class Heatmap extends BaseChart { | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
configure(args) { | |||||
super.configure(args); | |||||
this.start = args.data.start; | |||||
this.today = new Date(); | |||||
if(!this.start) { | |||||
this.start = new Date(); | |||||
this.start.setFullYear( this.start.getFullYear() - 1 ); | |||||
} | |||||
this.firstWeekStart = new Date(this.start.toDateString()); | |||||
this.lastWeekStart = new Date(this.today.toDateString()); | |||||
if(this.firstWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.firstWeekStart, (-1) * this.firstWeekStart.getDay()); | |||||
} | |||||
if(this.lastWeekStart.getDay() !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(this.lastWeekStart, (-1) * this.lastWeekStart.getDay()); | |||||
} | |||||
this.no_of_cols = getWeeksBetween(this.firstWeekStart + '', this.lastWeekStart + '') + 1; | |||||
} | |||||
updateWidth() { | updateWidth() { | ||||
this.baseWidth = (this.no_of_cols + 99) * COL_SIZE; | |||||
this.baseWidth = (this.state.noOfWeeks + 99) * COL_SIZE; | |||||
if(this.discreteDomains) { | if(this.discreteDomains) { | ||||
this.baseWidth += (COL_SIZE * NO_OF_YEAR_MONTHS); | this.baseWidth += (COL_SIZE * NO_OF_YEAR_MONTHS); | ||||
@@ -55,32 +33,54 @@ export default class Heatmap extends BaseChart { | |||||
this.domainLabelGroup = makeSVGGroup(this.drawArea, | this.domainLabelGroup = makeSVGGroup(this.drawArea, | ||||
'domain-label-group chart-label'); | 'domain-label-group chart-label'); | ||||
this.dataGroups = makeSVGGroup(this.drawArea, | |||||
this.colGroups = makeSVGGroup(this.drawArea, | |||||
'data-groups', | 'data-groups', | ||||
`translate(0, 20)` | `translate(0, 20)` | ||||
); | ); | ||||
} | } | ||||
prepareData(data=this.data) { | |||||
if(data.start && data.end && data.start > data.end) { | |||||
throw new Error('Start date cannot be greater than end date.'); | |||||
} | |||||
if(!data.start) { | |||||
data.start = new Date(); | |||||
data.start.setFullYear( data.start.getFullYear() - 1 ); | |||||
} | |||||
if(!data.end) { data.end = new Date(); } | |||||
return data; | |||||
} | |||||
calc() { | calc() { | ||||
this.distribution = calcDistribution( | |||||
let s = this.state; | |||||
s.start = this.data.start; | |||||
s.end = this.data.end; | |||||
s.firstWeekStart = setDayToSunday(clone(s.start)); | |||||
s.noOfWeeks = getWeeksBetween(s.firstWeekStart, s.end); | |||||
s.distribution = calcDistribution( | |||||
Object.values(this.dataPoints), HEATMAP_DISTRIBUTION_SIZE); | Object.values(this.dataPoints), HEATMAP_DISTRIBUTION_SIZE); | ||||
} | } | ||||
update(data=this.data) { | update(data=this.data) { | ||||
this.data = this.prepareData(data); | this.data = this.prepareData(data); | ||||
this.draw(); | this.draw(); | ||||
this.bindTooltip(); | |||||
} | } | ||||
render() { | render() { | ||||
this.renderAllWeeksAndStoreXValues(this.no_of_cols); | |||||
this.renderAllWeeksAndStoreXValues(this.state.noOfWeeks); | |||||
} | } | ||||
renderAllWeeksAndStoreXValues(no_of_weeks) { | renderAllWeeksAndStoreXValues(no_of_weeks) { | ||||
// renderAllWeeksAndStoreXValues | // renderAllWeeksAndStoreXValues | ||||
this.domainLabelGroup.textContent = ''; | this.domainLabelGroup.textContent = ''; | ||||
this.dataGroups.textContent = ''; | |||||
this.colGroups.textContent = ''; | |||||
let currentWeekSunday = new Date(this.firstWeekStart); | |||||
let currentWeekSunday = new Date(this.state.firstWeekStart); | |||||
this.weekCol = 0; | this.weekCol = 0; | ||||
this.currentMonth = currentWeekSunday.getMonth(); | this.currentMonth = currentWeekSunday.getMonth(); | ||||
@@ -90,11 +90,11 @@ export default class Heatmap extends BaseChart { | |||||
this.monthWeeks[this.currentMonth] = 0; | this.monthWeeks[this.currentMonth] = 0; | ||||
for(var i = 0; i < no_of_weeks; i++) { | for(var i = 0; i < no_of_weeks; i++) { | ||||
let dataGroup, monthChange = 0; | |||||
let colGroup, monthChange = 0; | |||||
let day = new Date(currentWeekSunday); | let day = new Date(currentWeekSunday); | ||||
[dataGroup, monthChange] = this.getWeekSquaresGroup(day, this.weekCol); | |||||
this.dataGroups.appendChild(dataGroup); | |||||
[colGroup, monthChange] = this.getWeekSquaresGroup(day, this.weekCol); | |||||
this.colGroups.appendChild(colGroup); | |||||
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) { | ||||
@@ -109,12 +109,15 @@ export default class Heatmap extends BaseChart { | |||||
getWeekSquaresGroup(currentDate, index) { | getWeekSquaresGroup(currentDate, index) { | ||||
const step = 1; | const step = 1; | ||||
const todayTime = this.today.getTime(); | |||||
let today = new Date(); | |||||
const todayTime = today.getTime(); | |||||
let monthChange = 0; | let monthChange = 0; | ||||
let weekColChange = 0; | let weekColChange = 0; | ||||
let dataGroup = makeSVGGroup(this.dataGroups, 'data-group'); | |||||
let colGroup = makeSVGGroup(this.colGroups, 'data-group'); | |||||
for(var y = 0, i = 0; i < NO_OF_DAYS_IN_WEEK; i += step, y += COL_SIZE) { | for(var y = 0, i = 0; i < NO_OF_DAYS_IN_WEEK; i += step, y += COL_SIZE) { | ||||
let dataValue = 0; | let dataValue = 0; | ||||
@@ -132,7 +135,7 @@ export default class Heatmap extends BaseChart { | |||||
} | } | ||||
if(dataValue) { | if(dataValue) { | ||||
colorIndex = getMaxCheckpoint(dataValue, this.distribution); | |||||
colorIndex = getMaxCheckpoint(dataValue, this.state.distribution); | |||||
} | } | ||||
let x = (index + weekColChange) * COL_SIZE; | let x = (index + weekColChange) * COL_SIZE; | ||||
@@ -146,7 +149,7 @@ export default class Heatmap extends BaseChart { | |||||
let heatSquare = makeHeatSquare('day', x, y, HEATMAP_SQUARE_SIZE, | let heatSquare = makeHeatSquare('day', x, y, HEATMAP_SQUARE_SIZE, | ||||
this.colors[colorIndex], dataAttr); | this.colors[colorIndex], dataAttr); | ||||
dataGroup.appendChild(heatSquare); | |||||
colGroup.appendChild(heatSquare); | |||||
let nextDate = new Date(currentDate); | let nextDate = new Date(currentDate); | ||||
addDays(nextDate, 1); | addDays(nextDate, 1); | ||||
@@ -164,12 +167,12 @@ export default class Heatmap extends BaseChart { | |||||
currentDate = nextDate; | currentDate = nextDate; | ||||
} | } | ||||
return [dataGroup, monthChange]; | |||||
return [colGroup, monthChange]; | |||||
} | } | ||||
renderMonthLabels() { | renderMonthLabels() { | ||||
// this.first_month_label = 1; | // this.first_month_label = 1; | ||||
// if (this.firstWeekStart.getDate() > 8) { | |||||
// if (this.state.firstWeekStart.getDate() > 8) { | |||||
// this.first_month_label = 0; | // this.first_month_label = 0; | ||||
// } | // } | ||||
// this.last_month_label = 1; | // this.last_month_label = 1; | ||||
@@ -217,9 +220,4 @@ export default class Heatmap extends BaseChart { | |||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
update(data) { | |||||
super.update(data); | |||||
this.bindTooltip(); | |||||
} | |||||
} | } |
@@ -2,7 +2,9 @@ | |||||
export const NO_OF_YEAR_MONTHS = 12; | export const NO_OF_YEAR_MONTHS = 12; | ||||
export const NO_OF_DAYS_IN_WEEK = 7; | export const NO_OF_DAYS_IN_WEEK = 7; | ||||
export const DAYS_IN_YEAR = 375; | |||||
export const NO_OF_MILLIS = 1000; | export const NO_OF_MILLIS = 1000; | ||||
export const SEC_IN_DAY = 86400; | |||||
export const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | export const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", | ||||
"July", "August", "September", "October", "November", "December"]; | "July", "August", "September", "October", "November", "December"]; | ||||
@@ -10,8 +12,8 @@ export const MONTH_NAMES = ["January", "February", "March", "April", "May", "Jun | |||||
export const MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | export const MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | ||||
// https://stackoverflow.com/a/11252167/6495043 | // https://stackoverflow.com/a/11252167/6495043 | ||||
function treatAsUtc(dateStr) { | |||||
let result = new Date(dateStr); | |||||
function treatAsUtc(date) { | |||||
let result = new Date(date); | |||||
result.setMinutes(result.getMinutes() - result.getTimezoneOffset()); | result.setMinutes(result.getMinutes() - result.getTimezoneOffset()); | ||||
return result; | return result; | ||||
} | } | ||||
@@ -30,21 +32,42 @@ export function clone(date) { | |||||
return new Date(date.getTime()); | return new Date(date.getTime()); | ||||
} | } | ||||
export function getWeeksBetween(startDateStr, endDateStr) { | |||||
return Math.ceil(getDaysBetween(startDateStr, endDateStr) / 7); | |||||
export function timestampSec(date) { | |||||
return date.getTime()/NO_OF_MILLIS; | |||||
} | } | ||||
export function getDaysBetween(startDateStr, endDateStr) { | |||||
let millisecondsPerDay = 24 * 60 * 60 * 1000; | |||||
return (treatAsUtc(endDateStr) - treatAsUtc(startDateStr)) / millisecondsPerDay; | |||||
export function timestampToMidnight(timestamp, roundAhead = false) { | |||||
let midnightTs = Math.floor(timestamp - (timestamp % SEC_IN_DAY)); | |||||
if(roundAhead) { | |||||
return midnightTs + SEC_IN_DAY; | |||||
} | |||||
return midnightTs; | |||||
} | } | ||||
// mutates | |||||
export function addDays(date, numberOfDays) { | |||||
date.setDate(date.getDate() + numberOfDays); | |||||
export function getWeeksBetween(startDate, endDate) { | |||||
return Math.ceil(getDaysBetween(startDate, endDate) / NO_OF_DAYS_IN_WEEK); | |||||
} | |||||
export function getDaysBetween(startDate, endDate) { | |||||
let millisecondsPerDay = SEC_IN_DAY * NO_OF_MILLIS; | |||||
return (treatAsUtc(endDate) - treatAsUtc(startDate)) / millisecondsPerDay; | |||||
} | } | ||||
export function getMonthName(i, short=false) { | export function getMonthName(i, short=false) { | ||||
let monthName = MONTH_NAMES[i]; | let monthName = MONTH_NAMES[i]; | ||||
return short ? monthName.slice(0, 3) : monthName; | return short ? monthName.slice(0, 3) : monthName; | ||||
} | } | ||||
// mutates | |||||
export function setDayToSunday(date) { | |||||
const day = date.getDay(); | |||||
if(day !== NO_OF_DAYS_IN_WEEK) { | |||||
addDays(date, (-1) * day); | |||||
} | |||||
return date; | |||||
} | |||||
// mutates | |||||
export function addDays(date, numberOfDays) { | |||||
date.setDate(date.getDate() + numberOfDays); | |||||
} |