Skip to content

Commit

Permalink
Update Streaming UI
Browse files Browse the repository at this point in the history
  • Loading branch information
zsxwing committed Apr 28, 2015
1 parent 04c7500 commit 4c0b43f
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 44 deletions.
135 changes: 104 additions & 31 deletions core/src/main/resources/org/apache/spark/ui/static/bootstrap-tooltip.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* ===========================================================
* bootstrap-tooltip.js v2.2.2
* http://twitter.github.com/bootstrap/javascript.html#tooltips
* bootstrap-tooltip.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#tooltips
* Inspired by the original jQuery.tipsy by Jason Frame
* ===========================================================
* Copyright 2012 Twitter, Inc.
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,19 +38,27 @@
, init: function (type, element, options) {
var eventIn
, eventOut
, triggers
, trigger
, i

this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.enabled = true

if (this.options.trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (this.options.trigger != 'manual') {
eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
triggers = this.options.trigger.split(' ')

for (i = triggers.length; i--;) {
trigger = triggers[i]
if (trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}

this.options.selector ?
Expand All @@ -59,7 +67,7 @@
}

, getOptions: function (options) {
options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)

if (options.delay && typeof options.delay == 'number') {
options.delay = {
Expand All @@ -72,7 +80,15 @@
}

, enter: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
var defaults = $.fn[this.type].defaults
, options = {}
, self

this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
}, this)

self = $(e.currentTarget)[this.type](options).data(this.type)

if (!self.options.delay || !self.options.delay.show) return self.show()

Expand All @@ -97,14 +113,16 @@

, show: function () {
var $tip
, inside
, pos
, actualWidth
, actualHeight
, placement
, tp
, e = $.Event('show')

if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$tip = this.tip()
this.setContent()

Expand All @@ -116,19 +134,18 @@
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement

inside = /in/.test(placement)

$tip
.detach()
.css({ top: 0, left: 0, display: 'block' })
.insertAfter(this.$element)

pos = this.getPosition(inside)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

pos = this.getPosition()

actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight

switch (inside ? placement.split(' ')[1] : placement) {
switch (placement) {
case 'bottom':
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
break
Expand All @@ -143,11 +160,56 @@
break
}

$tip
.offset(tp)
.addClass(placement)
.addClass('in')
this.applyPlacement(tp, placement)
this.$element.trigger('shown')
}
}

, applyPlacement: function(offset, placement){
var $tip = this.tip()
, width = $tip[0].offsetWidth
, height = $tip[0].offsetHeight
, actualWidth
, actualHeight
, delta
, replace

$tip
.offset(offset)
.addClass(placement)
.addClass('in')

actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight

if (placement == 'top' && actualHeight != height) {
offset.top = offset.top + height - actualHeight
replace = true
}

if (placement == 'bottom' || placement == 'top') {
delta = 0

if (offset.left < 0){
delta = offset.left * -2
offset.left = 0
$tip.offset(offset)
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
}

this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
} else {
this.replaceArrow(actualHeight - height, actualHeight, 'top')
}

if (replace) $tip.offset(offset)
}

, replaceArrow: function(delta, dimension, position){
this
.arrow()
.css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
}

, setContent: function () {
Expand All @@ -161,6 +223,10 @@
, hide: function () {
var that = this
, $tip = this.tip()
, e = $.Event('hide')

this.$element.trigger(e)
if (e.isDefaultPrevented()) return

$tip.removeClass('in')

Expand All @@ -179,6 +245,8 @@
removeWithAnimation() :
$tip.detach()

this.$element.trigger('hidden')

return this
}

Expand All @@ -193,11 +261,12 @@
return this.getTitle()
}

, getPosition: function (inside) {
return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
width: this.$element[0].offsetWidth
, height: this.$element[0].offsetHeight
})
, getPosition: function () {
var el = this.$element[0]
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
width: el.offsetWidth
, height: el.offsetHeight
}, this.$element.offset())
}

, getTitle: function () {
Expand All @@ -215,6 +284,10 @@
return this.$tip = this.$tip || $(this.options.template)
}

, arrow: function(){
return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
}

, validate: function () {
if (!this.$element[0].parentNode) {
this.hide()
Expand All @@ -236,8 +309,8 @@
}

, toggle: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
self[self.tip().hasClass('in') ? 'hide' : 'show']()
var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
self.tip().hasClass('in') ? self.hide() : self.show()
}

, destroy: function () {
Expand Down Expand Up @@ -269,10 +342,11 @@
, placement: 'top'
, selector: false
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
, trigger: 'hover'
, trigger: 'hover focus'
, title: ''
, delay: 0
, html: false
, container: false
}


Expand All @@ -285,4 +359,3 @@
}

}(window.jQuery);

Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@
}

.distribution {
width: 300px;
width: auto;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ function hideGraphTooltip() {
graphTooltip.style("visibility", "hidden");
}

function showBootstrapTooltip(node, text) {
console.log(text);
$(node).tooltip({title: text, trigger: "manual", 'container': 'body'});
$(node).tooltip("show");
console.log($(node));
}

function hideBootstrapTooltip(node) {
$(node).tooltip("destroy");
}

/**
* @param id the `id` used in the html `div` tag
* @param data the data for the timeline graph
Expand Down Expand Up @@ -107,15 +118,17 @@ function drawTimeline(id, data, minX, maxX, minY, maxY, unitY) {
.attr("r", function(d) { return 3; })
.on('mouseover', function(d) {
var tip = d.y + " " + unitY + " at " + timeFormat[d.x];
showGraphTooltip(tip, d3.event.pageX + 5, d3.event.pageY - 25);
showBootstrapTooltip(d3.select(this).node(), tip);
//showGraphTooltip(tip, d3.event.pageX + 5, d3.event.pageY - 25);
// show the point
d3.select(this)
.attr("stroke", "steelblue")
.attr("fill", "steelblue")
.attr("opacity", "1");
})
.on('mouseout', function() {
hideGraphTooltip();
hideBootstrapTooltip(d3.select(this).node());
//hideGraphTooltip();
// hide the point
d3.select(this)
.attr("stroke", "white")
Expand Down Expand Up @@ -172,7 +185,8 @@ function drawDistribution(id, values, minY, maxY, unitY) {
.attr("width", function(d) { return x(d.y); })
.attr("height", function(d) { return height - y(d.dx); })
.on('mouseover', function(d) {
var tip = d.y + " between " + formatBinValue(d.x) + " " + unitY + " and " + formatBinValue(d.x + d.dx) + " " + unitY;
var tip = d.y + " between " + formatBinValue(d.x) + " and " + formatBinValue(d.x + d.dx) + " " + unitY;
showBootstrapTooltip(d3.select(this).node(), tip);

// Calculate the location for tip
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
Expand All @@ -184,13 +198,14 @@ function drawDistribution(id, values, minY, maxY, unitY) {
point.x = targetBBox.x;
point.y = targetBBox.y;
var bbox = point.matrixTransform(matrix);
var tipX = bbox.x + scrollLeft + x(d.y) + 2;
var tipY = bbox.y + scrollTop - 6;
var tipX = bbox.x + scrollLeft;
var tipY = bbox.y + scrollTop + 15;

showGraphTooltip(tip, tipX, tipY);
//showGraphTooltip(tip, tipX, tipY);
})
.on('mouseout', function() {
hideGraphTooltip();
hideBootstrapTooltip(d3.select(this).node());
//hideGraphTooltip();
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,13 @@ private[ui] class StreamingPage(parent: StreamingTab)

val table =
// scalastyle:off
<table class="table table-bordered">
<table class="table table-bordered" style="width: auto">
<thead>
<tr><th></th><th>Timelines</th><th>Distributions</th></tr>
<tr><th></th><th>Timelines</th><th>Histograms</th></tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">
<td style="vertical-align: middle; width: 200px;">
<div>
<span onclick={Unparsed(triangleJs)}>{Unparsed(BLACK_RIGHT_TRIANGLE_HTML)}</span>
<strong>Input Rate</strong>
Expand Down Expand Up @@ -331,7 +331,7 @@ private[ui] class StreamingPage(parent: StreamingTab)
generateInputReceiverRow(jsCollector, receiverId, distribution, minX, maxX, minY, maxY)
}.foldLeft[Seq[Node]](Nil)(_ ++ _)

<table class="table table-bordered">
<table class="table table-bordered" style="width: auto">
<thead>
<tr>
<th></th>
Expand Down Expand Up @@ -389,7 +389,7 @@ private[ui] class StreamingPage(parent: StreamingTab)
"events/sec").toHtml(jsCollector)

<tr>
<td rowspan="2" style="vertical-align: middle;">
<td rowspan="2" style="vertical-align: middle; width: 193px;">
<div>
<strong>{receiverName}</strong>
</div>
Expand Down

0 comments on commit 4c0b43f

Please sign in to comment.