Skip to content

Commit 41f7d3c

Browse files
committed
Add "cursors" in heatmap og hover and click (logging of events included)
1 parent 88cfdea commit 41f7d3c

File tree

1 file changed

+110
-108
lines changed

1 file changed

+110
-108
lines changed

src/app/component/circular-heatmap/circular-heatmap.component.ts

Lines changed: 110 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -433,75 +433,39 @@ export class CircularHeatmapComponent implements OnInit {
433433
svg
434434
.selectAll('path')
435435
.on('click', function (d) {
436-
console.log(d);
437-
try {
438-
curr = d.explicitOriginalTarget.__data__;
439-
} catch {
440-
curr = d.srcElement.__data__;
441-
}
442-
var index = 0;
443-
var cnt = 0;
444-
for (var i = 0; i < _self.ALL_CARD_DATA.length; i++) {
445-
if (
446-
_self.ALL_CARD_DATA[i]['SubDimension'] === curr.SubDimension &&
447-
_self.ALL_CARD_DATA[i]['Level'] === curr.Level
448-
) {
449-
index = i;
450-
break;
451-
}
436+
_self.console_log_event('click', d);
437+
_self.setSectorCursor(svg, '#hover', '');
438+
439+
var clickedId = d.currentTarget.id;
440+
var index = parseInt(clickedId.replace('index-', ''));
441+
curr = _self.ALL_CARD_DATA[index];
442+
console.log('index', curr['Activity']);
443+
444+
if (curr['Done%'] == -1) {
445+
_self.showActivityCard = false;
446+
_self.setSectorCursor(svg, '#selected', '');
447+
} else {
448+
_self.showActivityCard = true;
449+
_self.currentDimension = curr.Dimension;
450+
_self.cardSubheader = curr.Level;
451+
_self.activityData = curr.Activity;
452+
_self.cardHeader = curr.SubDimension;
453+
_self.setSectorCursor(svg, '#selected', clickedId);
452454
}
453-
console.log('index', _self.ALL_CARD_DATA[index]['Activity']);
454-
_self.currentDimension = curr.Dimension;
455-
_self.cardSubheader = curr.Level;
456-
_self.activityData = curr.Activity;
457-
_self.cardHeader = curr.SubDimension;
458-
_self.showActivityCard = true;
459455
})
460456
.on('mouseover', function (d) {
461-
//console.log(d.toElement.__data__.Name)
462-
try {
463-
curr = d.explicitOriginalTarget.__data__;
464-
} catch {
465-
curr = d.toElement.__data__;
466-
}
467-
// increase the segment height of the one being hovered as well as all others of the same date
468-
// while decreasing the height of all others accordingly
469-
if (curr['Done%'] != -1) {
470-
d3.selectAll(
471-
'#segment-' +
472-
curr.SubDimension.replace(/ /g, '-') +
473-
'-' +
474-
curr.Level.replaceAll(' ', '-')
475-
).attr('fill', 'yellow');
457+
_self.console_log_event('mouseover', d);
458+
curr = d.currentTarget.__data__;
459+
460+
if (curr && curr['Done%'] != -1) {
461+
var clickedId = d.srcElement.id;
462+
_self.setSectorCursor(svg, '#hover', clickedId);
476463
}
477464
})
478465

479466
.on('mouseout', function (d) {
480-
//console.log(d.explicitOriginalTarget.__data__.Day)
481-
482-
if (curr['Done%'] != -1) {
483-
d3.selectAll(
484-
'#segment-' +
485-
curr.SubDimension.replace(/ /g, '-') +
486-
'-' +
487-
curr.Level.replaceAll(' ', '-')
488-
).attr('fill', function (p) {
489-
var color = d3
490-
.scaleLinear<string, string>()
491-
.domain([0, 1])
492-
.range(['white', 'green']);
493-
// how to access a function within reusable charts
494-
//console.log(color(d.Done));
495-
return color(curr['Done%']);
496-
});
497-
} else {
498-
d3.selectAll(
499-
'#segment-' +
500-
curr.SubDimension.replace(/ /g, '-') +
501-
'-' +
502-
curr.Level.replaceAll(' ', '-')
503-
).attr('fill', '#DCDCDC');
504-
}
467+
_self.console_log_event('mouseout', d);
468+
_self.setSectorCursor(svg, '#hover', '');
505469
});
506470
this.reColorHeatmap();
507471
}
@@ -563,13 +527,8 @@ export class CircularHeatmapComponent implements OnInit {
563527
.attr('class', function (d: any) {
564528
return 'segment-' + d.SubDimension.replace(/ /g, '-');
565529
})
566-
.attr('id', function (d: any) {
567-
return (
568-
'segment-' +
569-
d.SubDimension.replace(/ /g, '-') +
570-
'-' +
571-
d.Level.replaceAll(' ', '-')
572-
);
530+
.attr('id', function (d: any, i: number) {
531+
return 'index-' + i;
573532
})
574533
.attr(
575534
'd',
@@ -580,9 +539,7 @@ export class CircularHeatmapComponent implements OnInit {
580539
.startAngle(sa)
581540
.endAngle(ea)
582541
)
583-
.attr('stroke', function (d) {
584-
return '#252525';
585-
})
542+
.attr('stroke', '#252525')
586543
.attr('fill', function (d) {
587544
return color(accessor(d));
588545
});
@@ -630,6 +587,31 @@ export class CircularHeatmapComponent implements OnInit {
630587
.text(function (d: any) {
631588
return d;
632589
});
590+
var cursors = svg
591+
.append('g')
592+
.classed('cursors', true)
593+
.attr(
594+
'transform',
595+
'translate(' +
596+
(margin.left + offset) +
597+
',' +
598+
(margin.top + offset) +
599+
')'
600+
);
601+
cursors
602+
.append('path')
603+
.attr('id', 'hover')
604+
.attr('pointer-events', 'none')
605+
.attr('stroke', 'green')
606+
.attr('stroke-width', '7')
607+
.attr('fill', 'transparent');
608+
cursors
609+
.append('path')
610+
.attr('id', 'selected')
611+
.attr('pointer-events', 'none')
612+
.attr('stroke', '#232323')
613+
.attr('stroke-width', '4')
614+
.attr('fill', 'transparent');
633615
});
634616
}
635617

@@ -711,15 +693,21 @@ export class CircularHeatmapComponent implements OnInit {
711693
return chart;
712694
}
713695

696+
setSectorCursor(svg: any, cursor: string, targetId: string): void {
697+
let element = svg.select(cursor);
698+
let path: string = '';
699+
if (targetId) {
700+
if (targetId[0] != '#') targetId = '#' + targetId;
701+
path = svg.select(targetId).attr('d');
702+
}
703+
704+
svg.select(cursor).attr('d', path);
705+
}
706+
714707
noActivitytoGrey(): void {
715708
for (var x = 0; x < this.ALL_CARD_DATA.length; x++) {
716709
if (this.ALL_CARD_DATA[x]['Done%'] == -1) {
717-
d3.selectAll(
718-
'#segment-' +
719-
this.ALL_CARD_DATA[x]['SubDimension'].replace(/ /g, '-') +
720-
'-' +
721-
this.ALL_CARD_DATA[x]['Level'].replace(' ', '-')
722-
).attr('fill', '#DCDCDC');
710+
d3.select('#index-' + x).attr('fill', '#DCDCDC');
723711
}
724712
}
725713
}
@@ -806,47 +794,39 @@ export class CircularHeatmapComponent implements OnInit {
806794

807795
reColorHeatmap() {
808796
console.log('recolor');
797+
var teamsCount = this.teamVisible.length;
798+
809799
for (var index = 0; index < this.ALL_CARD_DATA.length; index++) {
810-
let cntAll: number = 0;
800+
var activities = this.ALL_CARD_DATA[index]['Activity'];
801+
let cntAll: number = teamsCount * activities.length;
811802
let cntTrue: number = 0;
812803
var _self = this;
813-
for (var i = 0; i < this.ALL_CARD_DATA[index]['Activity'].length; i++) {
814-
var activityTeamList: any;
815-
activityTeamList =
816-
this.ALL_CARD_DATA[index]['Activity'][i]['teamsImplemented'];
817-
(
818-
Object.keys(activityTeamList) as (keyof typeof activityTeamList)[]
819-
).forEach((key, index) => {
820-
if (typeof key === 'string') {
821-
if (this.teamVisible.includes(key)) {
822-
if (activityTeamList[key] === true) {
823-
cntTrue += 1;
824-
}
825-
cntAll += 1;
826-
}
804+
for (var i = 0; i < activities.length; i++) {
805+
for (var teamname of this.teamVisible) {
806+
if (activities[i]['teamsImplemented'][teamname]) {
807+
cntTrue++;
808+
// console.log(`Counting ${activities[i].activityName}: ${teamname} (${cntTrue})`);
827809
}
828-
});
810+
}
829811
}
812+
813+
var colorSector = d3
814+
.scaleLinear<string, string>()
815+
.domain([0, 1])
816+
.range(['white', 'green']);
817+
830818
if (cntAll !== 0) {
831819
this.ALL_CARD_DATA[index]['Done%'] = cntTrue / cntAll;
820+
// console.log(`${this.ALL_CARD_DATA[index].SubDimension} ${this.ALL_CARD_DATA[index].Level} Done: ${cntTrue}/${cntAll} = ${(cntTrue / cntAll*100).toFixed(1)}%`);
821+
d3.select('#index-' + index).attr('fill', function (p) {
822+
return colorSector(_self.ALL_CARD_DATA[index]['Done%']);
823+
});
832824
} else {
833825
this.ALL_CARD_DATA[index]['Done%'] = -1;
826+
// console.log(`${this.ALL_CARD_DATA[index].SubDimension} ${this.ALL_CARD_DATA[index].Level} None`);
827+
d3.select('#index-' + index).attr('fill', '#DCDCDC');
834828
}
835-
var color = d3
836-
.scaleLinear<string, string>()
837-
.domain([0, 1])
838-
.range(['white', 'green']);
839-
840-
d3.selectAll(
841-
'#segment-' +
842-
this.ALL_CARD_DATA[index]['SubDimension'].replace(/ /g, '-') +
843-
'-' +
844-
this.ALL_CARD_DATA[index]['Level'].replace(' ', '-')
845-
).attr('fill', function (p) {
846-
return color(_self.ALL_CARD_DATA[index]['Done%']);
847-
});
848829
}
849-
this.noActivitytoGrey();
850830
}
851831

852832
ResetIsImplemented() {
@@ -887,4 +867,26 @@ export class CircularHeatmapComponent implements OnInit {
887867
unsorted() {
888868
return 0;
889869
}
870+
871+
console_log_event(type: string, event: any) {
872+
console.log(this.perfNow() + ': --- ' + type + ' ---');
873+
console.log(`${this.perfNow()}: ${this.eventstr('currentTarget', event)}`);
874+
// eslint-disable-next-line
875+
console.log(`${this.perfNow()}: ${this.eventstr('explicitOriginalTarget', event)}`);
876+
console.log(`${this.perfNow()}: ${this.eventstr('srcElement', event)}`);
877+
console.log(`${this.perfNow()}: ${this.eventstr('toElement', event)}`);
878+
console.log(`${this.perfNow()}: ${this.eventstr('relatedTarget', event)}`);
879+
}
880+
eventstr(name: string, event: any): string {
881+
let str: string = ': ' + name + ': ';
882+
if (event[name]) {
883+
str +=
884+
`<${event[name]?.localName} id="${event[name]?.id}" ` +
885+
`class="${event[name]?.classList?.toString()}">`;
886+
} else {
887+
str += event[name];
888+
}
889+
890+
return str;
891+
}
890892
}

0 commit comments

Comments
 (0)