Skip to content

Commit e981a9c

Browse files
committed
Add heatmap chart for interval
1 parent 1b74a67 commit e981a9c

File tree

8 files changed

+240
-13
lines changed

8 files changed

+240
-13
lines changed

src/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@
2525
<a id="settings">Settings</a>
2626
</div>
2727
<div id="chart"></div>
28+
<div id="timeChart"></div>
2829
<div id="resultTable" class="list-of-site"></div>
29-
<div id="total" class="inline-flex"></div>
30+
<div id="total"></div>
3031
<div id="byDays" class="calendar-block"></div>
3132

3233
<svg class="height-0">

src/scripts/activity.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,18 @@ class Activity {
9999
}
100100

101101
setCurrentActiveTab(domain) {
102+
this.closeIntervalForCurrentTab();
102103
currentTab = domain;
103104
}
104105

105106
clearCurrentActiveTab() {
107+
this.closeIntervalForCurrentTab();
106108
currentTab = '';
107109
}
110+
111+
closeIntervalForCurrentTab(){
112+
var tabUrl = this.getTab(currentTab);
113+
if (tabUrl !== undefined)
114+
tabUrl.closeInterval();
115+
}
108116
};

src/scripts/background.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ function backgroundCheck() {
4848
}
4949
}
5050
}
51+
} else {
52+
activity.closeIntervalForCurrentTab();
5153
}
5254
});
5355
}

src/scripts/chart/chart-core.js

Lines changed: 151 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ function donutChart() {
226226
}
227227

228228
function barChart(data) {
229-
var margin = { top: 5, right: 5, bottom: 25, left: 5 },
230-
width = 485,
229+
var margin = { top: 25, right: 5, bottom: 25, left: 5 },
230+
width = 555,
231231
height = 160;
232232

233233
// set the ranges
@@ -282,4 +282,153 @@ function barChart(data) {
282282

283283
if (data.length > 9)
284284
document.querySelectorAll('#barChart g.tick ').forEach(element => { element.remove() });
285+
}
286+
287+
function drawIntervalChart(data) {
288+
data.forEach(function (item){
289+
var hFrom = getHourFrom(item.interval);
290+
var hTo = getHourTo(item.interval);
291+
if (hFrom != hTo){
292+
var sourceTimeFrom = item.interval.split('-')[0].split(':');
293+
var sourceTimeTo = item.interval.split('-')[1].split(':');
294+
var timeTo = sourceTimeFrom[0] + ":" + 59 + ":" + 59;
295+
var timeFrom = sourceTimeTo[0] + ":" + 00 + ":" + 00;
296+
data.push({"domain":item.domain, "interval":item.interval.split('-')[0] + "-" + timeTo});
297+
data.push({"domain":item.domain, "interval":timeFrom + "-" + item.interval.split('-')[1]});
298+
}
299+
});
300+
301+
var margin = { top: 5, right: 10, bottom: 20, left: 20 },
302+
width = 580 - margin.left - margin.right,
303+
height = 410 - margin.top - margin.bottom;
304+
305+
//linear 24 hour scale
306+
var y = d3.scaleLinear()
307+
.domain([0, 60])
308+
.range([height, 0]);
309+
310+
//vertical axis
311+
var yAxis = d3.axisLeft()
312+
.ticks(10)
313+
.scale(y);
314+
315+
var x = d3.scaleLinear()
316+
.domain([0, 24])
317+
.range([0, width]);
318+
319+
//vertical axis
320+
var xAxis = d3.axisBottom()
321+
.ticks(24)
322+
.scale(x)
323+
324+
var tickDistance = 4.38;
325+
326+
var tooltip = d3.select("#timeChart")
327+
.append("div")
328+
.style("opacity", 0)
329+
.style("position", "absolute")
330+
.attr("class", "tooltip")
331+
.style("background-color", "white")
332+
.style("border", "solid")
333+
.style("border-width", "1px")
334+
.style("border-radius", "5px")
335+
.style("padding", "5px")
336+
337+
// Three function that change the tooltip when user hover / move / leave a cell
338+
var mouseover = function (d) {
339+
tooltip
340+
.style("opacity", 1)
341+
d3.select(this)
342+
.style("stroke", "black")
343+
.style("stroke-width", "0.5px")
344+
.style("opacity", 1)
345+
}
346+
var mousemove = function (d) {
347+
tooltip
348+
.html(d.domain + "<br>" + d.interval)
349+
.style("left", (d3.mouse(this)[0]) + 10 + "px")
350+
.style("top", (d3.mouse(this)[1]) + 275 + "px")
351+
}
352+
var mouseleave = function (d) {
353+
tooltip
354+
.style("opacity", 0)
355+
d3.select(this)
356+
.style("stroke", "none")
357+
.style("opacity", 0.8)
358+
}
359+
360+
//create the svg
361+
var svg = d3.select("#timeChart").append("svg")
362+
.attr("width", width + margin.left + margin.right)
363+
.attr("height", height + margin.top + margin.bottom)
364+
.append("g")
365+
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
366+
367+
//draw the axis.
368+
svg.append("g")
369+
.attr("class", "x axis")
370+
.attr("transform", "translate(0," + height + ")")
371+
.attr("class", "label")
372+
.call(xAxis)
373+
.append("text")
374+
.text("Value");
375+
376+
// Add a y-axis with label.
377+
svg.append("g")
378+
.attr("class", "y axis")
379+
.call(yAxis)
380+
.append("text")
381+
.attr("class", "label")
382+
.attr("y", 6)
383+
.attr("dy", ".71em")
384+
.attr("text-anchor", "end")
385+
.attr("transform", "rotate(-90)")
386+
.text("Value");
387+
388+
//draw the bars, offset y and bar height based on data
389+
svg.selectAll(".bar")
390+
.data(data)
391+
.enter()
392+
.append("rect")
393+
.style("fill", "lightgreen")
394+
.style("stroke", "#f1f1f1")
395+
.style("stroke-width", "1")
396+
.attr("class", "bar")
397+
.attr("x", function (d) {
398+
return x(getHourFrom(d.interval));
399+
})
400+
.attr("width", 19)
401+
.attr("y", function (d) {
402+
return y(getMinutesTo(d.interval));
403+
})
404+
.attr("height", function (d) {
405+
var offset = getMinutesTo(d.interval) - getMinutesFrom(d.interval);
406+
// if (offset == 0)
407+
// return 2;
408+
// else
409+
return offset * tickDistance;
410+
})
411+
.on("mouseover", mouseover)
412+
.on("mousemove", mousemove)
413+
.on("mouseleave", mouseleave);
414+
}
415+
416+
function getHourFrom(interval) {
417+
var time = interval.split('-')[0];
418+
return time.split(':')[0];
419+
}
420+
421+
function getHourTo(interval) {
422+
var time = interval.split('-')[1];
423+
return time.split(':')[0];
424+
}
425+
426+
function getMinutesFrom(interval) {
427+
var time = interval.split('-')[0];
428+
return time.split(':')[1];
429+
}
430+
431+
function getMinutesTo(interval) {
432+
var time = interval.split('-')[1];
433+
return time.split(':')[1];
285434
}

src/scripts/tab.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,41 @@ class Tab {
4141
}
4242
else {
4343
day['counter'] += 1;
44+
this.addInterval(day);
4445
}
4546
}
4647

4748
addNewDay(today) {
49+
var date = new Date();
50+
var stringDate = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
4851
this.days.push(
4952
{
5053
'date': today,
5154
'summary': 1,
52-
'counter': 1
55+
'counter': 1,
56+
'time': ["" + stringDate + '-'+ stringDate + ""]
5357
}
5458
);
5559
}
60+
61+
addInterval(day){
62+
var date = new Date();
63+
var stringDate = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
64+
if (day.time == undefined)
65+
day.time = [stringDate + '-'+ stringDate];
66+
else {
67+
day.time.push(stringDate + '-' + stringDate);
68+
}
69+
}
70+
71+
closeInterval(){
72+
var date = new Date();
73+
var stringDate = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
74+
var today = new Date().toLocaleDateString("en-US");
75+
var day = this.days.find(x => x.date == today);
76+
if (day != undefined && day.time !== undefined){
77+
var interval = day.time.pop();
78+
day.time.push(interval.split('-')[0] + '-' + stringDate);
79+
}
80+
}
5681
};

src/scripts/ui.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ class UI {
3333
clearUI() {
3434
document.getElementById('resultTable').innerHTML = null;
3535
document.getElementById('chart').innerHTML = null;
36+
document.getElementById('timeChart').innerHTML = null;
3637
document.getElementById('total').innerHTML = null;
3738
document.getElementById('byDays').innerHTML = null;
3839
}
3940

4041
createTotalBlock(totalTime) {
4142
var totalElement = document.getElementById('total');
4243

43-
var spanTitle = this.createElement('span', ['span-total'], 'Total');
44+
var spanTitle = this.createElement('span', ['title'], 'Total: ');
4445
var spanTime = this.createElement('span', ['span-time'], convertSummaryTimeToString(totalTime));
4546

4647
totalElement = this.appendChild(totalElement, [spanTitle, spanTime]);
@@ -78,7 +79,7 @@ class UI {
7879

7980
drawChart(tabs) {
8081
var donut = donutChart()
81-
.width(480)
82+
.width(550)
8283
.height(230)
8384
.cornerRadius(5) // sets how rounded the corners are on each slice
8485
.padAngle(0.020) // effectively dictates the gap between slices
@@ -92,6 +93,10 @@ class UI {
9293
ui.addHrAfterChart();
9394
}
9495

96+
drawTimeChart(tabs) {
97+
//drawIntervalChart(tabs);
98+
}
99+
95100
drawBarChart(days) {
96101
d3.select('#barChart').datum(days);
97102
barChart(days);

src/scripts/webact.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,25 @@ function getTabsFromStorage(tabs) {
142142
ui.addHrAfterTableOfSite();
143143
ui.createTotalBlock(totalTime);
144144
ui.drawChart(tabsForChart);
145+
if (currentTypeOfList === TypeListEnum.ToDay)
146+
ui.drawTimeChart(getTabsForTimeChart(targetTabs));
145147
ui.setActiveTooltipe(currentTab);
146148
}
147149

150+
function getTabsForTimeChart(targetTabs){
151+
var resultArr = [];
152+
targetTabs.forEach(function (name){
153+
var current = name.days.forEach(function (item){
154+
if (item.date == new Date().toLocaleDateString("en-US")){
155+
item.time.forEach(function (time){
156+
resultArr.push({'domain':name.url, 'interval':time});
157+
})
158+
}
159+
});
160+
});
161+
return resultArr;
162+
}
163+
148164
function getTabsForExpander() {
149165
storage.loadTabs(STORAGE_TABS, getTabsFromStorageForExpander);
150166
}

0 commit comments

Comments
 (0)