From 6ae28af352ebdd08c3608e34747d790d5978411d Mon Sep 17 00:00:00 2001 From: Hoan Nguyen Mau Quoc Date: Thu, 15 Sep 2016 20:37:16 +0100 Subject: [PATCH 1/3] update code based on indications in previous PR --- public/heatmap.html | 3 +- public/heatmap.js | 6 +- public/heatmap_tooltip.css | 27 +++ public/heatmap_tooltip.html | 8 + public/heatmap_tooltip_directive.js | 58 +++++ public/lib/heatmap_controller.js | 48 +++- public/tooltip_directive.js | 52 +++++ public/vis/components/axis/axis.js | 1 - public/vis/components/control/events.js | 3 +- public/vis/components/elements/text.js | 1 - public/vis/components/utils/d3.tip.js | 280 ++++++++++++++++++++++++ public/vis/index.js | 1 - 12 files changed, 479 insertions(+), 9 deletions(-) create mode 100644 public/heatmap_tooltip.css create mode 100644 public/heatmap_tooltip.html create mode 100644 public/heatmap_tooltip_directive.js create mode 100644 public/tooltip_directive.js create mode 100644 public/vis/components/utils/d3.tip.js diff --git a/public/heatmap.html b/public/heatmap.html index 1ee986c..0d81b32 100644 --- a/public/heatmap.html +++ b/public/heatmap.html @@ -1,3 +1,4 @@
- + +
diff --git a/public/heatmap.js b/public/heatmap.js index c883c59..a1d2a7f 100644 --- a/public/heatmap.js +++ b/public/heatmap.js @@ -1,11 +1,13 @@ require('plugins/heatmap/heatmap.less'); +require('plugins/heatmap/heatmap_tooltip.css'); require('plugins/heatmap/color_directive.js'); require('plugins/heatmap/lib/heatmap_controller.js'); require('plugins/heatmap/lib/heatmap_directive.js'); +require('plugins/heatmap/heatmap_tooltip_directive.js'); function HeatmapProvider(Private) { - var TemplateVisType = Private(require('ui/template_vis_type/TemplateVisType')); - var Schemas = Private(require('ui/Vis/Schemas')); + var TemplateVisType = Private(require('ui/template_vis_type/template_vis_type')); + var Schemas = Private(require('ui/vis/schemas')); var colors = require('plugins/heatmap/colors.js'); return new TemplateVisType({ diff --git a/public/heatmap_tooltip.css b/public/heatmap_tooltip.css new file mode 100644 index 0000000..b7cdab5 --- /dev/null +++ b/public/heatmap_tooltip.css @@ -0,0 +1,27 @@ +.heatmap-tooltip { + position: absolute; + width: auto; + height: auto; + padding: 5px; + z-index: 150; + background-color: #d3d3d3; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); + -mox-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); + box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); + pointer-events: none; + white-space: nowrap; +} + +.heatmap-tooltip-list { + padding: 0; + list-style-type: none; +} +.heatmap-tooltip-list span{ + font-size: 12px; +} +.heatmap-tooltip-list span.key{ + font-weight: bold; +} \ No newline at end of file diff --git a/public/heatmap_tooltip.html b/public/heatmap_tooltip.html new file mode 100644 index 0000000..1e5fa00 --- /dev/null +++ b/public/heatmap_tooltip.html @@ -0,0 +1,8 @@ +
+ +
\ No newline at end of file diff --git a/public/heatmap_tooltip_directive.js b/public/heatmap_tooltip_directive.js new file mode 100644 index 0000000..6c95457 --- /dev/null +++ b/public/heatmap_tooltip_directive.js @@ -0,0 +1,58 @@ +var d3 = require("d3"); +var _ = require("lodash"); +var module = require('ui/modules').get('heatmap'); + +module.directive('tooltip', function () { + + function controller($scope) { + $scope.isShown = false; + /* + * Make sure that the items array is populated before tooltip is shown. + * The items variable is an array of objects, e.g. + * [ + * { key: "Column", value: "Tuesday" }, + * { key: "Row", value: "12pm" }, + * { key: "Count", value: 12 } + * ] + */ + this.showOnHover = function () { + $scope.isShown = !!($scope.items && _.isArray($scope.items) && $scope.items.length); + }; + + this.hideOnOut = function(){ + $scope.isShown = false; + }; + } + + function link(scope, element, attrs, ctrl) { + function render($scope) { + d3.select(_.first(element)) + .style("top", $scope.top + "px") + .style("left", $scope.left + "px"); + + ctrl.showOnHover(); + } + + scope.$watchGroup(["top", "left", "items"], function (newVal, oldVal, scope) { + render(scope); + }, 250); + + scope.$watch("ngShow", function (newVal) { + ctrl.hideOnOut(); + }); + }; + + return { + restrict: "E", + scope: { + top: "=", + left: "=", + items: "=", + ngShow: "=" + }, + replace: true, + controller: controller, + link: link, + template: require("plugins/heatmap/heatmap_tooltip.html") + }; +}); \ No newline at end of file diff --git a/public/lib/heatmap_controller.js b/public/lib/heatmap_controller.js index a7aa6db..52e24e1 100644 --- a/public/lib/heatmap_controller.js +++ b/public/lib/heatmap_controller.js @@ -47,7 +47,7 @@ module.controller('HeatmapController', function ($scope, Private) { $scope.data = null; return; } - + // Add row, column, and metric titles as vis parameters _.merge($scope.vis.params, { rowAxis: { title: getLabel($scope.vis.aggs, 'rows') }, @@ -58,5 +58,51 @@ module.controller('HeatmapController', function ($scope, Private) { $scope.data = [{ cells: processTableGroups(tabifyAggResponse($scope.vis, resp), $scope) }]; + + $scope.eventListeners = { + mouseover: [ mouseover ], + mouseout: [ mouseout ] + }; + + function mouseover(event) { + var target = d3.select(event.target); + var isHeatmapCell = (target.attr("class") === "cell"); + var OFFSET = 50; + + if (isHeatmapCell) { + // get data bound to heatmap cell + var d = _.first(target.data()); + // Custom code for tooltip functionality goes here + $scope.$apply(function () { + var params = $scope.vis.params; + $scope.tooltipItems = Object.keys(d) + .filter(function (key) { return key !== "data"; }) + .map(function (key) { + + var title = d3.selectAll('text.title'); + var value = d[key]; + if(key.toUpperCase() === 'ROW') + key = params.columnAxis.title || 'ROW'; + if(key.toUpperCase() === 'COL') + key = params.rowAxis.title || 'COL'; + return { + key: key.toUpperCase(), + value: value + }; + }); + + $scope.top = d.data.row + parseInt(params.margin.top) + OFFSET; + $scope.left = d.data.col + parseInt(params.margin.left) + OFFSET; + }); + } + }; + + function mouseout(event){ + $scope.$apply(function () { + $scope.tooltipItems = []; + $scope.top = 0; + $scope.left = 0; + }); + } }); }); diff --git a/public/tooltip_directive.js b/public/tooltip_directive.js new file mode 100644 index 0000000..78e614d --- /dev/null +++ b/public/tooltip_directive.js @@ -0,0 +1,52 @@ +var d3 = require("d3"); +var _ = require("lodash"); +var module = require('ui/modules').get('heatmap'); + +module.directive('tooltip', function () { + debugger; + function controller($scope) { + $scope.isShown = false; + debugger; + /* + * Make sure that the items array is populated before tooltip is shown. + * The items variable is an array of objects, e.g. + * [ + * { key: "Column", value: "Tuesday" }, + * { key: "Row", value: "12pm" }, + * { key: "Count", value: 12 } + * ] + */ + this.showOnHover = function () { + $scope.isShown = !!($scope.items && _.isArray($scope.items) && $scope.items.length); + }; + } + + function link(scope, element, attrs, ctrl) { + function render($scope) { + debugger; + d3.select(_.first(element)) + .style("top", $scope.top + "px") + .style("left", $scope.left + "px"); + + ctrl.showOnHover(); + } + + scope.$watchGroup(["top", "left", "items"], function (newVal, oldVal, scope) { + debugger; + render(scope); + }, 250); + } + + return { + restrict: "E", + scope: { + top: "=", + left: "=", + items: "=" + }, + replace: true, + controller: controller, + link: link, + template: require("plugins/heatmap/heatmap_tooltip.html") + }; +}); \ No newline at end of file diff --git a/public/vis/components/axis/axis.js b/public/vis/components/axis/axis.js index db2f5ac..ee76984 100644 --- a/public/vis/components/axis/axis.js +++ b/public/vis/components/axis/axis.js @@ -58,7 +58,6 @@ function axes() { var text = g.selectAll('text.title') .data([data]); - text.exit().remove(); text.enter().append('text') .attr('class', title.class || 'title'); diff --git a/public/vis/components/control/events.js b/public/vis/components/control/events.js index dfd5ecf..c3b1ce4 100644 --- a/public/vis/components/control/events.js +++ b/public/vis/components/control/events.js @@ -14,9 +14,8 @@ function events() { } d3.entries(listeners).forEach(function (d) { - svg.on(d.key, function () { + element.on(d.key, function () { d3.event.stopPropagation(); // => event.stopPropagation() - _.forEach(d.value, function (listener) { listener.call(this, processor(d3.event)); }); diff --git a/public/vis/components/elements/text.js b/public/vis/components/elements/text.js index 63bcbc9..e6967ba 100644 --- a/public/vis/components/elements/text.js +++ b/public/vis/components/elements/text.js @@ -15,7 +15,6 @@ function text() { selection.each(function (data) { var text = d3.select(this).selectAll('text.' + cssClass) .data(data); - text.exit().remove(); text.enter().append('text') diff --git a/public/vis/components/utils/d3.tip.js b/public/vis/components/utils/d3.tip.js new file mode 100644 index 0000000..6cfa3cb --- /dev/null +++ b/public/vis/components/utils/d3.tip.js @@ -0,0 +1,280 @@ +// d3.tip +// Copyright (c) 2013 Justin Palmer +// +// Tooltips for d3.js SVG visualizations + +// Public - contructs a new tooltip +// +// Returns a tip +d3.tip = function() { + var direction = d3_tip_direction, + offset = d3_tip_offset, + html = d3_tip_html, + node = initNode(), + svg = null, + point = null, + target = null + + function tip(vis) { + svg = getSVGNode(vis) + point = svg.createSVGPoint() + document.body.appendChild(node) + } + + // Public - show the tooltip on the screen + // + // Returns a tip + tip.show = function() { + var args = Array.prototype.slice.call(arguments) + if(args[args.length - 1] instanceof SVGElement) target = args.pop() + + var content = html.apply(this, args), + poffset = offset.apply(this, args), + dir = direction.apply(this, args), + nodel = d3.select(node), i = 0, + coords + + nodel.html(content) + .style({ opacity: 1, 'pointer-events': 'all' }) + + while(i--) nodel.classed(directions[i], false) + coords = direction_callbacks.get(dir).apply(this) + nodel.classed(dir, true).style({ + top: (coords.top + poffset[0]) + 'px', + left: (coords.left + poffset[1]) + 'px' + }) + + return tip + } + + // Public - hide the tooltip + // + // Returns a tip + tip.hide = function() { + nodel = d3.select(node) + nodel.style({ opacity: 0, 'pointer-events': 'none' }) + return tip + } + + // Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value. + // + // n - name of the attribute + // v - value of the attribute + // + // Returns tip or attribute value + tip.attr = function(n, v) { + if (arguments.length < 2 && typeof n === 'string') { + return d3.select(node).attr(n) + } else { + var args = Array.prototype.slice.call(arguments) + d3.selection.prototype.attr.apply(d3.select(node), args) + } + + return tip + } + + // Public: Proxy style calls to the d3 tip container. Sets or gets a style value. + // + // n - name of the property + // v - value of the property + // + // Returns tip or style property value + tip.style = function(n, v) { + if (arguments.length < 2 && typeof n === 'string') { + return d3.select(node).style(n) + } else { + var args = Array.prototype.slice.call(arguments) + d3.selection.prototype.style.apply(d3.select(node), args) + } + + return tip + } + + // Public: Set or get the direction of the tooltip + // + // v - One of n(north), s(south), e(east), or w(west), nw(northwest), + // sw(southwest), ne(northeast) or se(southeast) + // + // Returns tip or direction + tip.direction = function(v) { + if (!arguments.length) return direction + direction = v == null ? v : d3.functor(v) + + return tip + } + + // Public: Sets or gets the offset of the tip + // + // v - Array of [x, y] offset + // + // Returns offset or + tip.offset = function(v) { + if (!arguments.length) return offset + offset = v == null ? v : d3.functor(v) + + return tip + } + + // Public: sets or gets the html value of the tooltip + // + // v - String value of the tip + // + // Returns html value or tip + tip.html = function(v) { + if (!arguments.length) return html + html = v == null ? v : d3.functor(v) + + return tip + } + + function d3_tip_direction() { return 'n' } + function d3_tip_offset() { return [0, 0] } + function d3_tip_html() { return ' ' } + + var direction_callbacks = d3.map({ + n: direction_n, + s: direction_s, + e: direction_e, + w: direction_w, + nw: direction_nw, + ne: direction_ne, + sw: direction_sw, + se: direction_se + }), + + directions = direction_callbacks.keys() + + function direction_n() { + var bbox = getScreenBBox() + return { + top: bbox.n.y - node.offsetHeight, + left: bbox.n.x - node.offsetWidth / 2 + } + } + + function direction_s() { + var bbox = getScreenBBox() + return { + top: bbox.s.y, + left: bbox.s.x - node.offsetWidth / 2 + } + } + + function direction_e() { + var bbox = getScreenBBox() + return { + top: bbox.e.y - node.offsetHeight / 2, + left: bbox.e.x + } + } + + function direction_w() { + var bbox = getScreenBBox() + return { + top: bbox.w.y - node.offsetHeight / 2, + left: bbox.w.x - node.offsetWidth + } + } + + function direction_nw() { + var bbox = getScreenBBox() + return { + top: bbox.nw.y - node.offsetHeight, + left: bbox.nw.x - node.offsetWidth + } + } + + function direction_ne() { + var bbox = getScreenBBox() + return { + top: bbox.ne.y - node.offsetHeight, + left: bbox.ne.x + } + } + + function direction_sw() { + var bbox = getScreenBBox() + return { + top: bbox.sw.y, + left: bbox.sw.x - node.offsetWidth + } + } + + function direction_se() { + var bbox = getScreenBBox() + return { + top: bbox.se.y, + left: bbox.e.x + } + } + + function initNode() { + var node = d3.select(document.createElement('div')) + node.style({ + position: 'absolute', + opacity: 0, + pointerEvents: 'none', + boxSizing: 'border-box' + }) + + return node.node() + } + + function getSVGNode(el) { + el = el.node() + if(el.tagName.toLowerCase() == 'svg') + return el + + return el.ownerSVGElement + } + + // Private - gets the screen coordinates of a shape + // + // Given a shape on the screen, will return an SVGPoint for the directions + // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest), + // sw(southwest). + // + // +-+-+ + // | | + // + + + // | | + // +-+-+ + // + // Returns an Object {n, s, e, w, nw, sw, ne, se} + function getScreenBBox() { + var targetel = target || d3.event.target, + bbox = {}, + matrix = targetel.getScreenCTM(), + tbbox = targetel.getBBox(), + width = tbbox.width, + height = tbbox.height, + x = tbbox.x, + y = tbbox.y, + scrollTop = document.documentElement.scrollTop || document.body.scrollTop, + scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft + + + point.x = x + scrollLeft + point.y = y + scrollTop + bbox.nw = point.matrixTransform(matrix) + point.x += width + bbox.ne = point.matrixTransform(matrix) + point.y += height + bbox.se = point.matrixTransform(matrix) + point.x -= width + bbox.sw = point.matrixTransform(matrix) + point.y -= height / 2 + bbox.w = point.matrixTransform(matrix) + point.x += width + bbox.e = point.matrixTransform(matrix) + point.x -= width / 2 + point.y -= height / 2 + bbox.n = point.matrixTransform(matrix) + point.y += height + bbox.s = point.matrixTransform(matrix) + + return bbox + } + + return tip +}; diff --git a/public/vis/index.js b/public/vis/index.js index 44be53d..4961edd 100644 --- a/public/vis/index.js +++ b/public/vis/index.js @@ -15,7 +15,6 @@ function vis() { function generator(selection) { selection.each(function (data) { events.listeners(listeners); - layout.attr({ type: opts.layout || 'grid', columns: opts.numOfColumns || 0, From c4d7bbd49f01d01793ee6fd19594650c6134978a Mon Sep 17 00:00:00 2001 From: Hoan Nguyen Mau Quoc Date: Fri, 16 Sep 2016 17:43:48 +0100 Subject: [PATCH 2/3] remove d3.tip.js --- public/vis/components/utils/d3.tip.js | 280 -------------------------- 1 file changed, 280 deletions(-) delete mode 100644 public/vis/components/utils/d3.tip.js diff --git a/public/vis/components/utils/d3.tip.js b/public/vis/components/utils/d3.tip.js deleted file mode 100644 index 6cfa3cb..0000000 --- a/public/vis/components/utils/d3.tip.js +++ /dev/null @@ -1,280 +0,0 @@ -// d3.tip -// Copyright (c) 2013 Justin Palmer -// -// Tooltips for d3.js SVG visualizations - -// Public - contructs a new tooltip -// -// Returns a tip -d3.tip = function() { - var direction = d3_tip_direction, - offset = d3_tip_offset, - html = d3_tip_html, - node = initNode(), - svg = null, - point = null, - target = null - - function tip(vis) { - svg = getSVGNode(vis) - point = svg.createSVGPoint() - document.body.appendChild(node) - } - - // Public - show the tooltip on the screen - // - // Returns a tip - tip.show = function() { - var args = Array.prototype.slice.call(arguments) - if(args[args.length - 1] instanceof SVGElement) target = args.pop() - - var content = html.apply(this, args), - poffset = offset.apply(this, args), - dir = direction.apply(this, args), - nodel = d3.select(node), i = 0, - coords - - nodel.html(content) - .style({ opacity: 1, 'pointer-events': 'all' }) - - while(i--) nodel.classed(directions[i], false) - coords = direction_callbacks.get(dir).apply(this) - nodel.classed(dir, true).style({ - top: (coords.top + poffset[0]) + 'px', - left: (coords.left + poffset[1]) + 'px' - }) - - return tip - } - - // Public - hide the tooltip - // - // Returns a tip - tip.hide = function() { - nodel = d3.select(node) - nodel.style({ opacity: 0, 'pointer-events': 'none' }) - return tip - } - - // Public: Proxy attr calls to the d3 tip container. Sets or gets attribute value. - // - // n - name of the attribute - // v - value of the attribute - // - // Returns tip or attribute value - tip.attr = function(n, v) { - if (arguments.length < 2 && typeof n === 'string') { - return d3.select(node).attr(n) - } else { - var args = Array.prototype.slice.call(arguments) - d3.selection.prototype.attr.apply(d3.select(node), args) - } - - return tip - } - - // Public: Proxy style calls to the d3 tip container. Sets or gets a style value. - // - // n - name of the property - // v - value of the property - // - // Returns tip or style property value - tip.style = function(n, v) { - if (arguments.length < 2 && typeof n === 'string') { - return d3.select(node).style(n) - } else { - var args = Array.prototype.slice.call(arguments) - d3.selection.prototype.style.apply(d3.select(node), args) - } - - return tip - } - - // Public: Set or get the direction of the tooltip - // - // v - One of n(north), s(south), e(east), or w(west), nw(northwest), - // sw(southwest), ne(northeast) or se(southeast) - // - // Returns tip or direction - tip.direction = function(v) { - if (!arguments.length) return direction - direction = v == null ? v : d3.functor(v) - - return tip - } - - // Public: Sets or gets the offset of the tip - // - // v - Array of [x, y] offset - // - // Returns offset or - tip.offset = function(v) { - if (!arguments.length) return offset - offset = v == null ? v : d3.functor(v) - - return tip - } - - // Public: sets or gets the html value of the tooltip - // - // v - String value of the tip - // - // Returns html value or tip - tip.html = function(v) { - if (!arguments.length) return html - html = v == null ? v : d3.functor(v) - - return tip - } - - function d3_tip_direction() { return 'n' } - function d3_tip_offset() { return [0, 0] } - function d3_tip_html() { return ' ' } - - var direction_callbacks = d3.map({ - n: direction_n, - s: direction_s, - e: direction_e, - w: direction_w, - nw: direction_nw, - ne: direction_ne, - sw: direction_sw, - se: direction_se - }), - - directions = direction_callbacks.keys() - - function direction_n() { - var bbox = getScreenBBox() - return { - top: bbox.n.y - node.offsetHeight, - left: bbox.n.x - node.offsetWidth / 2 - } - } - - function direction_s() { - var bbox = getScreenBBox() - return { - top: bbox.s.y, - left: bbox.s.x - node.offsetWidth / 2 - } - } - - function direction_e() { - var bbox = getScreenBBox() - return { - top: bbox.e.y - node.offsetHeight / 2, - left: bbox.e.x - } - } - - function direction_w() { - var bbox = getScreenBBox() - return { - top: bbox.w.y - node.offsetHeight / 2, - left: bbox.w.x - node.offsetWidth - } - } - - function direction_nw() { - var bbox = getScreenBBox() - return { - top: bbox.nw.y - node.offsetHeight, - left: bbox.nw.x - node.offsetWidth - } - } - - function direction_ne() { - var bbox = getScreenBBox() - return { - top: bbox.ne.y - node.offsetHeight, - left: bbox.ne.x - } - } - - function direction_sw() { - var bbox = getScreenBBox() - return { - top: bbox.sw.y, - left: bbox.sw.x - node.offsetWidth - } - } - - function direction_se() { - var bbox = getScreenBBox() - return { - top: bbox.se.y, - left: bbox.e.x - } - } - - function initNode() { - var node = d3.select(document.createElement('div')) - node.style({ - position: 'absolute', - opacity: 0, - pointerEvents: 'none', - boxSizing: 'border-box' - }) - - return node.node() - } - - function getSVGNode(el) { - el = el.node() - if(el.tagName.toLowerCase() == 'svg') - return el - - return el.ownerSVGElement - } - - // Private - gets the screen coordinates of a shape - // - // Given a shape on the screen, will return an SVGPoint for the directions - // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest), - // sw(southwest). - // - // +-+-+ - // | | - // + + - // | | - // +-+-+ - // - // Returns an Object {n, s, e, w, nw, sw, ne, se} - function getScreenBBox() { - var targetel = target || d3.event.target, - bbox = {}, - matrix = targetel.getScreenCTM(), - tbbox = targetel.getBBox(), - width = tbbox.width, - height = tbbox.height, - x = tbbox.x, - y = tbbox.y, - scrollTop = document.documentElement.scrollTop || document.body.scrollTop, - scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft - - - point.x = x + scrollLeft - point.y = y + scrollTop - bbox.nw = point.matrixTransform(matrix) - point.x += width - bbox.ne = point.matrixTransform(matrix) - point.y += height - bbox.se = point.matrixTransform(matrix) - point.x -= width - bbox.sw = point.matrixTransform(matrix) - point.y -= height / 2 - bbox.w = point.matrixTransform(matrix) - point.x += width - bbox.e = point.matrixTransform(matrix) - point.x -= width / 2 - point.y -= height / 2 - bbox.n = point.matrixTransform(matrix) - point.y += height - bbox.s = point.matrixTransform(matrix) - - return bbox - } - - return tip -}; From 90b18accea30dbfe8047c806681de9ec01145599 Mon Sep 17 00:00:00 2001 From: Hoan Nguyen Mau Quoc Date: Sun, 25 Sep 2016 20:37:04 +0100 Subject: [PATCH 3/3] fix syntax --- public/heatmap_tooltip.css | 6 ++---- public/lib/heatmap_controller.js | 6 ++++-- public/tooltip_directive.js | 1 - public/vis/components/axis/axis.js | 1 + public/vis/components/elements/text.js | 1 + public/vis/index.js | 1 + 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/public/heatmap_tooltip.css b/public/heatmap_tooltip.css index b7cdab5..3261b8d 100644 --- a/public/heatmap_tooltip.css +++ b/public/heatmap_tooltip.css @@ -1,10 +1,8 @@ .heatmap-tooltip { position: absolute; width: auto; - height: auto; - padding: 5px; - z-index: 150; - background-color: #d3d3d3; + fadeout(@gray-darker, 7%); + gray-darker: #222222; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; diff --git a/public/lib/heatmap_controller.js b/public/lib/heatmap_controller.js index 52e24e1..074f1de 100644 --- a/public/lib/heatmap_controller.js +++ b/public/lib/heatmap_controller.js @@ -81,10 +81,12 @@ module.controller('HeatmapController', function ($scope, Private) { var title = d3.selectAll('text.title'); var value = d[key]; - if(key.toUpperCase() === 'ROW') + if (key.toUpperCase() === 'ROW') { key = params.columnAxis.title || 'ROW'; - if(key.toUpperCase() === 'COL') + } + if (key.toUpperCase() === 'COL') { key = params.rowAxis.title || 'COL'; + } return { key: key.toUpperCase(), value: value diff --git a/public/tooltip_directive.js b/public/tooltip_directive.js index 78e614d..b09a538 100644 --- a/public/tooltip_directive.js +++ b/public/tooltip_directive.js @@ -1,4 +1,3 @@ -var d3 = require("d3"); var _ = require("lodash"); var module = require('ui/modules').get('heatmap'); diff --git a/public/vis/components/axis/axis.js b/public/vis/components/axis/axis.js index ee76984..98794ea 100644 --- a/public/vis/components/axis/axis.js +++ b/public/vis/components/axis/axis.js @@ -58,6 +58,7 @@ function axes() { var text = g.selectAll('text.title') .data([data]); + text.exit().remove(); text.enter().append('text') .attr('class', title.class || 'title'); diff --git a/public/vis/components/elements/text.js b/public/vis/components/elements/text.js index e6967ba..0500c15 100644 --- a/public/vis/components/elements/text.js +++ b/public/vis/components/elements/text.js @@ -15,6 +15,7 @@ function text() { selection.each(function (data) { var text = d3.select(this).selectAll('text.' + cssClass) .data(data); + text.exit().remove(); text.enter().append('text') diff --git a/public/vis/index.js b/public/vis/index.js index 4961edd..e78df43 100644 --- a/public/vis/index.js +++ b/public/vis/index.js @@ -15,6 +15,7 @@ function vis() { function generator(selection) { selection.each(function (data) { events.listeners(listeners); + layout.attr({ type: opts.layout || 'grid', columns: opts.numOfColumns || 0,