Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Clients.Hive.WebJobManager/Scripts/GlobalJS/d3-tip.js @ 17709

Last change on this file since 17709 was 13754, checked in by jlodewyc, 9 years ago

#2582 User management done, start resource calendar

File size: 9.7 KB
Line 
1// d3.tip
2// Copyright (c) 2013 Justin Palmer
3//
4// Tooltips for d3.js SVG visualizations
5
6(function (root, factory) {
7    if (typeof define === 'function' && define.amd) {
8        // AMD. Register as an anonymous module with d3 as a dependency.
9        define(['d3'], factory)
10    } else if (typeof module === 'object' && module.exports) {
11        // CommonJS
12        module.exports = function (d3) {
13            d3.tip = factory(d3)
14            return d3.tip
15        }
16    } else {
17        // Browser global.
18        root.d3.tip = factory(root.d3)
19    }
20}(this, function (d3) {
21
22    // Public - contructs a new tooltip
23    //
24    // Returns a tip
25    return function () {
26        var direction = d3_tip_direction,
27            offset = d3_tip_offset,
28            html = d3_tip_html,
29            node = initNode(),
30            svg = null,
31            point = null,
32            target = null
33
34        function tip(vis) {
35            svg = getSVGNode(vis)
36            point = svg.createSVGPoint()
37            document.body.appendChild(node)
38        }
39
40        // Public - show the tooltip on the screen
41        //
42        // Returns a tip
43        tip.show = function () {
44            var args = Array.prototype.slice.call(arguments)
45            if (args[args.length - 1] instanceof SVGElement) target = args.pop()
46
47            var content = html.apply(this, args),
48                poffset = offset.apply(this, args),
49                dir = direction.apply(this, args),
50                nodel = getNodeEl(),
51                i = directions.length,
52                coords,
53                scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
54                scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
55
56            nodel.html(content)
57              .style({ opacity: 1, 'pointer-events': 'all' })
58
59            while (i--) nodel.classed(directions[i], false)
60            coords = direction_callbacks.get(dir).apply(this)
61            nodel.classed(dir, true).style({
62                top: (coords.top + poffset[0]) + scrollTop + 'px',
63                left: (coords.left + poffset[1]) + scrollLeft + 'px'
64            })
65
66            return tip
67        }
68
69        // Public - hide the tooltip
70        //
71        // Returns a tip
72        tip.hide = function () {
73            var nodel = getNodeEl()
74            nodel.style({ opacity: 0, 'pointer-events': 'none' })
75            return tip
76        }
77
78        // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value.
79        //
80        // n - name of the attribute
81        // v - value of the attribute
82        //
83        // Returns tip or attribute value
84        tip.attr = function (n, v) {
85            if (arguments.length < 2 && typeof n === 'string') {
86                return getNodeEl().attr(n)
87            } else {
88                var args = Array.prototype.slice.call(arguments)
89                d3.selection.prototype.attr.apply(getNodeEl(), args)
90            }
91
92            return tip
93        }
94
95        // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value.
96        //
97        // n - name of the property
98        // v - value of the property
99        //
100        // Returns tip or style property value
101        tip.style = function (n, v) {
102            if (arguments.length < 2 && typeof n === 'string') {
103                return getNodeEl().style(n)
104            } else {
105                var args = Array.prototype.slice.call(arguments)
106                d3.selection.prototype.style.apply(getNodeEl(), args)
107            }
108
109            return tip
110        }
111
112        // Public: Set or get the direction of the tooltip
113        //
114        // v - One of n(north), s(south), e(east), or w(west), nw(northwest),
115        //     sw(southwest), ne(northeast) or se(southeast)
116        //
117        // Returns tip or direction
118        tip.direction = function (v) {
119            if (!arguments.length) return direction
120            direction = v == null ? v : d3.functor(v)
121
122            return tip
123        }
124
125        // Public: Sets or gets the offset of the tip
126        //
127        // v - Array of [x, y] offset
128        //
129        // Returns offset or
130        tip.offset = function (v) {
131            if (!arguments.length) return offset
132            offset = v == null ? v : d3.functor(v)
133
134            return tip
135        }
136
137        // Public: sets or gets the html value of the tooltip
138        //
139        // v - String value of the tip
140        //
141        // Returns html value or tip
142        tip.html = function (v) {
143            if (!arguments.length) return html
144            html = v == null ? v : d3.functor(v)
145
146            return tip
147        }
148
149        // Public: destroys the tooltip and removes it from the DOM
150        //
151        // Returns a tip
152        tip.destroy = function () {
153            if (node) {
154                getNodeEl().remove();
155                node = null;
156            }
157            return tip;
158        }
159
160        function d3_tip_direction() { return 'n' }
161        function d3_tip_offset() { return [0, 0] }
162        function d3_tip_html() { return ' ' }
163
164        var direction_callbacks = d3.map({
165            n: direction_n,
166            s: direction_s,
167            e: direction_e,
168            w: direction_w,
169            nw: direction_nw,
170            ne: direction_ne,
171            sw: direction_sw,
172            se: direction_se
173        }),
174
175        directions = direction_callbacks.keys()
176
177        function direction_n() {
178            var bbox = getScreenBBox()
179            return {
180                top: bbox.n.y - node.offsetHeight,
181                left: bbox.n.x - node.offsetWidth / 2
182            }
183        }
184
185        function direction_s() {
186            var bbox = getScreenBBox()
187            return {
188                top: bbox.s.y,
189                left: bbox.s.x - node.offsetWidth / 2
190            }
191        }
192
193        function direction_e() {
194            var bbox = getScreenBBox()
195            return {
196                top: bbox.e.y - node.offsetHeight / 2,
197                left: bbox.e.x
198            }
199        }
200
201        function direction_w() {
202            var bbox = getScreenBBox()
203            return {
204                top: bbox.w.y - node.offsetHeight / 2,
205                left: bbox.w.x - node.offsetWidth
206            }
207        }
208
209        function direction_nw() {
210            var bbox = getScreenBBox()
211            return {
212                top: bbox.nw.y - node.offsetHeight,
213                left: bbox.nw.x - node.offsetWidth
214            }
215        }
216
217        function direction_ne() {
218            var bbox = getScreenBBox()
219            return {
220                top: bbox.ne.y - node.offsetHeight,
221                left: bbox.ne.x
222            }
223        }
224
225        function direction_sw() {
226            var bbox = getScreenBBox()
227            return {
228                top: bbox.sw.y,
229                left: bbox.sw.x - node.offsetWidth
230            }
231        }
232
233        function direction_se() {
234            var bbox = getScreenBBox()
235            return {
236                top: bbox.se.y,
237                left: bbox.e.x
238            }
239        }
240
241        function initNode() {
242            var node = d3.select(document.createElement('div'))
243            node.style({
244                position: 'absolute',
245                top: 0,
246                opacity: 0,
247                'pointer-events': 'none',
248                'box-sizing': 'border-box'
249            })
250
251            return node.node()
252        }
253
254        function getSVGNode(el) {
255            el = el.node()
256            if (el.tagName.toLowerCase() === 'svg')
257                return el
258
259            return el.ownerSVGElement
260        }
261
262        function getNodeEl() {
263            if (node === null) {
264                node = initNode();
265                // re-add node to DOM
266                document.body.appendChild(node);
267            };
268            return d3.select(node);
269        }
270
271        // Private - gets the screen coordinates of a shape
272        //
273        // Given a shape on the screen, will return an SVGPoint for the directions
274        // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest),
275        // sw(southwest).
276        //
277        //    +-+-+
278        //    |   |
279        //    +   +
280        //    |   |
281        //    +-+-+
282        //
283        // Returns an Object {n, s, e, w, nw, sw, ne, se}
284        function getScreenBBox() {
285            var targetel = target || d3.event.target;
286
287            while ('undefined' === typeof targetel.getScreenCTM && 'undefined' === targetel.parentNode) {
288                targetel = targetel.parentNode;
289            }
290
291            var bbox = {},
292                matrix = targetel.getScreenCTM(),
293                tbbox = targetel.getBBox(),
294                width = tbbox.width,
295                height = tbbox.height,
296                x = tbbox.x,
297                y = tbbox.y
298
299            point.x = x
300            point.y = y
301            bbox.nw = point.matrixTransform(matrix)
302            point.x += width
303            bbox.ne = point.matrixTransform(matrix)
304            point.y += height
305            bbox.se = point.matrixTransform(matrix)
306            point.x -= width
307            bbox.sw = point.matrixTransform(matrix)
308            point.y -= height / 2
309            bbox.w = point.matrixTransform(matrix)
310            point.x += width
311            bbox.e = point.matrixTransform(matrix)
312            point.x -= width / 2
313            point.y -= height / 2
314            bbox.n = point.matrixTransform(matrix)
315            point.y += height
316            bbox.s = point.matrixTransform(matrix)
317
318            return bbox
319        }
320
321        return tip
322    };
323
324}));
Note: See TracBrowser for help on using the repository browser.