Related
I'm trying to have divs that, when moused over, change their background color, and being able to reset those colors. I've managed the former, but the latter is giving me issues.
As written, the divs do, in fact, change color, but attempting to press a key does not result in anything. I've also tried to put the resetColor function in the same block of Script, but doing so makes it so I can't even hover over and change the colors of those divs. As such, I'm wondering what I should do to be able to reset the divs' color?
function randomColor(element) {
var x = Math.floor(Math.random() * 256);
var y = Math.floor(Math.random() * 256);
var z = Math.floor(Math.random() * 256);
var bgColor = "rgb(" + x + "," + y + "," + z + ")";
console.log(bgColor);
element.backgroundColor = bgColor;
}
function resetColor(element) {
element.backgroundColor = '#ffff99';
}
body {
background-color: lightblue;
}
.colorCell {
border: 1px solid black;
width: 10px;
padding: 5px;
background-color: #ffff99;
border-radius: 0px;
}
<div class="colorCell" onmouseover="randomColor(this.style)" onkeydown="resetColor(this.style)">
<!--Successfullly changed color-->
<!--<a onmouseover="colorCell.body.style.backgroundColor = '#f39352'">-->
</div>
<div class="colorCell" onmouseover="randomColor(this.style)" onkeydown="resetColor(this.style)">
</div>
<div class="colorCell" onmouseover="randomColor(this.style)" onkeydown="resetColor(this.style)">
</div>
Check the fiddle: https://jsfiddle.net/ycn4zx9b/3/
HTML:
<div class="colorCell" onmouseover="randomColor(this)"></div>
<div class="colorCell" onmouseover="randomColor(this)"></div>
<div class="colorCell" onmouseover="randomColor(this)"></div>
CSS is still the same as you provided.
JS:
function randomColor(element) {
var x = Math.floor(Math.random() * 256);
var y = Math.floor(Math.random() * 256);
var z = Math.floor(Math.random() * 256);
var bgColor = "rgb(" + x + "," + y + "," + z + ")";
element.style.backgroundColor = bgColor;
element.classList.add(`reset-me`);
}
function resetColor(element) {
element.style.backgroundColor = '#ffff99';
}
window.onload = () => {
document.getElementsByTagName(`body`)[0].addEventListener(`keydown`, () => {
var itemss = document.querySelectorAll(`.reset-me`);
for (var i = 0; i < itemss.length; i++) {
resetColor(itemss[i]);
}
});
}
Keypress won't work on such elements on which you cannot enter something.
Make the event global instead and it should work.
an idea can be to :
add an event listener at document level
stored hovered cell
if one cell is over and keydown reset the celle style
let elementHovered = null;
function getRandomColor() {
return Math.floor(Math.random() * 256);
}
function randomColor(element) {
const bgColor = `rgb(${getRandomColor()}, ${getRandomColor()}, ${getRandomColor()})`;
console.log(bgColor);
element.backgroundColor = bgColor;
}
function resetColor(element) {
element.backgroundColor = '#ffff99';
}
[...document.querySelectorAll('.colorCell')].forEach(cell => {
cell.addEventListener('mouseover', () => {
elementHovered = event.target.style;
randomColor(elementHovered);
});
});
document.addEventListener('keydown', () => {
if (elementHovered) {
resetColor(elementHovered)
}
});
body {
background-color: lightblue;
}
.colorCell {
border: 1px solid black;
width: 10px;
padding: 5px;
background-color: #ffff99;
border-radius: 0px;
}
<div class="colorCell"></div>
<div class="colorCell"></div>
<div class="colorCell"></div>
So far i only can achieve to this point. I am using example code from w3school
I trying to figure out to get year in the same position like in the picture but no luck and also tried to insert image background for circle but only manage to color fill
/* The actual timeline (the vertical ruler) */
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
}
/* The actual timeline (the vertical ruler) */
.timeline::after {
content: ' ';
position: absolute;
width: 6px;
background-color: #ffc200;
top: 0;
bottom: 0;
left: 50%;
margin-left: -5px;
}
/* Container around content */
.contaiment {
padding: 10px 40px;
position: relative;
background-color: inherit;
width: 50%;
}
/* The circles on the timeline */
.contaiment::after {
content: '';
position: absolute;
width: 25px;
height: 25px;
right: -11px;
background-color: #ffc200;
border: 4px solid #ffc200;
top: 15px;
border-radius: 50%;
z-index: 1;
}
/* Place the container to the left */
.left {
left: 0;
}
/* Place the container to the right */
.right {
left: 50%;
}
/* Add arrows to the left container (pointing right) */
/* .left::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
right: 30px;
border: medium solid white;
border-width: 10px 0 10px 10px;
border-color: transparent transparent transparent white;
} */
/* Add arrows to the right container (pointing left) */
.right::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
left: 30px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
/* Fix the circle for containers on the right side */
.right::after {
left: -16px;
}
/* The actual content */
.content {
padding: 20px 30px;
background-color: white;
position: relative;
border-radius: 6px;
}
<div class="timeline">
<div class="contaiment left">
<div class="content">
<p>2017
<p>
<p>Lorem ipsum..</p>
</div>
</div>
<div class="contaiment right">
<div class="content">
<p class="">2017
<p>
<p>Lorem ipsum..</p>
</div>
</div>
<div class="contaiment left">
<div class="content">
<p class="">2017
<p>
<p>Lorem ipsum..</p>
</div>
</div>
</div>
I know you want to do something with only HTML and CSS, but take a look at this JQuery library. It's very easy to use.
https://github.com/musclesoft/jquery-connections/wiki/API
You just need to set the 2 elements you want to connect.
$("#div1, #div2").connections();
$("#div2, #div3").connections();
$("#div3, #div4").connections();
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
<title>Hello, world!</title>
</head>
<body>
<p style="width: 50px;height: 50px;border: 1px solid black;" id="div1">TEST</p>
<p style="width: 50px;height: 50px;margin-left: 50px;border: 1px solid black;" id="div2">TEST</p>
<p style="width: 50px;height: 50px;margin-left: 200px;border: 1px solid black;" id="div3">TEST</p>
<p style="width: 50px;height: 50px;margin-left: 300px;border: 1px solid black;" id="div4">TEST</p>
<!-- Script retrieved from https://raw.githubusercontent.com/musclesoft/jquery-connections/gh-pages/jquery.connections.js -->
<script>
(function($) {
$.fn.connections = function(options) {
if (options === "update") {
return processConnections(update, this);
} else if (options === "remove") {
return processConnections(destroy, this);
} else {
options = $.extend(
true,
{
borderClasses: {},
class: "connection",
css: {},
from: this,
tag: "connection",
to: this,
within: ":root"
},
options
);
connect(options);
return this;
}
};
$.event.special.connections = {
teardown: function(namespaces) {
processConnections(destroy, $(this));
}
};
var connect = function(options) {
var borderClasses = options.borderClasses;
var tag = options.tag;
var end1 = $(options.from);
var end2 = $(options.to);
var within = $(options.within);
delete options.borderClasses;
delete options.tag;
delete options.from;
delete options.to;
delete options.within;
within.each(function() {
var container = this;
var done = new Array();
end1.each(function() {
var node = this;
done.push(this);
end2.not(done).each(function() {
createConnection(
container,
[node, this],
tag,
borderClasses,
options
);
});
});
});
};
var createConnection = function(
container,
nodes,
tag,
borderClasses,
options
) {
var css = $.extend({ position: "absolute" }, options.css);
var connection = $("<" + tag + "/>", options).css(css);
connection.appendTo(container);
var border_w = (connection.outerWidth() - connection.innerWidth()) / 2;
var border_h = (connection.outerHeight() - connection.innerHeight()) / 2;
if (border_w <= 0 && border_h <= 0) {
border_w = border_h = 1;
}
var data = {
borderClasses: borderClasses,
border_h: border_h,
border_w: border_w,
node_from: $(nodes[0]),
node_to: $(nodes[1]),
nodes_dom: nodes,
css: css
};
if ("none" === connection.css("border-top-style")) {
data.css.borderStyle = "solid";
}
$.data(connection.get(0), "connection", data);
$.data(connection.get(0), "connections", [connection.get(0)]);
for (var i = 0; i < 2; i++) {
var connections = connection.add($.data(nodes[i], "connections")).get();
$.data(nodes[i], "connections", connections);
if (connections.length == 1) {
$(nodes[i]).on("connections.connections", false);
}
}
update(connection.get(0));
};
var destroy = function(connection) {
var nodes = $.data(connection, "connection").nodes_dom;
for (var i = 0; i < 2; i++) {
var connections = $($.data(nodes[i], "connections"))
.not(connection)
.get();
$.data(nodes[i], "connections", connections);
}
$(connection).remove();
};
var getState = function(data) {
data.rect_from = data.nodes_dom[0].getBoundingClientRect();
data.rect_to = data.nodes_dom[1].getBoundingClientRect();
var cached = data.cache;
data.cache = [
data.rect_from.top,
data.rect_from.right,
data.rect_from.bottom,
data.rect_from.left,
data.rect_to.top,
data.rect_to.right,
data.rect_to.bottom,
data.rect_to.left
];
data.hidden =
0 === (data.cache[0] | data.cache[1] | data.cache[2] | data.cache[3]) ||
0 === (data.cache[4] | data.cache[5] | data.cache[6] | data.cache[7]);
data.unmodified = true;
if (cached === undefined) {
return (data.unmodified = false);
}
for (var i = 0; i < 8; i++) {
if (cached[i] !== data.cache[i]) {
return (data.unmodified = false);
}
}
};
var update = function(connection) {
var data = $.data(connection, "connection");
getState(data);
if (data.unmodified) {
return;
}
var border_h = data.border_h;
var border_w = data.border_w;
var from = data.rect_from;
var to = data.rect_to;
var b = (from.bottom + from.top) / 2;
var r = (to.left + to.right) / 2;
var t = (to.bottom + to.top) / 2;
var l = (from.left + from.right) / 2;
var h = ["right", "left"];
if (l > r) {
h = ["left", "right"];
var x = Math.max(r - border_w / 2, Math.min(from.right, to.right));
r = l + border_w / 2;
l = x;
} else {
l -= border_w / 2;
r = Math.min(r + border_w / 2, Math.max(from.left, to.left));
}
var v = ["bottom", "top"];
if (t > b) {
v = ["top", "bottom"];
var x = Math.max(b - border_h / 2, Math.min(from.bottom, to.bottom));
b = t + border_h / 2;
t = x;
} else {
b = Math.min(b, Math.max(from.top, to.top));
t -= border_h / 2;
}
var width = r - l;
var height = b - t;
if (width < border_w) {
t = Math.max(t, Math.min(from.bottom, to.bottom));
b = Math.min(b, Math.max(from.top, to.top));
l = Math.max(from.left, to.left);
r = Math.min(from.right, to.right);
r = l = (l + r - border_w) / 2;
}
if (height < border_h) {
l = Math.max(l, Math.min(from.right, to.right));
r = Math.min(r, Math.max(from.left, to.left));
t = Math.max(from.top, to.top);
b = Math.min(from.bottom, to.bottom);
b = t = (t + b - border_h) / 2;
}
width = r - l;
height = b - t;
width <= 0 && (border_h = 0);
height <= 0 && (border_w = 0);
var style =
"border-" +
v[0] +
"-" +
h[0] +
"-radius: 0;" +
"border-" +
v[0] +
"-" +
h[1] +
"-radius: 0;" +
"border-" +
v[1] +
"-" +
h[0] +
"-radius: 0;";
(border_h <= 0 || border_w <= 0) &&
(style += "border-" + v[1] + "-" + h[1] + "-radius: 0;");
if (data.hidden) {
style += "display: none;";
} else {
data.css["border-" + v[0] + "-width"] = 0;
data.css["border-" + h[0] + "-width"] = 0;
data.css["border-" + v[1] + "-width"] = border_h;
data.css["border-" + h[1] + "-width"] = border_w;
var current_rect = connection.getBoundingClientRect();
data.css.left = connection.offsetLeft + l - current_rect.left;
data.css.top = connection.offsetTop + t - current_rect.top;
data.css.width = width - border_w;
data.css.height = height - border_h;
}
var bc = data.borderClasses;
$(connection)
.removeClass(bc[v[0]])
.removeClass(bc[h[0]])
.addClass(bc[v[1]])
.addClass(bc[h[1]])
.attr("style", style)
.css(data.css);
};
var processConnections = function(method, elements) {
return elements.each(function() {
var connections = $.data(this, "connections");
if (connections instanceof Array) {
for (var i = 0, len = connections.length; i < len; i++) {
method(connections[i]);
}
}
});
};
})(jQuery);
</script>
<script defer type="text/javascript">
$("#div1, #div2").connections();
$("#div2, #div3").connections();
$("#div3, #div4").connections();
</script>
</body>
</html>
On any given application, is there a way, maybe in dev tools where I can check the pixel location of my mouse hover?
Use javascript to get cursor location.
document.addEventListener("mouseover", function( event ) {
console.log(event.screenX, event.screenY);
}, false);
Getting the Mouse Click Position :
<!DOCTYPE html>
<html>
<head>
<title>Move to Click Position</title>
<style type="text/css">
body {
background-color: #FFF;
margin: 30px;
margin-top: 10px;
}
#contentContainer {
width: 550px;
height: 350px;
border: 5px black solid;
overflow: hidden;
background-color: #F2F2F2;
cursor: pointer;
}
#thing {
position: relative;
left: 50px;
top: 50px;
transition: left .5s ease-in, top .5s ease-in;
}
</style>
</head>
<body>
<div id="contentContainer">
<img id="thing" src="//www.kirupa.com/images/smiley_red.png">
</div>
<script src="//www.kirupa.com/prefixfree.min.js"></script>
<script>
var theThing = document.querySelector("#thing");
var container = document.querySelector("#contentContainer");
container.addEventListener("click", getClickPosition, false);
function getClickPosition(e) {
var parentPosition = getPosition(e.currentTarget);
var xPosition = e.clientX - parentPosition.x - (theThing.clientWidth / 2);
var yPosition = e.clientY - parentPosition.y - (theThing.clientHeight / 2);
theThing.style.left = xPosition + "px";
theThing.style.top = yPosition + "px";
}
// Helper function to get an element's exact position
function getPosition(el) {
var xPos = 0;
var yPos = 0;
while (el) {
if (el.tagName == "BODY") {
// deal with browser quirks with body/window/document and page scroll
var xScroll = el.scrollLeft || document.documentElement.scrollLeft;
var yScroll = el.scrollTop || document.documentElement.scrollTop;
xPos += (el.offsetLeft - xScroll + el.clientLeft);
yPos += (el.offsetTop - yScroll + el.clientTop);
} else {
// for all other non-BODY elements
xPos += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPos += (el.offsetTop - el.scrollTop + el.clientTop);
}
el = el.offsetParent;
}
return {
x: xPos,
y: yPos
};
}
</script>
</body>
</html>
Refer : MouseEvent clientX Property & Getting the Mouse Click Position
I have tried to enter a tooltip to explain the different payment methods offered to customers. However, I need the tooltip to stay open so the customer can mouseover the area to click a hyperlink. I also need the tooltip icon to be some for of question mark.
This is all I have so far...
<h6 class="right">Preferred Payment Method<span class="question">?</span></h6>
CSS for the question mark...
span.question {
cursor: pointer;
display: inline-block;
width: 16px;
height: 16px;
background-color: #89A4CC;
line-height: 16px;
color: White;
font-size: 13px;
font-weight: bold;
border-radius: 8px;
text-align: center;
position: relative;
}
span.question:hover {
background-color: #3D6199;
}
You'll need to use JavaScript to provide this functionality. Below is the minimal code that is used by Bootstrap to achieve this. Bootstrap Documentation :
/*!
* Bootstrap v3.3.5 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*!
* Generated using the Bootstrap Customizer (https://getbootstrap.com/customize/?id=009d6e1c8360baaa5978)
* Config saved to config.json and https://gist.github.com/009d6e1c8360baaa5978
*/
if (typeof jQuery === 'undefined') {
throw new Error('Bootstrap\'s JavaScript requires jQuery')
}
+function ($) {
'use strict';
var version = $.fn.jquery.split(' ')[0].split('.')
if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {
throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
}
}(jQuery);
/* ========================================================================
* Bootstrap: tooltip.js v3.3.6
* http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// TOOLTIP PUBLIC CLASS DEFINITION
// ===============================
var Tooltip = function (element, options) {
this.type = null
this.options = null
this.enabled = null
this.timeout = null
this.hoverState = null
this.$element = null
this.inState = null
this.init('tooltip', element, options)
}
Tooltip.VERSION = '3.3.6'
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = {
animation: true,
placement: 'top',
selector: false,
template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
trigger: 'hover focus',
title: '',
delay: 0,
html: false,
container: false,
viewport: {
selector: 'body',
padding: 0
}
}
Tooltip.prototype.init = function (type, element, options) {
this.enabled = true
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
this.inState = { click: false, hover: false, focus: false }
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
}
var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) {
var trigger = triggers[i]
if (trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
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 ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
Tooltip.prototype.getDefaults = function () {
return Tooltip.DEFAULTS
}
Tooltip.prototype.getOptions = function (options) {
options = $.extend({}, this.getDefaults(), this.$element.data(), options)
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay,
hide: options.delay
}
}
return options
}
Tooltip.prototype.getDelegateOptions = function () {
var options = {}
var defaults = this.getDefaults()
this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
})
return options
}
Tooltip.prototype.enter = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type)
if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
$(obj.currentTarget).data('bs.' + this.type, self)
}
if (obj instanceof $.Event) {
self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
}
if (self.tip().hasClass('in') || self.hoverState == 'in') {
self.hoverState = 'in'
return
}
clearTimeout(self.timeout)
self.hoverState = 'in'
if (!self.options.delay || !self.options.delay.show) return self.show()
self.timeout = setTimeout(function () {
if (self.hoverState == 'in') self.show()
}, self.options.delay.show)
}
Tooltip.prototype.isInStateTrue = function () {
for (var key in this.inState) {
if (this.inState[key]) return true
}
return false
}
Tooltip.prototype.leave = function (obj) {
var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type)
if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
$(obj.currentTarget).data('bs.' + this.type, self)
}
if (obj instanceof $.Event) {
self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
}
if (self.isInStateTrue()) return
clearTimeout(self.timeout)
self.hoverState = 'out'
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.timeout = setTimeout(function () {
if (self.hoverState == 'out') self.hide()
}, self.options.delay.hide)
}
Tooltip.prototype.show = function () {
var e = $.Event('show.bs.' + this.type)
if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
if (e.isDefaultPrevented() || !inDom) return
var that = this
var $tip = this.tip()
var tipId = this.getUID(this.type)
this.setContent()
$tip.attr('id', tipId)
this.$element.attr('aria-describedby', tipId)
if (this.options.animation) $tip.addClass('fade')
var placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
var autoToken = /\s?auto?\s?/i
var autoPlace = autoToken.test(placement)
if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
$tip
.detach()
.css({ top: 0, left: 0, display: 'block' })
.addClass(placement)
.data('bs.' + this.type, this)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
this.$element.trigger('inserted.bs.' + this.type)
var pos = this.getPosition()
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
if (autoPlace) {
var orgPlacement = placement
var viewportDim = this.getPosition(this.$viewport)
placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
placement
$tip
.removeClass(orgPlacement)
.addClass(placement)
}
var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
this.applyPlacement(calculatedOffset, placement)
var complete = function () {
var prevHoverState = that.hoverState
that.$element.trigger('shown.bs.' + that.type)
that.hoverState = null
if (prevHoverState == 'out') that.leave(that)
}
$.support.transition && this.$tip.hasClass('fade') ?
$tip
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete()
}
}
Tooltip.prototype.applyPlacement = function (offset, placement) {
var $tip = this.tip()
var width = $tip[0].offsetWidth
var height = $tip[0].offsetHeight
// manually read margins because getBoundingClientRect includes difference
var marginTop = parseInt($tip.css('margin-top'), 10)
var marginLeft = parseInt($tip.css('margin-left'), 10)
// we must check for NaN for ie 8/9
if (isNaN(marginTop)) marginTop = 0
if (isNaN(marginLeft)) marginLeft = 0
offset.top += marginTop
offset.left += marginLeft
// $.fn.offset doesn't round pixel values
// so we use setOffset directly with our own function B-0
$.offset.setOffset($tip[0], $.extend({
using: function (props) {
$tip.css({
top: Math.round(props.top),
left: Math.round(props.left)
})
}
}, offset), 0)
$tip.addClass('in')
// check to see if placing tip in new offset caused the tip to resize itself
var actualWidth = $tip[0].offsetWidth
var actualHeight = $tip[0].offsetHeight
if (placement == 'top' && actualHeight != height) {
offset.top = offset.top + height - actualHeight
}
var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
if (delta.left) offset.left += delta.left
else offset.top += delta.top
var isVertical = /top|bottom/.test(placement)
var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
$tip.offset(offset)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
}
Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
this.arrow()
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isVertical ? 'top' : 'left', '')
}
Tooltip.prototype.setContent = function () {
var $tip = this.tip()
var title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
}
Tooltip.prototype.hide = function (callback) {
var that = this
var $tip = $(this.$tip)
var e = $.Event('hide.bs.' + this.type)
function complete() {
if (that.hoverState != 'in') $tip.detach()
that.$element
.removeAttr('aria-describedby')
.trigger('hidden.bs.' + that.type)
callback && callback()
}
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$tip.removeClass('in')
$.support.transition && $tip.hasClass('fade') ?
$tip
.one('bsTransitionEnd', complete)
.emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete()
this.hoverState = null
return this
}
Tooltip.prototype.fixTitle = function () {
var $e = this.$element
if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
}
}
Tooltip.prototype.hasContent = function () {
return this.getTitle()
}
Tooltip.prototype.getPosition = function ($element) {
$element = $element || this.$element
var el = $element[0]
var isBody = el.tagName == 'BODY'
var elRect = el.getBoundingClientRect()
if (elRect.width == null) {
// width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
}
var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
return $.extend({}, elRect, scroll, outerDims, elOffset)
}
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
}
Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
var delta = { top: 0, left: 0 }
if (!this.$viewport) return delta
var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
var viewportDimensions = this.getPosition(this.$viewport)
if (/right|left/.test(placement)) {
var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
if (topEdgeOffset < viewportDimensions.top) { // top overflow
delta.top = viewportDimensions.top - topEdgeOffset
} else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
}
} else {
var leftEdgeOffset = pos.left - viewportPadding
var rightEdgeOffset = pos.left + viewportPadding + actualWidth
if (leftEdgeOffset < viewportDimensions.left) { // left overflow
delta.left = viewportDimensions.left - leftEdgeOffset
} else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
}
}
return delta
}
Tooltip.prototype.getTitle = function () {
var title
var $e = this.$element
var o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
Tooltip.prototype.getUID = function (prefix) {
do prefix += ~~(Math.random() * 1000000)
while (document.getElementById(prefix))
return prefix
}
Tooltip.prototype.tip = function () {
if (!this.$tip) {
this.$tip = $(this.options.template)
if (this.$tip.length != 1) {
throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
}
}
return this.$tip
}
Tooltip.prototype.arrow = function () {
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
}
Tooltip.prototype.enable = function () {
this.enabled = true
}
Tooltip.prototype.disable = function () {
this.enabled = false
}
Tooltip.prototype.toggleEnabled = function () {
this.enabled = !this.enabled
}
Tooltip.prototype.toggle = function (e) {
var self = this
if (e) {
self = $(e.currentTarget).data('bs.' + this.type)
if (!self) {
self = new this.constructor(e.currentTarget, this.getDelegateOptions())
$(e.currentTarget).data('bs.' + this.type, self)
}
}
if (e) {
self.inState.click = !self.inState.click
if (self.isInStateTrue()) self.enter(self)
else self.leave(self)
} else {
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
}
}
Tooltip.prototype.destroy = function () {
var that = this
clearTimeout(this.timeout)
this.hide(function () {
that.$element.off('.' + that.type).removeData('bs.' + that.type)
if (that.$tip) {
that.$tip.detach()
}
that.$tip = null
that.$arrow = null
that.$viewport = null
})
}
// TOOLTIP PLUGIN DEFINITION
// =========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option
if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
}
var old = $.fn.tooltip
$.fn.tooltip = Plugin
$.fn.tooltip.Constructor = Tooltip
// TOOLTIP NO CONFLICT
// ===================
$.fn.tooltip.noConflict = function () {
$.fn.tooltip = old
return this
}
}(jQuery);
/* ========================================================================
* Bootstrap: popover.js v3.3.6
* http://getbootstrap.com/javascript/#popovers
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// POPOVER PUBLIC CLASS DEFINITION
// ===============================
var Popover = function (element, options) {
this.init('popover', element, options)
}
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
Popover.VERSION = '3.3.6'
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right',
trigger: 'click',
content: '',
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
})
// NOTE: POPOVER EXTENDS tooltip.js
// ================================
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
Popover.prototype.constructor = Popover
Popover.prototype.getDefaults = function () {
return Popover.DEFAULTS
}
Popover.prototype.setContent = function () {
var $tip = this.tip()
var title = this.getTitle()
var content = this.getContent()
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
$tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
](content)
$tip.removeClass('fade top bottom left right in')
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
// this manually by checking the contents.
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
}
Popover.prototype.hasContent = function () {
return this.getTitle() || this.getContent()
}
Popover.prototype.getContent = function () {
var $e = this.$element
var o = this.options
return $e.attr('data-content')
|| (typeof o.content == 'function' ?
o.content.call($e[0]) :
o.content)
}
Popover.prototype.arrow = function () {
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
}
// POPOVER PLUGIN DEFINITION
// =========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.popover')
var options = typeof option == 'object' && option
if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
if (typeof option == 'string') data[option]()
})
}
var old = $.fn.popover
$.fn.popover = Plugin
$.fn.popover.Constructor = Popover
// POPOVER NO CONFLICT
// ===================
$.fn.popover.noConflict = function () {
$.fn.popover = old
return this
}
}(jQuery);
$(function () {
$('[data-toggle="popover"]').popover()
})
$('#example').popover({html:true})
.popover {
position: absolute;
top: 0;
left: 0;
z-index: 1060;
display: none;
max-width: 276px;
padding: 1px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-style: normal;
font-weight: normal;
letter-spacing: normal;
line-break: auto;
line-height: 1.42857143;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
font-size: 14px;
background-color: #ffffff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
.popover.top {
margin-top: -10px;
}
.popover.right {
margin-left: 10px;
}
.popover.bottom {
margin-top: 10px;
}
.popover.left {
margin-left: -10px;
}
.popover-title {
margin: 0;
padding: 8px 14px;
font-size: 14px;
background-color: #f7f7f7;
border-bottom: 1px solid #ebebeb;
border-radius: 5px 5px 0 0;
}
.popover-content {
padding: 9px 14px;
}
.popover > .arrow,
.popover > .arrow:after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.popover > .arrow {
border-width: 11px;
}
.popover > .arrow:after {
border-width: 10px;
content: "";
}
.popover.top > .arrow {
left: 50%;
margin-left: -11px;
border-bottom-width: 0;
border-top-color: #999999;
border-top-color: rgba(0, 0, 0, 0.25);
bottom: -11px;
}
.popover.top > .arrow:after {
content: " ";
bottom: 1px;
margin-left: -10px;
border-bottom-width: 0;
border-top-color: #ffffff;
}
.popover.right > .arrow {
top: 50%;
left: -11px;
margin-top: -11px;
border-left-width: 0;
border-right-color: #999999;
border-right-color: rgba(0, 0, 0, 0.25);
}
.popover.right > .arrow:after {
content: " ";
left: 1px;
bottom: -10px;
border-left-width: 0;
border-right-color: #ffffff;
}
.popover.bottom > .arrow {
left: 50%;
margin-left: -11px;
border-top-width: 0;
border-bottom-color: #999999;
border-bottom-color: rgba(0, 0, 0, 0.25);
top: -11px;
}
.popover.bottom > .arrow:after {
content: " ";
top: 1px;
margin-left: -10px;
border-top-width: 0;
border-bottom-color: #ffffff;
}
.popover.left > .arrow {
top: 50%;
right: -11px;
margin-top: -11px;
border-right-width: 0;
border-left-color: #999999;
border-left-color: rgba(0, 0, 0, 0.25);
}
.popover.left > .arrow:after {
content: " ";
right: 1px;
border-right-width: 0;
border-left-color: #ffffff;
bottom: -10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" id="example" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's <a href='#'>a link</a>. It's very engaging. Right?">Click to toggle popover</button>
You can do it with HTML/CSS, the following example might need a bit of styling and enhancements to markup but should achieve what you want.
HTML:
<a class="tooltip" href="">Tooltip</a>
<span>Tooltip with link</span>
CSS:
span {
position: relative;
width: 140px;
color: #fff;
background: #000;
visibility: hidden;
display: block;
left: 30px;
top: -15px;
padding: 25px;
opacity: .8;
}
a:hover + span,
span:hover {
visibility: visible;
z-index: 999;
}
http://codepen.io/williamjamesclark/pen/xZJJXb
I am using jmeter for performing load test on web site. And Jmeter generates output in form of CSV file.
I want to generate bar graph using this CSV file. For generating graph i am using D3 and Crossfilter.
For this i have referred http://square.github.io/crossfilter/ and used same code by editing as per my CSV file requirement.
It shows Following error :-
Error: Problem parsing d="M230,100V50h9V100MNaN,100V0h9V100" index.html:1
2
Error: Problem parsing d="M230,100V100h9V100MNaN,100V100h9V100" d3.v3.min.js:1
46
Error: Problem parsing d="M230,100V100h9V100MNaN,100V100h9V100" d3.v3.min.js:1
114
Error: Problem parsing d="M230,100V100h9V100MNaN,100V0h9V100" d3.v3.min.js:1
30
My CSV File is:
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,grpThreads,allThreads,Latency,Hostname
12/25/2012 0:02,2417,/ratings/rate.php,200,OK,Thread Group 1-1,text,TRUE,1067,1,1,2417,PRAVIN-PC
12/25/2012 0:02,3784,/ratings/rate.php,200,OK,Thread Group 1-1,text,TRUE,913,1,1,3783,PRAVIN-PC
12/25/2012 0:12,3121,/gampad/ads,200,OK,Thread Group 1-1,text,TRUE,1214,1,1,3121,PRAVIN-PC
`
And my HTML file code is:
<style>
body {
font-family: "Helvetica Neue";
margin: 40px auto;
width: 960px;
min-height: 2000px;
}
#body {
position: relative;
}
footer {
padding: 2em 0 1em 0;
font-size: 12px;
}
h1 {
font-size: 96px;
margin-top: .3em;
margin-bottom: 0;
}
h1 + h2 {
margin-top: 0;
}
h2 {
font-weight: 400;
font-size: 28px;
}
h1, h2 {
font-family: "Yanone Kaffeesatz";
text-rendering: optimizeLegibility;
}
#body > p {
line-height: 1.5em;
width: 640px;
text-rendering: optimizeLegibility;
}
#charts {
padding: 10px 0;
}
.chart {
display: inline-block;
height: 151px;
margin-bottom: 20px;
}
.reset {
padding-left: 1em;
font-size: smaller;
color: #ccc;
}
.background.bar {
fill: #ccc;
}
.foreground.bar {
fill: steelblue;
}
.axis path, .axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text {
font: 10px sans-serif;
}
.brush rect.extent {
fill: steelblue;
fill-opacity: .125;
}
.brush .resize path {
fill: #eee;
stroke: #666;
}
#hour-chart {
width: 260px;
}
#delay-chart {
width: 230px;
}
#distance-chart {
width: 420px;
}
#date-chart {
width: 920px;
}
#flight-list {
min-height: 1024px;
}
#flight-list .date,
#flight-list .day {
margin-bottom: .4em;
}
#flight-list .flight {
line-height: 1.5em;
background: #eee;
width: 640px;
margin-bottom: 1px;
}
#flight-list .time {
color: #999;
}
#flight-list .flight div {
display: inline-block;
width: 100px;
}
#flight-list div.distance,
#flight-list div.delay {
width: 160px;
padding-right: 10px;
text-align: right;
}
#flight-list .early {
color: green;
}
aside {
position: absolute;
left: 740px;
font-size: smaller;
width: 220px;
}
</style>
<div id="body">
<div id="charts">
<div id="hour-chart" class="chart">
<div class="title">Time of Day</div>
</div></br>
<div id="delay-chart" class="chart">
<div class="title">Page Load Time (ms.)</div>
</div>
<!-- <div id="distance-chart" class="chart">
<div class="title">Visit Time (mi.)</div>
</div>
<div id="date-chart" class="chart">
<div class="title">Date</div>
</div>-->
</div>
<aside id="totals"><span id="active">-</span> of <span id="total">-</span> Visits selected.</aside>
<div id="lists">
<div id="flight-list" class="list"></div>
</div>
<footer>
<span style="float:right;">
Released under the Apache License 2.0.
</span>
Copyright 2012 Square, Inc.
</footer>
</div>
<script src="crossfilter.min.js"></script>
<script src="d3.v3.min.js"></script>
<script>
// (It's CSV, but GitHub Pages only gzip's JSON at the moment.)
d3.csv("resultofcommandline.csv", function(flights) {
// A nest operator, for grouping the flight list.
var nestByDate = d3.nest()
.key(function(d) { return d3.time.day(d.date); });
// A little coercion, since the CSV is untyped.
flights.forEach(function(d, i) {
d.index = i;
d.timeStamp = parseDate(d.timeStamp);
d.Latency = +d.Latency;
});
// Create the crossfilter for the relevant dimensions and groups.
var flight = crossfilter(flights),
all = flight.groupAll(),
hour = flight.dimension(function(d) { return d.timeStamp.getHours() + d.timeStamp.getMinutes() / 60; }),
hours = hour.group(Math.floor),
latency = flight.dimension(function(d) {return Math.min(1999, d.Latency);}),
latencys = latency.group(function (d){ return Math.floor(d/50)*50 ;});
var charts = [
barChart()
.dimension(latency)
.group(latencys)
.x(d3.scale.linear()
.domain([0, 2000])
.rangeRound([0, 10 * 40])),
barChart()
.dimension(hour)
.group(hours)
.x(d3.scale.linear()
.domain([0, 24])
.rangeRound([0, 10 * 24]))
];
// Given our array of charts, which we assume are in the same order as the
// .chart elements in the DOM, bind the charts to the DOM and render them.
// We also listen to the chart's brush events to update the display.
var chart = d3.selectAll(".chart")
.data(charts)
.each(function(chart) { chart.on("brush", renderAll).on("brushend", renderAll); });
renderAll();
// Renders the specified chart or list.
function render(method) {
d3.select(this).call(method);
}
// Whenever the brush moves, re-rendering everything.
function renderAll() {
chart.each(render);
}
// Like d3.time.format, but faster.
function parseDate(d) {
return new Date(d.substring(6,10),
d.substring(0, 2) - 1,
d.substring(3, 5),
d.substring(11, 13),
d.substring(14, 16));
}
window.filter = function(filters) {
filters.forEach(function(d, i) { charts[i].filter(d); });
renderAll();
};
window.reset = function(i) {
charts[i].filter(null);
renderAll();
};
function barChart() {
if (!barChart.id) barChart.id = 0;
var margin = {top: 10, right: 10, bottom: 20, left: 10},
x,
y = d3.scale.linear().range([100, 0]),
id = barChart.id++,
axis = d3.svg.axis().orient("bottom"),
brush = d3.svg.brush(),
brushDirty,
dimension,
group,
round;
function chart(div) {
var width = x.range()[1],
height = y.range()[0];
y.domain([0, group.top(1)[0].value]);
div.each(function() {
var div = d3.select(this),
g = div.select("g");
// Create the skeletal chart.
if (g.empty()) {
div.select(".title").append("a")
.attr("href", "javascript:reset(" + id + ")")
.attr("class", "reset")
.text("reset")
.style("display", "none");
g = div.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("clipPath")
.attr("id", "clip-" + id)
.append("rect")
.attr("width", width)
.attr("height", height);
g.selectAll(".bar")
.data(["background", "foreground"])
.enter().append("path")
.attr("class", function(d) { return d + " bar"; })
.datum(group.all());
g.selectAll(".foreground.bar")
.attr("clip-path", "url(#clip-" + id + ")");
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(axis);
// Initialize the brush component with pretty resize handles.
var gBrush = g.append("g").attr("class", "brush").call(brush);
gBrush.selectAll("rect").attr("height", height);
gBrush.selectAll(".resize").append("path").attr("d", resizePath);
}
// Only redraw the brush if set externally.
if (brushDirty) {
brushDirty = false;
g.selectAll(".brush").call(brush);
div.select(".title a").style("display", brush.empty() ? "none" : null);
if (brush.empty()) {
g.selectAll("#clip-" + id + " rect")
.attr("x", 0)
.attr("width", width);
}
else {
var extent = brush.extent();
g.selectAll("#clip-" + id + " rect")
.attr("x", x(extent[0]))
.attr("width", x(extent[1]) - x(extent[0]));
}
}
g.selectAll(".bar").attr("d", barPath);
});
function barPath(groups) {
var path = [],
i = -1,
n = groups.length,
d;
while (++i < n) {
d = groups[i];
path.push("M", x(d.key), ",", height, "V", y(d.value), "h9V", height);
}
return path.join("");
}
function resizePath(d) {
var e = +(d == "e"),
x = e ? 1 : -1,
y = height / 3;
return "M" + (.5 * x) + "," + y
+ "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6)
+ "V" + (2 * y - 6)
+ "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y)
+ "Z"
+ "M" + (2.5 * x) + "," + (y + 8)
+ "V" + (2 * y - 8)
+ "M" + (4.5 * x) + "," + (y + 8)
+ "V" + (2 * y - 8);
}
}
brush.on("brushstart.chart", function() {
var div = d3.select(this.parentNode.parentNode.parentNode);
div.select(".title a").style("display", null);
});
brush.on("brush.chart", function() {
var g = d3.select(this.parentNode),
extent = brush.extent();
if (round) g.select(".brush")
.call(brush.extent(extent = extent.map(round)))
.selectAll(".resize")
.style("display", null);
g.select("#clip-" + id + " rect")
.attr("x", x(extent[0]))
.attr("width", x(extent[1]) - x(extent[0]));
dimension.filterRange(extent);
});
brush.on("brushend.chart", function() {
if (brush.empty()) {
var div = d3.select(this.parentNode.parentNode.parentNode);
div.select(".title a").style("display", "none");
div.select("#clip-" + id + " rect").attr("x", null).attr("width", "100%");
dimension.filterAll();
}
});
chart.margin = function(_) {
if (!arguments.length) return margin;
margin = _;
return chart;
};
chart.x = function(_) {
if (!arguments.length) return x;
x = _;
axis.scale(x);
brush.x(x);
return chart;
};
chart.y = function(_) {
if (!arguments.length) return y;
y = _;
return chart;
};
chart.dimension = function(_) {
if (!arguments.length) return dimension;
dimension = _;
return chart;
};
chart.filter = function(_) {
if (_) {
brush.extent(_);
dimension.filterRange(_);
} else {
brush.clear();
dimension.filterAll();
}
brushDirty = true;
return chart;
};
chart.group = function(_) {
if (!arguments.length) return group;
group = _;
return chart;
};
chart.round = function(_) {
if (!arguments.length) return round;
round = _;
return chart;
};
return d3.rebind(chart, brush, "on");
}
});
</script>
The problem is that your parseDate() function assumes a hh:mm time format, but your data contains h:mm entries.
So you would have to either change the format of your input data, or adapt the parsing function.
I changed the 3 sample rows you gave, see the working sample here!