Built with blockbuilder.org
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: #00acf8;
}
.bar:hover {
fill: #acacac;
}
.x.axis path {
display: none;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.4);
color: #fff;
border-radius: 20px;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: #ababab;
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
.line{
fill: none;
stroke: blue;
stroke-width: 2px;
}
.tick text{
font-size: 12px;
}
.tick line{
opacity: 0.1;
}
</style>
<body>
<div id="chart"></div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
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)
}
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
}
tip.hide = function() {
nodel = d3.select(node)
nodel.style({ opacity: 0, 'pointer-events': 'none' })
return tip
}
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
}
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
}
tip.direction = function(v) {
if (!arguments.length) return direction
direction = v == null ? v : d3.functor(v)
return tip
}
tip.offset = function(v) {
if (!arguments.length) return offset
offset = v == null ? v : d3.functor(v)
return 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
};
var data = [
{
"letter": "A",
"frequency": 0.08167
},
{
"letter": "B",
"frequency": 0.01492
},
{
"letter": "C",
"frequency": 0.02782
},
{
"letter": "D",
"frequency": 0.04253
},
{
"letter": "E",
"frequency": 0.12702
},
{
"letter": "F",
"frequency": 0.02288
},
{
"letter": "G",
"frequency": 0.02015
},
{
"letter": "H",
"frequency": 0.06094
},
{
"letter": "I",
"frequency": 0.06966
},
{
"letter": "J",
"frequency": 0.00153
},
{
"letter": "K",
"frequency": 0.00772
},
{
"letter": "L",
"frequency": 0.04025
},
{
"letter": "M",
"frequency": 0.02406
},
{
"letter": "N",
"frequency": 0.06749
},
{
"letter": "O",
"frequency": 0.07507
},
{
"letter": "P",
"frequency": 0.01929
},
{
"letter": "Q",
"frequency": 0.00095
},
{
"letter": "R",
"frequency": 0.05987
},
{
"letter": "S",
"frequency": 0.06327
},
{
"letter": "T",
"frequency": 0.09056
},
{
"letter": "U",
"frequency": 0.02758
},
{
"letter": "V",
"frequency": 0.00978
},
{
"letter": "W",
"frequency": 0.0236
},
{
"letter": "X",
"frequency": 0.0015
},
{
"letter": "Y",
"frequency": 0.01974
},
{
"letter": "Z",
"frequency": 0.00074
}
];
var container = document.getElementById("chart");
// Mike Bostock "margin conventions"
var margin = {top: 20, right: 20, bottom: 40, left: 40},
width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.top - margin.bottom;
var formatPercent = d3.format(".0%");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Frequency:</strong> <span style='color:#00acf8'>" + d.frequency + "</span>";
})
// the final line sets the transform on <g>, not on <svg>
var svg = d3.select("#chart").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 + ")");
svg.call(tip);
svg
.append("g")
.append("text") // just for the title (ticks are automatic)
.attr("class", "y label")
.attr("transform", "rotate(-90)") // rotate the text!
.attr("y", -30)
.style("text-anchor", "end")
.text("Frequency");
//d3.tsv("data.tsv", type, function(error, data) {
beforeResizeDraw(data);
window.addEventListener("resize", function() {
resizeDraw(data);
});
//});
function type(d) {
// + coerces to a Number from a String (or anything)
d.frequency = +d.frequency;
return d;
}
function createBarAxis() {
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
// grid case
.innerTickSize(height)
.outerTickSize(0)
.tickPadding(10);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(formatPercent)
// grid case
.innerTickSize(-width)
.outerTickSize(0)
.tickPadding(10);
svg.call(tip);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0,0)");
svg.append("g")
.attr("class", "y axis");
svg.select(".x.axis")
.attr("transform", "translate(0,0)")
.call(xAxis);
svg.select(".y.axis")
.call(yAxis);
}
function beforeResizeDraw(data) {
d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
x.domain(data.map(function(d) { return d.letter; }));
y.range([height, 0])
.domain([0, d3.max(data, function(d) { return d.frequency; })]);
// THIS IS THE ACTUAL WORK!
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
// .on("mouseover", function(){
// // move to front
// this.parentNode.appendChild(this);
// })
// $( ".bar" ).on('mouseout' function() {
// // Handler for .load() called.
// this.parentNode.appendChild(this);
// });
// D3 Axis - renders a d3 scale in SVG
createBarAxis();
}
function resizeDraw(data) {
width = window.innerWidth - margin.left - margin.right;
height = window.innerHeight - margin.top - margin.bottom;
d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
x.rangeRoundBands([0, width], .1)
.domain(data.map(function(d) { return d.letter; }));
y.range([height, 0])
.domain([0, d3.max(data, function(d) { return d.frequency; })]);
// THIS IS THE ACTUAL WORK!
var bars = svg.selectAll(".bar")
.data(data, function(d) { return d.letter; });
// data that needs DOM = enter() (a set/selection, not an event!)
bars.enter().append("rect")
.attr("class", "bar");
bars.exit()
.transition()
.duration(300)
.attr("y", y(0))
.attr("height", height - y(0))
.style('fill-opacity', 1e-6)
.remove();
// the "UPDATE" set:
bars
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
// D3 Axis - renders a d3 scale in SVG
createBarAxis();
}
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://code.jquery.com/jquery-1.12.4.min.js