Skip to content

Instantly share code, notes, and snippets.

@bytesbysophie
Last active October 20, 2018 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bytesbysophie/0311395c1e082f98e67efaf2c7f9555b to your computer and use it in GitHub Desktop.
Save bytesbysophie/0311395c1e082f98e67efaf2c7f9555b to your computer and use it in GitHub Desktop.
Box Plot | tooltip | d3 v5
license: mit

d3-tip.js
This block shows d3-tip being used with D3.js version 5.
The version of d3-tip used in this example can be obtained from VACLab/d3-tip on GitHub.
VACLab/d3-tip is licensed under the Apache License 2.0.

data
The used source data.js contains randomly generated data.

// d3.tip
// Copyright (c) 2013 Justin Palmer
// ES6 / D3 v4 Adaption Copyright (c) 2016 Constantin Gavrilete
// Removal of ES6 for D3 v4 Adaption Copyright (c) 2016 David Gotz
//
// Tooltips for d3.js SVG visualizations
d3.functor = function functor(v) {
return typeof v === "function" ? v : function() {
return v;
};
};
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 = getNodeEl(),
i = directions.length,
coords,
scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
nodel.html(content)
.style('position', 'absolute')
.style('opacity', 1)
.style('pointer-events', 'all')
while(i--) nodel.classed(directions[i], false)
coords = direction_callbacks[dir].apply(this)
nodel.classed(dir, true)
.style('top', (coords.top + poffset[0]) + scrollTop + 'px')
.style('left', (coords.left + poffset[1]) + scrollLeft + 'px')
return tip
}
// Public - hide the tooltip
//
// Returns a tip
tip.hide = function() {
var nodel = getNodeEl()
nodel
.style('opacity', 0)
.style('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 getNodeEl().attr(n)
} else {
var args = Array.prototype.slice.call(arguments)
d3.selection.prototype.attr.apply(getNodeEl(), 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) {
// debugger;
if (arguments.length < 2 && typeof n === 'string') {
return getNodeEl().style(n)
} else {
var args = Array.prototype.slice.call(arguments);
if (args.length === 1) {
var styles = args[0];
Object.keys(styles).forEach(function(key) {
return d3.selection.prototype.style.apply(getNodeEl(), [key, styles[key]]);
});
}
}
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
}
// Public: destroys the tooltip and removes it from the DOM
//
// Returns a tip
tip.destroy = function() {
if(node) {
getNodeEl().remove();
node = null;
}
return tip;
}
function d3_tip_direction() { return 'n' }
function d3_tip_offset() { return [0, 0] }
function d3_tip_html() { return ' ' }
var direction_callbacks = {
n: direction_n,
s: direction_s,
e: direction_e,
w: direction_w,
nw: direction_nw,
ne: direction_ne,
sw: direction_sw,
se: direction_se
};
var directions = Object.keys(direction_callbacks);
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')
.style('top', '0')
.style('opacity', '0')
.style('pointer-events', 'none')
.style('box-sizing', 'border-box')
return node.node()
}
function getSVGNode(el) {
el = el.node()
if(el.tagName.toLowerCase() === 'svg')
return el
return el.ownerSVGElement
}
function getNodeEl() {
if(node === null) {
node = initNode();
// re-add node to DOM
document.body.appendChild(node);
};
return d3.select(node);
}
// 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;
while ('undefined' === typeof targetel.getScreenCTM && 'undefined' === targetel.parentNode) {
targetel = targetel.parentNode;
}
var bbox = {},
matrix = targetel.getScreenCTM(),
tbbox = targetel.getBBox(),
width = tbbox.width,
height = tbbox.height,
x = tbbox.x,
y = tbbox.y
point.x = x
point.y = y
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
};
{
"data group 1": [
0.5352900069984017,
-1.7791024927620143,
0.9150982182884015,
0.9238065955967064,
0.2462548726505484,
1.925606875216743,
-0.615514056084244,
0.9616318322394037,
2.4227145176133753,
0.6620101619724866,
-0.8001134933853573,
-1.186840375987921,
0.2131392597622092,
1.7979811077182768,
-0.4299145291311903,
0.8246577866883834,
0.8743418613995311,
0.20565162183766866,
0.11748713859229176,
0.6026624831668027,
-0.258498579144279,
-0.5848122860329406,
-1.84400519581359,
2.4457260298891406,
-0.18682836072510833,
1.1786764683793072,
1.0377785980858891,
1.3051229576852594,
0.37535447314803394,
-0.7596330282346193,
0.6036740008090407,
-1.3121123322156698,
-0.05398330759896386,
-0.028268311565498416,
0.19086915222878964,
0.10421998399190202,
0.1667969209239809,
0.2084361025196257,
-0.6467269237974553,
1.0178280344977715,
0.9114772393844865,
1.6985368093447744,
-1.4184708173114533,
-0.6065967763872702,
-0.4493811148190643,
0.3092234438020506,
0.565033633832378,
0.6987316814881362,
0.1678201004107054,
-0.25302428208925754,
0.19047924993698168,
-0.13636805380751948,
-1.6685871096633385,
-0.21057884846851782,
-0.5431361126923304,
0.9694328981725038,
1.4840130934840894,
1.1382381179181191,
0.09397475081547318,
0.1351941971369391,
-0.42028664382908365,
0.4920202662146399,
1.8131811608547663,
-1.6753199656438498,
0.5260728652461457,
-0.9278470423303935,
0.7219055826251612,
0.37967858981068775,
2.873860131065224,
0.08504691535481612,
0.9964951467584278,
0.9575571210481588,
0.47914213128217736,
0.12732630238368742,
2.7044450737577286,
0.04995536677587625,
-0.6471413104605377,
1.7148288006288748,
-1.5317251233257907,
0.6785614892781668,
-0.8140550288337298,
1.3615478310810674,
-0.34062056744306224,
0.4985663389197543,
1.005190501780555,
0.08985778410393319,
0.46181073566109954,
0.8169625341375543,
1.1014945989194582,
-0.7043541533640081,
2.3440085601825915,
-1.1059524452111686,
1.7703350907984046,
0.4399582772310596,
-0.6436664643306387,
1.4090089971561608,
2.612878060777795,
0.528746369757118,
0.34635870907903155,
-0.5134507134457014
],
"data group 2": [
10.009434810213735,
8.74764784762182,
9.209507325581297,
8.309717788770522,
10.51850417893284,
7.7493582001246555,
9.277390317430163,
11.045703346495845,
9.920362679473216,
10.70026442933519,
9.49022800319164,
9.681408132462698,
10.436311961267526,
10.482639123990383,
9.965573364826547,
7.792547226261525,
9.884243165958603,
9.350533084124555,
8.963096675324472,
10.839155535800668,
8.89716953536752,
7.3147746360756045,
9.744933039189727,
7.516929331906158,
8.375042038282162,
9.922114574703137,
9.766198135907143,
10.716399520128736,
8.854736693181628,
9.007128405946817,
8.653672424226722,
10.431266485268639,
10.300814360035073,
7.888645292147463,
9.368081309918871,
10.009136596299992,
11.704185052235719,
7.618530454176458,
9.516628738553255,
9.564217057488163,
10.219919629712512,
9.117521158210499,
10.122537182760123,
9.987795166606492,
8.486808770544881,
9.047642941201218,
9.51665379501418,
10.952539447964421,
9.0971450964464,
8.167589539653372,
9.474088259266235,
9.346540954254902,
11.62579796952127,
9.848584920085523,
11.661664375508723,
8.428934364616051,
9.522534484667908,
10.039704679556221,
11.70489911806213,
9.442107754514996,
8.710197621682692,
8.87010074216731,
9.405626993190154,
8.276997713596344,
9.609543440373491,
10.08519565028156,
11.296123843791575,
7.951204837505156,
8.896890064190874,
8.343677871033302,
11.120085310968252,
10.70982327440251,
10.181765523844742,
7.930643386277678,
8.773474893164963,
8.434102074781016,
8.565741152325948,
8.621182598718677,
9.580164757207653,
8.810430516938046,
8.741995646560806,
9.510879775721964,
7.825371092042257,
11.767612375854288,
9.699026099824817,
9.296892018877498,
8.790306113981611,
10.13140466071075,
8.935729134184049,
9.008435548072015,
8.923045501300424,
8.19442539300722,
9.687260030166708,
9.435222469450455,
8.225906627108552,
10.470936419929723,
9.72063034539787,
10.346386663884424,
7.3782127956453465,
9.242166746014698
],
"data group 3": [
7.603646818367262,
6.998213619847963,
6.793594463451299,
5.309299587179453,
4.542307567464604,
6.980029227817457,
6.255562322133557,
8.775909667007804,
6.469855046721744,
7.865317018229417,
8.825104394377757,
5.462233413262513,
7.398580058292482,
6.1198800067162455,
6.596437822112686,
5.644814654676587,
8.110040073370131,
7.357465834153866,
5.43793148884452,
7.170507588819066,
7.934025196413,
7.187285316371485,
6.915063845938751,
6.045872357962081,
7.135881775926692,
6.971916978927261,
5.819484947737589,
8.176611519805423,
5.292060645071514,
7.362371264649148,
5.842345547218573,
6.600069000346167,
5.23179512848575,
8.66979509886349,
6.888602564995485,
5.800513011326471,
5.891361408139966,
6.887919088372138,
7.541051189120404,
6.337500118171134,
7.580133886403563,
7.109770080824818,
9.336829519181656,
7.036043771476552,
6.755745481290967,
6.261876023963954,
7.129271040596288,
6.490319345875473,
7.093043627445697,
7.042342171561739,
8.042020742667384,
5.865282498949545,
7.392840542938162,
6.028058408389408,
6.648460856381471,
6.717808448300772,
7.1151361640010204,
7.17586671750052,
7.92684718343876,
6.545163312341261,
5.157988474064794,
6.854123169750357,
6.142939763297752,
6.798926324201765,
7.01856026164799,
7.569922420776862,
6.371375133883351,
6.413112651972197,
6.867306169168018,
6.967842159069824,
7.436073272036745,
5.9744714166194735,
6.683873241635285,
5.90517368075599,
7.812578731080231,
6.276265296482206,
6.253587923503021,
6.3973072561743525,
5.432190262636849,
7.02268000749249,
8.997864045637874,
6.7709544213025845,
6.686723435604992,
9.95754507927897,
6.589166668350852,
6.865653748005097,
9.542590132132354,
6.5856610892455905,
6.348013882045972,
5.862062505604868,
7.375680638439379,
5.226323729852715,
8.242876163427033,
5.984569726775165,
7.871462457842013,
6.992072730416628,
7.037606080846123,
7.519507268051527,
7.005367182520205,
7.090260651996964
],
"data group 4": [
6.926782493983623,
8.613551776901826,
8.671792603640089,
6.133810353779647,
7.436394658896131,
7.53355142537482,
8.363351119089389,
7.848603290932221,
7.611489907063506,
7.384989529161147,
6.897911787560112,
7.711823883608307,
6.359426401401347,
6.334971996903791,
8.390015391624548,
6.055386475998729,
7.308120489884073,
7.7101009549708985,
6.646643218685584,
7.023035018220515,
6.530518826968296,
7.322123810826516,
7.894712506560873,
7.5751057858691,
7.268396013258467,
7.674369569604295,
7.328501302197636,
7.363559778776676,
6.45508036555545,
7.473116684249696,
8.8453839112703,
6.637293226267234,
9.083603681575642,
9.668252995448453,
6.928689987676712,
7.239224616449231,
7.0487071327171495,
9.090395438222355,
8.096612260469136,
8.161982772097824,
8.177468234287861,
7.5577298287833825,
6.175508759112709,
8.345919018161043,
7.862924510192702,
8.530250674210874,
9.206155237063644,
8.511568592139778,
7.115683271321487,
6.348807191641107,
8.536920524723314,
7.579593668643209,
6.8646221161888725,
6.6772851305501515,
10.693364502320719,
7.817329395226933,
7.926182640200274,
8.262777434659213,
6.722264449169457,
6.7662872056287835,
7.431253410230147,
7.4885439963271345,
6.883684490232997,
7.193276783530206,
7.9671665707974375,
8.93726798775889,
7.6169536843805945,
7.298835337991046,
7.8456833103165495,
7.052162241671699,
7.614125967627774,
7.032553689927149,
8.956641132178055,
7.325464699617329,
8.285228767716674,
7.248203547104875,
9.173919751713473,
6.46778067842225,
6.74126518792102,
6.577932570359732,
8.370178700160647,
5.856861084254266,
8.203363324895856,
7.545397927134594,
6.961984873879911,
8.331472714781434,
7.709376301738583,
7.230049543257685,
7.179804778732678,
6.9161191965458855,
8.007147268292496,
7.434074482519087,
8.418110078531154,
6.091925469392365,
7.949291518496794,
7.321400150472493,
8.183202071780128,
8.00255135340456,
5.738723029826328,
7.825028533274028
],
"data group 5": [
7.637571243650436,
8.315549147929108,
7.3852076392844355,
8.406838189953906,
7.225526138512589,
9.072721438651703,
7.738620725702385,
8.126054009949506,
7.725759039434883,
6.7089859532136025,
8.629918492292866,
8.99100124730357,
7.53364071889497,
8.047146315171167,
7.29547577641902,
8.262164990586122,
7.679396600549858,
7.968536042524583,
7.28651386951744,
9.461139530810776,
7.371481272239612,
6.973974888156473,
5.957840187852257,
9.08046544627657,
9.978901531995053,
7.824520928895755,
8.03225484266987,
9.887343764893709,
9.489079745679634,
6.422132631894839,
8.045427591815933,
8.85690092834047,
7.744025843581954,
8.828738262241878,
8.989036410918525,
6.672709044977017,
8.175014275053222,
7.905829862885067,
7.227302142418971,
8.456299838667812,
8.732872133512787,
8.866753754156777,
7.714333203677158,
8.948320698293188,
8.410750133254242,
6.309086582576759,
7.5207415138956115,
8.75978574597703,
9.370867209180817,
7.447645659433421,
7.788167881212251,
7.525933363843692,
6.436666558023981,
7.1366940167937205,
7.890727084687808,
9.52534753786879,
6.897777750785976,
7.292180306134491,
7.359432989714596,
8.522622394653267,
9.125265414689514,
9.600066080354484,
7.827954228985638,
7.415073910415694,
9.089465572458936,
8.412428660472163,
8.959710066645176,
8.471220379832527,
8.773583528950068,
8.23289848480224,
8.569216290536685,
8.677394365820335,
8.066701257525906,
5.200053163427379,
8.156826953826117,
8.142747721522598,
8.923086055827252,
9.793591471703332,
6.921135468637114,
7.684458498169077,
6.777287981116281,
9.26354117750806,
7.779312142857344,
7.256539785176265,
8.014600195673877,
8.934294424178624,
9.077926594635024,
6.929421982034034,
8.012869638682648,
7.775793481803919,
5.826623582661358,
7.997879957872042,
6.840512156822008,
9.968867028438785,
8.509139942447373,
9.316300582327266,
7.326136648356018,
9.912664412418467,
7.792290311264319,
7.70956890642871
],
"data group 6": [
1.1145537007051596,
0.14503625388552244,
-1.408049544415145,
0.36765601268517734,
0.9030122948569815,
1.527795556197602,
0.23762613363326957,
-1.4747997616582695,
-0.9507101401845559,
-1.8371790748161412,
1.0365618935665872,
0.5947663273951291,
1.4242916574883768,
0.10449541915149488,
1.8084172972175014,
1.1550388085516305,
-1.1724890935463346,
1.268366822866595,
0.1550438548214329,
-0.4870071291735968,
-1.1365811370825847,
-1.2704963115176084,
-1.8712979550866362,
-1.0242659043849882,
-0.8088661599652861,
0.39054334069632773,
-0.5387423490779397,
0.41764722610094024,
0.4575098554273514,
-0.2591682858093046,
0.1433009400848337,
-2.1289108870149835,
0.33416125726563706,
1.277496382250138,
2.420152885905934,
-0.20878121507419806,
0.38240119394628996,
-2.178006124230347,
1.9143098491981165,
0.4288767397907326,
-1.0005709294976508,
0.6154634968736986,
1.4820669984829642,
-0.7203762059133149,
-1.459277254498355,
1.6459767518060302,
-0.2248758500774592,
0.14640397193316096,
-0.461572241101451,
0.5250431356679102,
0.40284914442476566,
0.7809290250077096,
-0.5401334813608805,
-0.9085115048057832,
-1.7096975716162222,
2.1482850417141517,
-1.6791012692612166,
-0.9389011238720162,
-0.6373036311789666,
0.8881828631728712,
0.9930354821965369,
0.9331538245909031,
2.524478064861906,
0.17191282600288033,
-1.2976157392957732,
-1.075317792715837,
0.886495506767261,
0.3362901171102985,
-0.770156875167343,
-0.21339508248386146,
1.5463760858780147,
2.0062819019116604,
-0.7774495779147144,
1.8425660842295266,
0.18993605318213097,
0.1055746891705663,
1.04298441370561,
0.07271508525503391,
-0.4020395589377781,
-1.429931447446108,
-0.4547751868391938,
0.4903022542752115,
0.3097479749443207,
0.4938971608309808,
-0.4540984190482418,
-0.372628892877357,
0.4873650724620409,
1.301560239590347,
0.1925289297736484,
-0.40819683822389785,
-0.47130717762957364,
1.3943010523278312,
-0.5513384057497219,
1.7046043766848873,
0.14454095451445387,
1.6336531508966912,
-0.7523757780210525,
-1.2055811978044482,
0.7247349714607673,
-0.48135109347681737
]
}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="d3-tip.js"></script>
<style>
:root { --var-color-grey: #898989; }
body {
margin:0;
position:fixed;
top:0;
right:0;
bottom:0;
left:0;
font-family: Helvetica; ;
}
text {
font-family: Helvetica;
color: var(--var-color-grey);
font-size: 1.2em;
}
.y.axis path,
.y.axis line {
fill: none;
stroke: var(--var-color-grey);
shape-rendering: crispEdges;
}
.x.axis path,
.x.axis line,
.grid path { stroke-width: 0; }
.tick line {
stroke: lightgrey;
opacity: 0.6;
stroke-dasharray: 2,1;
stroke-width: 1;
shape-rendering: crispEdges;
}
.d3-tip {
line-height: 1;
padding: 6px;
background: rgba(0, 0, 0, 0.7);
color: #fff;
border-radius: 4px;
font-size: 12px;
}
</style>
</head>
<body>
<div id="data"></div>
<script>
// Size and color settings for the chart
var totalWidth = 800;
var totalheight = 500;
var margin = {top: 40, right: 30, bottom: 30, left: 50},
width = totalWidth - margin.left - margin.right,
height = totalheight - margin.top - margin.bottom;
var barWidth = 40;
var boxPlotColor = "#898989";
var medianLineColor = "#ffffff";
var axisColor = "#898989";
// Setup the svg and group we will draw the box plot in
var svg = d3.select("body").append("svg")
.attr("width", totalWidth)
.attr("height", totalheight)
.append("g")
.attr("transform", "translate(" + (margin.left - barWidth) + "," + margin.top + ")");
// Move axis to center align the bars with the xAxis ticks
var yAxisBox = svg.append("g").attr("transform", "translate(40,0)");
var xAxisBox = svg.append("g").attr("transform", "translate(40,0)");
// Load and process data
d3.json("data.json").then(groupCounts => {
// Select all values into one Array for axis scaling (min/ max)
// and sort group counts so quantile methods work
var globalCounts = [];
for (var key in groupCounts) {
var groupCount = groupCounts[key]
groupCounts[key] = groupCount.sort(sortNumber);
groupCounts[key].forEach(element => {
globalCounts.push(element);
});
}
// Prepare the data for the box plots
var plotData = [];
var colorIndex = 0.1;
var colorIndexStepSize = 0.08;
for (var [key, groupCount] of Object.entries(groupCounts)) {
var record = {};
var localMin = d3.min(groupCount);
var localMax = d3.max(groupCount);
record["key"] = key;
record["counts"] = groupCount;
record["quartile"] = boxQuartiles(groupCount);
record["whiskers"] = [localMax, localMin];
record["color"] = d3.interpolateInferno(colorIndex);
plotData.push(record);
colorIndex += colorIndexStepSize;
}
// Create Tooltips
var tip = d3.tip().attr('class', 'd3-tip').direction('e').offset([0,5])
.html(function(d) {
var content = "<span style='margin-left: 2.5px;'><b>" + d.key + "</b></span><br>";
content +=`
<table style="margin-top: 2.5px;">
<tr><td>Max: </td><td style="text-align: right">` + d3.format(".2f")(d.whiskers[0]) + `</td></tr>
<tr><td>Q3: </td><td style="text-align: right">` + d3.format(".2f")(d.quartile[0]) + `</td></tr>
<tr><td>Median: </td><td style="text-align: right">` + d3.format(".2f")(d.quartile[1]) + `</td></tr>
<tr><td>Q1: </td><td style="text-align: right">` + d3.format(".2f")(d.quartile[2]) + `</td></tr>
<tr><td>Min: </td><td style="text-align: right">` + d3.format(".2f")(d.whiskers[1]) + `</td></tr>
</table>
`;
return content;
});
svg.call(tip);
// Compute an ordinal xScale for the keys in plotData
var xScale = d3.scalePoint()
.domain(Object.keys(groupCounts))
.rangeRound([0, width])
.padding([0.5]);
// Compute a global y scale based on the global counts
var min = d3.min(globalCounts);
var max = d3.max(globalCounts);
var yScale = d3.scaleLinear()
.range([height, 0])
.domain([min, max])
.nice();
// Setup the group the box plot elements will render in
var g = svg.append("g")
.attr("transform", "translate(20,0)");
// Draw the box plot vertical lines
var verticalLines = g.selectAll(".verticalLines")
.data(plotData)
.enter()
.append("line")
.attr("x1", d => { return xScale(d.key) + barWidth/2; })
.attr("y1", d => { return yScale(d.whiskers[0]); })
.attr("x2", d => { return xScale(d.key) + barWidth/2; })
.attr("y2", d => { return yScale(d.whiskers[1]); })
.attr("stroke", boxPlotColor)
.attr("stroke-width", 1)
.attr("stroke-dasharray", "5,5")
.attr("fill", "none");
// Draw the boxes of the box plot, filled in white and on top of vertical lines
var rects = g.selectAll("rect")
.data(plotData)
.enter()
.append("rect")
.attr("width", barWidth)
.attr("height", d => { return yScale(d.quartile[2]) - yScale(d.quartile[0]); })
.attr("x", d => { return xScale(d.key); })
.attr("y", d => { return yScale(d.quartile[0]); })
.attr("fill", d => { return d.color; })
.attr("stroke", boxPlotColor)
.attr("stroke-width", 1)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
// Config for whiskers and median
var horizontalLineConfigs = [
{ // Top whisker
x1: d => { return xScale(d.key) },
y1: d => { return yScale(d.whiskers[0]) },
x2: d => { return xScale(d.key) + barWidth },
y2: d => { return yScale(d.whiskers[0]) },
color: boxPlotColor
},
{ // Median
x1: d => { return xScale(d.key) },
y1: d => { return yScale(d.quartile[1]) },
x2: d => { return xScale(d.key) + barWidth },
y2: d => { return yScale(d.quartile[1]) },
color: medianLineColor
},
{ // Bottom whisker
x1: d => { return xScale(d.key) },
y1: d => { return yScale(d.whiskers[1]) },
x2: d => { return xScale(d.key) + barWidth },
y2: d => { return yScale(d.whiskers[1]) },
color: boxPlotColor
}
];
// Draw the whiskers and median line
for(var i=0; i < horizontalLineConfigs.length; i++) {
var lineConfig = horizontalLineConfigs[i];
var horizontalLine = g.selectAll(".whiskers")
.data(plotData)
.enter()
.append("line")
.attr("x1", lineConfig.x1)
.attr("y1", lineConfig.y1)
.attr("x2", lineConfig.x2)
.attr("y2", lineConfig.y2)
.attr("stroke", lineConfig.color)
.attr("stroke-width", 1)
.attr("fill", "none");
}
// add the Y gridlines
svg.append("g")
.attr("transform", "translate(40,0)")
.attr("class", "grid")
.call(d3.axisLeft(yScale)
.tickSize(-width)
.tickFormat("")
)
// Setup a scale on the left
var yAxis = d3.axisLeft(yScale).ticks(6)
yAxisBox.append("g")
.attr("class", "y axis")
.call(yAxis);
// Setup a series axis on the bottom
var xAxis = d3.axisBottom(xScale);
xAxisBox.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
});
// Quartile definition
function boxQuartiles(d) {
return [
d3.quantile(d, .75),
d3.quantile(d, .5),
d3.quantile(d, .25),
];
}
// Perform a numeric sort on an array
function sortNumber(a,b) { return a - b; }
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment