Skip to content

Commit 9e78176

Browse files
authored
Merge pull request #41 from nmqhoan/issue-6
Issue 6. Add tootip
2 parents 749811c + 90b18ac commit 9e78176

11 files changed

Lines changed: 201 additions & 9 deletions

File tree

public/heatmap.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<div ng-controller="HeatmapController" class="heatmap-vis">
2-
<heatmap data="data" options="vis.params" eventListeners="eventListeners"></heatmap>
2+
<heatmap data="data" options="vis.params" event-listeners="eventListeners"></heatmap>
3+
<tooltip top="top" left="left" items="tooltipItems"></tooltip>
34
</div>

public/heatmap.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
require('plugins/heatmap/heatmap.less');
2+
require('plugins/heatmap/heatmap_tooltip.css');
23
require('plugins/heatmap/color_directive.js');
34
require('plugins/heatmap/lib/heatmap_controller.js');
45
require('plugins/heatmap/lib/heatmap_directive.js');
6+
require('plugins/heatmap/heatmap_tooltip_directive.js');
57

68
function HeatmapProvider(Private) {
7-
var TemplateVisType = Private(require('ui/template_vis_type/TemplateVisType'));
8-
var Schemas = Private(require('ui/Vis/Schemas'));
9+
var TemplateVisType = Private(require('ui/template_vis_type/template_vis_type'));
10+
var Schemas = Private(require('ui/vis/schemas'));
911
var colors = require('plugins/heatmap/colors.js');
1012

1113
return new TemplateVisType({

public/heatmap_tooltip.css

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.heatmap-tooltip {
2+
position: absolute;
3+
width: auto;
4+
fadeout(@gray-darker, 7%);
5+
gray-darker: #222222;
6+
-webkit-border-radius: 10px;
7+
-moz-border-radius: 10px;
8+
border-radius: 10px;
9+
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
10+
-mox-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
11+
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
12+
pointer-events: none;
13+
white-space: nowrap;
14+
}
15+
16+
.heatmap-tooltip-list {
17+
padding: 0;
18+
list-style-type: none;
19+
}
20+
.heatmap-tooltip-list span{
21+
font-size: 12px;
22+
}
23+
.heatmap-tooltip-list span.key{
24+
font-weight: bold;
25+
}

public/heatmap_tooltip.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="heatmap-tooltip" ng-show="isShown">
2+
<ul class="heatmap-tooltip-list">
3+
<li ng-repeat="item in items">
4+
<span class="key">{{ item.key }}: </span>
5+
<span class="value">{{ item.value }}</span>
6+
</li>
7+
</ul>
8+
</div>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
var d3 = require("d3");
2+
var _ = require("lodash");
3+
var module = require('ui/modules').get('heatmap');
4+
5+
module.directive('tooltip', function () {
6+
7+
function controller($scope) {
8+
$scope.isShown = false;
9+
/*
10+
* Make sure that the items array is populated before tooltip is shown.
11+
* The items variable is an array of objects, e.g.
12+
* [
13+
* { key: "Column", value: "Tuesday" },
14+
* { key: "Row", value: "12pm" },
15+
* { key: "Count", value: 12 }
16+
* ]
17+
*/
18+
this.showOnHover = function () {
19+
$scope.isShown = !!($scope.items && _.isArray($scope.items) && $scope.items.length);
20+
};
21+
22+
this.hideOnOut = function(){
23+
$scope.isShown = false;
24+
};
25+
}
26+
27+
function link(scope, element, attrs, ctrl) {
28+
function render($scope) {
29+
d3.select(_.first(element))
30+
.style("top", $scope.top + "px")
31+
.style("left", $scope.left + "px");
32+
33+
ctrl.showOnHover();
34+
}
35+
36+
scope.$watchGroup(["top", "left", "items"], function (newVal, oldVal, scope) {
37+
render(scope);
38+
}, 250);
39+
40+
scope.$watch("ngShow", function (newVal) {
41+
ctrl.hideOnOut();
42+
});
43+
};
44+
45+
return {
46+
restrict: "E",
47+
scope: {
48+
top: "=",
49+
left: "=",
50+
items: "=",
51+
ngShow: "="
52+
},
53+
replace: true,
54+
controller: controller,
55+
link: link,
56+
template: require("plugins/heatmap/heatmap_tooltip.html")
57+
};
58+
});

public/lib/heatmap_controller.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ module.controller('HeatmapController', function ($scope, Private) {
4747
$scope.data = null;
4848
return;
4949
}
50-
50+
5151
// Add row, column, and metric titles as vis parameters
5252
_.merge($scope.vis.params, {
5353
rowAxis: { title: getLabel($scope.vis.aggs, 'rows') },
@@ -58,5 +58,53 @@ module.controller('HeatmapController', function ($scope, Private) {
5858
$scope.data = [{
5959
cells: processTableGroups(tabifyAggResponse($scope.vis, resp), $scope)
6060
}];
61+
62+
$scope.eventListeners = {
63+
mouseover: [ mouseover ],
64+
mouseout: [ mouseout ]
65+
};
66+
67+
function mouseover(event) {
68+
var target = d3.select(event.target);
69+
var isHeatmapCell = (target.attr("class") === "cell");
70+
var OFFSET = 50;
71+
72+
if (isHeatmapCell) {
73+
// get data bound to heatmap cell
74+
var d = _.first(target.data());
75+
// Custom code for tooltip functionality goes here
76+
$scope.$apply(function () {
77+
var params = $scope.vis.params;
78+
$scope.tooltipItems = Object.keys(d)
79+
.filter(function (key) { return key !== "data"; })
80+
.map(function (key) {
81+
82+
var title = d3.selectAll('text.title');
83+
var value = d[key];
84+
if (key.toUpperCase() === 'ROW') {
85+
key = params.columnAxis.title || 'ROW';
86+
}
87+
if (key.toUpperCase() === 'COL') {
88+
key = params.rowAxis.title || 'COL';
89+
}
90+
return {
91+
key: key.toUpperCase(),
92+
value: value
93+
};
94+
});
95+
96+
$scope.top = d.data.row + parseInt(params.margin.top) + OFFSET;
97+
$scope.left = d.data.col + parseInt(params.margin.left) + OFFSET;
98+
});
99+
}
100+
};
101+
102+
function mouseout(event){
103+
$scope.$apply(function () {
104+
$scope.tooltipItems = [];
105+
$scope.top = 0;
106+
$scope.left = 0;
107+
});
108+
}
61109
});
62110
});

public/tooltip_directive.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
var _ = require("lodash");
2+
var module = require('ui/modules').get('heatmap');
3+
4+
module.directive('tooltip', function () {
5+
debugger;
6+
function controller($scope) {
7+
$scope.isShown = false;
8+
debugger;
9+
/*
10+
* Make sure that the items array is populated before tooltip is shown.
11+
* The items variable is an array of objects, e.g.
12+
* [
13+
* { key: "Column", value: "Tuesday" },
14+
* { key: "Row", value: "12pm" },
15+
* { key: "Count", value: 12 }
16+
* ]
17+
*/
18+
this.showOnHover = function () {
19+
$scope.isShown = !!($scope.items && _.isArray($scope.items) && $scope.items.length);
20+
};
21+
}
22+
23+
function link(scope, element, attrs, ctrl) {
24+
function render($scope) {
25+
debugger;
26+
d3.select(_.first(element))
27+
.style("top", $scope.top + "px")
28+
.style("left", $scope.left + "px");
29+
30+
ctrl.showOnHover();
31+
}
32+
33+
scope.$watchGroup(["top", "left", "items"], function (newVal, oldVal, scope) {
34+
debugger;
35+
render(scope);
36+
}, 250);
37+
}
38+
39+
return {
40+
restrict: "E",
41+
scope: {
42+
top: "=",
43+
left: "=",
44+
items: "="
45+
},
46+
replace: true,
47+
controller: controller,
48+
link: link,
49+
template: require("plugins/heatmap/heatmap_tooltip.html")
50+
};
51+
});

public/vis/components/axis/axis.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function axes() {
5858

5959
var text = g.selectAll('text.title')
6060
.data([data]);
61-
61+
6262
text.exit().remove();
6363
text.enter().append('text')
6464
.attr('class', title.class || 'title');

public/vis/components/control/events.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ function events() {
1414
}
1515

1616
d3.entries(listeners).forEach(function (d) {
17-
svg.on(d.key, function () {
17+
element.on(d.key, function () {
1818
d3.event.stopPropagation(); // => event.stopPropagation()
19-
2019
_.forEach(d.value, function (listener) {
2120
listener.call(this, processor(d3.event));
2221
});

public/vis/components/elements/text.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function text() {
1515
selection.each(function (data) {
1616
var text = d3.select(this).selectAll('text.' + cssClass)
1717
.data(data);
18-
18+
1919
text.exit().remove();
2020

2121
text.enter().append('text')

0 commit comments

Comments
 (0)