Skip to content

Instantly share code, notes, and snippets.

@joelguerrero
Last active November 11, 2015 19:58
Show Gist options
  • Save joelguerrero/a8ba351d8653e201a53a to your computer and use it in GitHub Desktop.
Save joelguerrero/a8ba351d8653e201a53a to your computer and use it in GitHub Desktop.
My first gist/bl.ocks example - boxplot (box and whiskers plots)

#Boxplot (box and whiskers plot)

You can view this plot at http://bl.ocks.org/joelguerrero/a8ba351d8653e201a53a.

It is a boxplot which it is highly useful to find outliers. The source code is highly commented so you should not have problems understanding it.

It reads a csv file, the famous iris flower data set but you can read any csv.

To change the column to read in the csv, just look for the entry

var column_sample = 1;

and change the number.

sepal length sepal width petal length petal width species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
4.6 3.4 1.4 0.3 setosa
5.0 3.4 1.5 0.2 setosa
4.4 2.9 1.4 0.2 setosa
4.9 3.1 1.5 0.1 setosa
5.4 3.7 1.5 0.2 setosa
4.8 3.4 1.6 0.2 setosa
4.8 3.0 1.4 0.1 setosa
4.3 3.0 1.1 0.1 setosa
5.8 4.0 1.2 0.2 setosa
5.7 4.4 1.5 0.4 setosa
5.4 3.9 1.3 0.4 setosa
5.1 3.5 1.4 0.3 setosa
5.7 3.8 1.7 0.3 setosa
5.1 3.8 1.5 0.3 setosa
5.4 3.4 1.7 0.2 setosa
5.1 3.7 1.5 0.4 setosa
4.6 3.6 1.0 0.2 setosa
5.1 3.3 1.7 0.5 setosa
4.8 3.4 1.9 0.2 setosa
5.0 3.0 1.6 0.2 setosa
5.0 3.4 1.6 0.4 setosa
5.2 3.5 1.5 0.2 setosa
5.2 3.4 1.4 0.2 setosa
4.7 3.2 1.6 0.2 setosa
4.8 3.1 1.6 0.2 setosa
5.4 3.4 1.5 0.4 setosa
5.2 4.1 1.5 0.1 setosa
5.5 4.2 1.4 0.2 setosa
4.9 3.1 1.5 0.2 setosa
5.0 3.2 1.2 0.2 setosa
5.5 3.5 1.3 0.2 setosa
4.9 3.6 1.4 0.1 setosa
4.4 3.0 1.3 0.2 setosa
5.1 3.4 1.5 0.2 setosa
5.0 3.5 1.3 0.3 setosa
4.5 2.3 1.3 0.3 setosa
4.4 3.2 1.3 0.2 setosa
5.0 3.5 1.6 0.6 setosa
5.1 3.8 1.9 0.4 setosa
4.8 3.0 1.4 0.3 setosa
5.1 3.8 1.6 0.2 setosa
4.6 3.2 1.4 0.2 setosa
5.3 3.7 1.5 0.2 setosa
5.0 3.3 1.4 0.2 setosa
7.0 3.2 4.7 1.4 versicolor
6.4 3.2 4.5 1.5 versicolor
6.9 3.1 4.9 1.5 versicolor
5.5 2.3 4.0 1.3 versicolor
6.5 2.8 4.6 1.5 versicolor
5.7 2.8 4.5 1.3 versicolor
6.3 3.3 4.7 1.6 versicolor
4.9 2.4 3.3 1.0 versicolor
6.6 2.9 4.6 1.3 versicolor
5.2 2.7 3.9 1.4 versicolor
5.0 2.0 3.5 1.0 versicolor
5.9 3.0 4.2 1.5 versicolor
6.0 2.2 4.0 1.0 versicolor
6.1 2.9 4.7 1.4 versicolor
5.6 2.9 3.6 1.3 versicolor
6.7 3.1 4.4 1.4 versicolor
5.6 3.0 4.5 1.5 versicolor
5.8 2.7 4.1 1.0 versicolor
6.2 2.2 4.5 1.5 versicolor
5.6 2.5 3.9 1.1 versicolor
5.9 3.2 4.8 1.8 versicolor
6.1 2.8 4.0 1.3 versicolor
6.3 2.5 4.9 1.5 versicolor
6.1 2.8 4.7 1.2 versicolor
6.4 2.9 4.3 1.3 versicolor
6.6 3.0 4.4 1.4 versicolor
6.8 2.8 4.8 1.4 versicolor
6.7 3.0 5.0 1.7 versicolor
6.0 2.9 4.5 1.5 versicolor
5.7 2.6 3.5 1.0 versicolor
5.5 2.4 3.8 1.1 versicolor
5.5 2.4 3.7 1.0 versicolor
5.8 2.7 3.9 1.2 versicolor
6.0 2.7 5.1 1.6 versicolor
5.4 3.0 4.5 1.5 versicolor
6.0 3.4 4.5 1.6 versicolor
6.7 3.1 4.7 1.5 versicolor
6.3 2.3 4.4 1.3 versicolor
5.6 3.0 4.1 1.3 versicolor
5.5 2.5 4.0 1.3 versicolor
5.5 2.6 4.4 1.2 versicolor
6.1 3.0 4.6 1.4 versicolor
5.8 2.6 4.0 1.2 versicolor
5.0 2.3 3.3 1.0 versicolor
5.6 2.7 4.2 1.3 versicolor
5.7 3.0 4.2 1.2 versicolor
5.7 2.9 4.2 1.3 versicolor
6.2 2.9 4.3 1.3 versicolor
5.1 2.5 3.0 1.1 versicolor
5.7 2.8 4.1 1.3 versicolor
6.3 3.3 6.0 2.5 virginica
5.8 2.7 5.1 1.9 virginica
7.1 3.0 5.9 2.1 virginica
6.3 2.9 5.6 1.8 virginica
6.5 3.0 5.8 2.2 virginica
7.6 3.0 6.6 2.1 virginica
4.9 2.5 4.5 1.7 virginica
7.3 2.9 6.3 1.8 virginica
6.7 2.5 5.8 1.8 virginica
7.2 3.6 6.1 2.5 virginica
6.5 3.2 5.1 2.0 virginica
6.4 2.7 5.3 1.9 virginica
6.8 3.0 5.5 2.1 virginica
5.7 2.5 5.0 2.0 virginica
5.8 2.8 5.1 2.4 virginica
6.4 3.2 5.3 2.3 virginica
6.5 3.0 5.5 1.8 virginica
7.7 3.8 6.7 2.2 virginica
7.7 2.6 6.9 2.3 virginica
6.0 2.2 5.0 1.5 virginica
6.9 3.2 5.7 2.3 virginica
5.6 2.8 4.9 2.0 virginica
7.7 2.8 6.7 2.0 virginica
6.3 2.7 4.9 1.8 virginica
6.7 3.3 5.7 2.1 virginica
7.2 3.2 6.0 1.8 virginica
6.2 2.8 4.8 1.8 virginica
6.1 3.0 4.9 1.8 virginica
6.4 2.8 5.6 2.1 virginica
7.2 3.0 5.8 1.6 virginica
7.4 2.8 6.1 1.9 virginica
7.9 3.8 6.4 2.0 virginica
6.4 2.8 5.6 2.2 virginica
6.3 2.8 5.1 1.5 virginica
6.1 2.6 5.6 1.4 virginica
7.7 3.0 6.1 2.3 virginica
6.3 3.4 5.6 2.4 virginica
6.4 3.1 5.5 1.8 virginica
6.0 3.0 4.8 1.8 virginica
6.9 3.1 5.4 2.1 virginica
6.7 3.1 5.6 2.4 virginica
6.9 3.1 5.1 2.3 virginica
5.8 2.7 5.1 1.9 virginica
6.8 3.2 5.9 2.3 virginica
6.7 3.3 5.7 2.5 virginica
6.7 3.0 5.2 2.3 virginica
6.3 2.5 5.0 1.9 virginica
6.5 3.0 5.2 2.0 virginica
6.2 3.4 5.4 2.3 virginica
5.9 3.0 5.1 1.8 virginica
<!DOCTYPE html>
<!--To definelanguage attribute-->
<html lang="en">
<!--<html>-->
<!--To definelanguage attribute-->
<head>
<!--
Metadata is used by browsers (how to display content), by search engines (keywords), and other web services.
-->
<meta charset="UTF-8">
<meta name="description" content="Free Web tutorials">
<meta name="keywords" content="HTML,CSS,XML,JavaScript">
<meta name="author" content="joegi">
<!--
Metadata is used by browsers (how to display content), by search engines (keywords), and other web services.
-->
<title>D3.JS boxplot</title>
<!--To read external CCS-->
<link rel="stylesheet" href="main.css" >
<!-- <link rel ="stylesheet" type="text/css" href="css/style.css" > -->
<link rel = "stylesheet" href="style.css" />
<!--To read external CCS-->
<!--To read external js-->
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<!--To read external js-->
<style>
/*Read main.css for style definition*/
</style>
</head>
<body>
<!--Place all DOM elements here -->
<script>
//Write your code here
//svg dimensions and margins
//Using these margings solve the problem of the axes not inside the svg.
//It also solve the problem of the padding in the bottom of the x axis
//The margins resize the svg
//var margin = {top: 30, right: 30, bottom: 30, left: 30};
var margin = {top: 20, bottom: 20, left:20, right: 20};
//var margin = {top: 0, bottom: 0, left: 0, right: 0};
// When creating the svg the actual dimension is the the width and
// height without the margins
var w1 = 600
var h1 = 150
var width = w1 - margin.left - margin.right;
var height = h1 - margin.top - margin.bottom;
var padding = 30;
//To create the plot area equal to the browser width and height plus some margin
//Responsive but remember to refresh to get new size
// var width = window.innerWidth - 2*margin.left - 2*margin.right;
// var height = window.innerHeight - 2*margin.top - 2*margin.bottom;
// var padding = 30;
//Midline of the svg
//midline = (height - padding) / 2;
var shift_box = -5
var midline = height/2 + shift_box;
//Define circle radius
var cir_r = 2.5;
//var cir_r = 4;
//column to sample in the input data
var column_sample = 1;
//column to use as title
var column_t = column_sample;
// //x axis
// var column_x = 1;
// //y axis
// var column_y = 1;
// //color encoder
// var column_c = 1;
// //size encoder
// var column_size = 0;
//max scales of color legend
//set it to the maximum count in each hexbin
//Better if it is computed automatically
//var color_max = 30;
//circles opacity
var cir_opacity = 1;
//whisker height
var whiskerheight = 30;
//box height
var boxheight = 60;
//median height
var medianheight = boxheight/2;
//Add some offset
//var xOffset = 20; //offset of graph and axis from right
var xOffset = 10; //offset of graph and axis from right gives space for legend or something else
var yOffset = 0; //offset of graph and axis from top
var xa_start = 0; //offset of left axis and graph
var ya_start = 0; //offset of bottom axis and graph
var shift_ax = 0; //translate bottom axis
var shift_ay = 0; //translate left axis
//Start and end of clipping
var xc_begin = 0;
var xc_Offset = 0; //usually same as xOffSet if you want to clip to the end of the axis
var xc_end = xc_Offset + xc_begin;
var yc_begin = 0;
var yc_Offset = 0; //usually same as yOffSet if you want to clip to the ens of the axis
var yc_end = yc_Offset + yc_begin;
//Start and end of clipping
//Legend position
var legend_x = 45;
var legend_y = 20;
//Legend position
//x label position
var text_padding_axx = width/2 - margin.right;
//var text_padding_axx = width/2 - (margin.left + margin.right)/2;
var text_padding_axy = 35;
//x label position
//y label position
var text_padding_ayx = 45;
var text_padding_ayy = height/2;
//var text_padding_ayy = height/2 + (margin.top + margin.bottom)/2;
//y label position
//title position
//var title_x = width/2;
var title_x = width/2 - (margin.left + margin.right)/2;
//var title_y = padding;
var title_y = 30;
//title position
//add jitter to the circle distribution
var jitter="yes"; //yes or no
var jitter_width = 20;
//outliers color
var color_outlier = "crimson";
//box legend attributes
var bl_color = "teal"
//var bl_color = "DarkGoldenrod"
//var bl_color = "RoyalBlue"
//var bl_color = "black" //color
var bl_dy = "15px" //relative spacing in y
var bl_dy1 = "-6px" //relative spacing in y
var bl_fs = "10px" //font size
//var bl_f = ".5g" //number format
var bl_f = " " //number format, use " " to disable thousond separator
var sbpl = "yes" //show boxplot legend yes/no
//axes number format
var a_f = ".d"
//=========================================================================================================================
//Put it outside the block in order to have global access
//empty list for array of points to be created after reading the csv
//=========================================================================================================================
//initialize boxplot statistics
var data = [];
var outliers = [];
var minVal = Infinity;
var lowerWhisker = Infinity;
var q1Val = Infinity;
var medianVal = 0;
var q3Val = -Infinity;
var iqr = 0;
var upperWhisker = -Infinity;
var maxVal = -Infinity;
//can be outside in order to take advantage of asyncronous reading
//=========================================================================================================================
// var xScale = d3.scale.linear()
// //.range([padding, width - padding])
// .range([xa_start, width - xOffset])
// .nice();
// var xAxis = d3.svg.axis()
// .scale(xScale)
// .orient("bottom");
//=========================================================================================================================
//begin F1
//read in the csv
d3.csv('flowers.csv', function(error, dataset)
{
//=========================================================================================================================
var headerNames = d3.keys(dataset[0]); //get header, using d3. Here we get first row
//console.log(headerNames)
var keys = Object.keys(dataset[0]); //get keys outside the loop. Same as the previous method but we do not use d3
//console.log(keys)
//get id of header to plot as title and axis name
var xLabel = Object.keys(dataset[0])[column_sample];
var tLabel = Object.keys(dataset[0])[column_t];
//=========================================================================================================================
//=========================================================================================================================
dataset.forEach(function(d,i) {
keys.forEach(function(key,i){
//console.log(d[key])
//console.log(key)
//From Hayle. Nice way to convert strings to numbers
//if it is a number it will converted otherwise will remain as a string
orig = d[key];
modified = Number(orig);
d[key] = (typeof orig === "string" && !isNaN(modified)) ? modified : orig;
//easy way to convert string to numbers
//d[key] = +d[key];
});
//console.log(d)
//console.log(keys[0],d[keys[0]])
});
//console.log(keys)
//console.log(dataset[0])
//console.log(dataset[0]['dv1'])
//=========================================================================================================================
//=========================================================================================================================
//map data to new arrays
//in this case we are mapping the data in column_sample of dataset
//can be a good idea to add a loop here to map all columns automatically
var mapdata = dataset.map(function(d,i)
{
return d[keys[column_sample]];
});
data = mapdata.sort(d3.ascending);
//console.log(mapdata);
//=========================================================================================================================
//=========================================================================================================================
//calculate the boxplot statistics
//min val
var minVal = data[0];
//max val
var maxVal = data[data.length - 1];
//q1 25%
var q1Val = d3.quantile(data, .25);
//q2 50% same as median
var medianVal = d3.quantile(data, .5);
//var medianVal = d3.median(data, .5);
//q3 75%
//there is a small deviation computing this quartile
//0.75 does not correponds exactly to my test cases
//round off?
//var q3Val = d3.quantile(data, .765);
var q3Val = d3.quantile(data, .75);
//inter quartile range
var iqr = q3Val - q1Val;
//lower and upper whiskers
//Attention, when outliers are present it gives a small
//deviation from python benchmark
//This is related to iqr deviation
// minVal = 180; //Test value, do not use in production
var lowerWhisker = d3.max([minVal, q1Val - 1.5*iqr]);
var upperWhisker = d3.min([maxVal, q3Val + 1.5*iqr]);
// var lowerWhisker = q1Val - 1.5*iqr;
// var upperWhisker = q3Val + 1.5*iqr;
// console.log(data)
// console.log(data[0])
// console.log("minval " + minVal)
// console.log("q1 " + q1Val)
// console.log("median " + medianVal)
// console.log("q3 " + q3Val)
// console.log("iqr " + iqr)
// console.log("max " + maxVal)
// //There is a small difference in the whisker outputs check
// console.log("lower whisker " + lowerWhisker)
// console.log("upper whisker " + upperWhisker)
//=========================================================================================================================
//=========================================================================================================================
//search for the lower whisker, the mininmum value within q1Val - 1.5*iqr
// var index = 0;
// while (index < data.length && lowerWhisker == Infinity) {
// if (data[index] >= (q1Val - 1.5*iqr))
// lowerWhisker = data[index];
// else
// outliers.push(data[index]);
// index++;
// }
// //console.log(outliers)
// //console.log(lowerWhisker)
// index = data.length-1; // reset index to end of array
// //search for the upper whisker, the maximum value within q1Val + 1.5*iqr
// while (index >= 0 && upperWhisker == -Infinity) {
// if (data[index] <= (q3Val + 1.5*iqr))
// upperWhisker = data[index];
// else
// outliers.push(data[index]);
// index--;
// }
//console.log(outliers)
//=========================================================================================================================
//=========================================================================================================================
//tooltip function
//taken form http://bl.ocks.org/Caged/6476579
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, -0])
//.direction('e')
//Set or get a tip's HTML content
//Initialize tooltip
.html(function(d) {
//return "<span style='color:white;font-size:10px'>x:</span> <span style='color:red;font-size:10px'>" + (height - d.y) + "</span>"
return "<span style='color:white;font-size:10px'>"
+ Object.keys(dataset[0])[column_sample] +
"</span> <span style='color:red;font-size:10px'>"
+ d[keys[column_sample]] + "</span>";
})
//=========================================================================================================================
//=========================================================================================================================
//initialize the x scale
var xScale = d3.scale.linear()
//map the domain to the x scale +10%
//This is to avoid the circles lying on the limit
//xScale.domain([0,maxVal*1.10]);
//Fixing minimum value of xScale to 0
//There is a mod related to how to plot the box
//xScale.domain([0,maxVal*1.0])
//Fixing minimum value of xScale to the min value of the input data
//There is a mod related to how to plot the box
xScale.domain([minVal*1.0,maxVal*1.0])
//.range([padding, width - padding])
.range([xa_start, width - xOffset])
.nice(); //fit nice the axis
//minimum value of the xaxis
var smin = xScale.domain()[0];
//maximumvalue of the xaxis
var smax = xScale.domain()[1];
// console.log(smin)
// console.log(smax)
//=========================================================================================================================
//=========================================================================================================================
//Use this block if you put the xScale function outside of the csv block
//map the domain to the x scale +10%
//xScale.domain([0,maxVal*1.10]);
//xScale.domain([0,maxVal*1.0]);
//=========================================================================================================================
//=========================================================================================================================
//initialize the x axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(d3.format(a_f))
//.tickFormat(d3.format(""))
//=========================================================================================================================
//=========================================================================================================================
//create the svg where we are going to plot the histogram
//add svg to DOM
var mySvg = d3.select("body")
.append("svg")
// .attr("width", width)
// .attr("height", height);
.attr("id", "chart") //add style to svg, defined in main.css
.attr("width", width + margin.left + margin.right) //The svg does not have margin
.attr("height", height + margin.top + margin.bottom) //The svg does not have margin
//For responsive svg
//.call(responsivefy)
.append("g") //not sure what this group is doing
.attr("transform", "translate("+ (margin.left + 0*margin.right) + ",0)") //to traslate whole svg
//.attr("transform", "translate("+ 2*margin.left +","+ margin.top +")") //to traslate whole svg
//=========================================================================================================================
//=========================================================================================================================
//append the axis
//create a group where to apply the axes
var group = mySvg.append("g")
//.attr("class", "axis")
.classed("axis", true)
.attr("transform", "translate(0," + (height - shift_ax) + ")") //translate axis from top to bottom
.call(xAxis)
.append("text")
//.attr("x", width + xOffset)
//.attr("y", -12)
.attr("y", text_padding_axy )
.attr("x", text_padding_axx )
//.attr("class", "label")
.style("font-family", "sans-serif")
.style("font-size", "12px")
.style("font-weight", "bold")
.style("fill", "black")
.style("text-anchor", "middle")
//.style("text-anchor", "end")
//.text("XXXXX");
//.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
.text(function(){ return xLabel});
//=========================================================================================================================
//=========================================================================================================================
//draw verical line for lowerWhisker
var lw = mySvg.append("line")
//.attr("class", "whisker")
.classed("whisker", true)
.attr("x1", xScale(lowerWhisker))
.attr("x2", xScale(lowerWhisker))
.attr("stroke", "black")
.attr("y1", midline - whiskerheight)
.attr("y2", midline + whiskerheight)
//.style("stroke", "red")
//=========================================================================================================================
//=========================================================================================================================
//draw vertical line for upperWhisker
var uw = mySvg.append("line")
//.attr("class", "whisker")
.classed("whisker", true)
.attr("x1", xScale(upperWhisker))
.attr("x2", xScale(upperWhisker))
.attr("stroke", "black")
.attr("y1", midline - whiskerheight)
.attr("y2", midline + whiskerheight)
//.style("stroke", "blue")
//=========================================================================================================================
//=========================================================================================================================
//draw horizontal line from lowerWhisker to upperWhisker
var whl = mySvg.append("line")
//.attr("class", "whisker")
.classed("whiskers_hline", true)
.attr("x1", xScale(lowerWhisker))
.attr("x2", xScale(upperWhisker))
.attr("stroke", "black")
.attr("y1", midline)
.attr("y2", midline)
.style("stroke-dasharray", ("10, 5"))
//.style("stroke", "orange")
//=========================================================================================================================
//=========================================================================================================================
//draw rectangle for iqr
var box = mySvg.append("rect")
//.attr("class", "box")
.classed("box", true)
.attr("stroke", "black")
.attr("fill", "white")
.attr("x", xScale(q1Val))
//.attr("x", xScale(1*q1Val + 0*smin))
//.attr("y", padding)
//.attr("y", height/2 - 30)
.attr("y", midline - boxheight/2 )
//If minVal is fix to 0 in xscale
//.attr("width", xScale(iqr))
//When using the minval of the input data
//.attr("width", xScale(iqr))
.attr("width", xScale(smin + iqr))
//.attr("height", 20);
.attr("height", boxheight)
//.style("fill", "steelblue")
// console.log(q1Val)
// console.log(q3Val)
// console.log(q3Val - q1Val)
// console.log(xScale(iqr))
// console.log(xScale(smin + iqr))
//=========================================================================================================================
//=========================================================================================================================
//draw vertical line for q1 hisker
mySvg.append("line")
//.attr("class", "whisker")
.classed("whisker", true)
.attr("x1", xScale(q1Val))
.attr("x2", xScale(q1Val))
.attr("y1", midline - medianheight)
.attr("y2", midline + medianheight)
.style("stroke", "orange")
.style("stroke-width", 2)
//draw vertical line for q3 whisker
mySvg.append("line")
//.attr("class", "whisker")
.classed("whisker", true)
.attr("x1", xScale(q3Val))
.attr("x2", xScale(q3Val))
.attr("y1", midline - medianheight)
.attr("y2", midline + medianheight)
.style("stroke", "orange")
.style("stroke-width", 2)
//=========================================================================================================================
//=========================================================================================================================
//draw vertical line at median
var medianvl = mySvg.append("line")
//.attr("class", "median")
.classed("median", true)
.attr("stroke", "black")
.attr("x1", xScale(medianVal))
.attr("x2", xScale(medianVal))
.attr("y1", midline - medianheight)
.attr("y2", midline + medianheight)
// .attr("y1", midline - (margin.top + margin.bottom)/2)
// .attr("y2", midline + (margin.top + margin.bottom)/2)
//.style("stroke", "cyan")
//=========================================================================================================================
//=========================================================================================================================
//draw data as points
var circles = mySvg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
//.attr("r", 2.5)
.attr("r", cir_r)
.attr("opacity", cir_opacity)
.attr("fill", color_outlier)
.attr("class", function(d) {
if (d[keys[column_sample]]< lowerWhisker || d[keys[column_sample]]> upperWhisker)
return "outlier";
else
return "point";
})
.attr("cx", function(d) {
return xScale(d[keys[column_sample]]);
})
.attr("cy", function(d) {
return random_jitter();
})
//appending title, this is shorcut to append tooltip in the ez way
//The title attribute is implemented in a browser dependent fashion
// .append("title")
// .append("text")
// .text(function(d) {
// //return "Date: " + d.date + "; value: " + d.value;
// return "value: " + d[keys[column_sample]];
// })
//=========================================================================================================================
//=========================================================================================================================
//Invoke the tip in the context of your visualization
//apply the tooltip to the svg
mySvg.call(tip)
circles
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
//two call two events at the same time use namespaces
// .on("mouseover.mover", mover).on("mouseover.tip_s", tip.show)
// .on("mouseout.mout", mout).on("mouseout.tip_h", tip.hide)
//=========================================================================================================================
//=========================================================================================================================
//chart title
// var title = mySvg.append("text")
// .attr("x", title_x )
// .attr("y", title_y)
// //.attr("dy", "0.35em")
// .style("text-anchor", "middle")
// .style("font-family", "sans-serif")
// .style("font-size", "20px")
// .style("font-weight", "bold")
// .style("fill", "black")
// //.text("This the title");
// //.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
// .text(function(){return tLabel});
//=========================================================================================================================
//=========================================================================================================================
//boxplot legends
if (sbpl=="yes")
{
mySvg.append("text")
.attr("x", xScale(lowerWhisker) )
.attr("y", midline + boxheight/2)
.attr("dy", bl_dy)
.style("text-anchor", "middle")
.style("font-family", "sans-serif")
.style("font-size", bl_fs)
//.style("font-weight", "bold")
.style("fill", bl_color)
//.text("This the title");
//.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
.text(function(){return d3.format(bl_f)(lowerWhisker)});
mySvg.append("text")
.attr("x", xScale(upperWhisker) )
.attr("y", midline + boxheight/2)
.attr("dy", bl_dy)
.style("text-anchor", "middle")
.style("font-family", "sans-serif")
.style("font-size", bl_fs)
//.style("font-weight", "bold")
.style("fill", bl_color)
//.text("This the title");
//.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
.text(function(){return d3.format(bl_f)(upperWhisker)});
mySvg.append("text")
.attr("x", xScale(medianVal) )
.attr("y", midline + boxheight/2)
.attr("dy", bl_dy)
.style("text-anchor", "middle")
.style("font-family", "sans-serif")
.style("font-size", bl_fs)
//.style("font-weight", "bold")
.style("fill", bl_color)
//.text("This the title");
//.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
.text(function(){return d3.format(bl_f)(medianVal)});
mySvg.append("text")
.attr("x", xScale(q1Val) )
.attr("y", midline - boxheight/2)
.attr("dy", bl_dy1)
.style("text-anchor", "middle")
.style("font-family", "sans-serif")
.style("font-size", bl_fs)
//.style("font-weight", "bold")
.style("fill", bl_color)
//.text("This the title");
//.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
.text(function(){return d3.format(bl_f)(q1Val)});
mySvg.append("text")
.attr("x", xScale(q3Val) )
.attr("y", midline - boxheight/2)
.attr("dy", bl_dy1)
.style("text-anchor", "middle")
.style("font-family", "sans-serif")
.style("font-size", bl_fs)
//.style("font-weight", "bold")
.style("fill", bl_color)
//.text("This the title");
//.text(function(){ var title = Object.keys(dataset[0])[column_sample]; return title});
.text(function(){return d3.format(bl_f)(q3Val)});
}
//=========================================================================================================================
});
//end F1
//read in the csv
//=========================================================================================================================
//=========================================================================================================================
//Function to call when you mouseover a circle
function mover(d) {
var cir_sel = d3.select(this)
.transition()
//.duration(1000)
.duration(10)
.style("fill", "orange")
.style("fill-opacity", 1)
.attr("r", cir_r + 2);
}
//Mouseout function
function mout(d) {
var cir_sel = d3.select(this)
.transition()
.duration(1000)
//.duration(10)
//.style("fill", "orange")
//.style("fill", function(d) { return color_outlier(d.length); })
.style("fill", function(d) { return color_outlier; })
//.style("fill-opacity", cir_opacity);
.attr("r", cir_r );
}
//=========================================================================================================================
//=========================================================================================================================
//Jitter function
if (jitter=="yes")
{
function random_jitter() {
if (Math.round(Math.random() * 1) == 0)
//var seed = -5;
var seed = -jitter_width;
else
//var seed = 5;
var seed = jitter_width;
//return midline + Math.floor((Math.random() * seed) + 1);
return midline + Math.floor((Math.random() * seed) + 0);
}
}
else
{
function random_jitter() {
//return midline + Math.floor((Math.random() * seed) + 1);
return midline;
}
};
//=========================================================================================================================
//=========================================================================================================================
//Parse function
// function type(d) {
// d.value = +d[keys[column_sample]]; // coerce to number
// return d;
// }
//=========================================================================================================================
</script>
</body>
</html>
body,html{
/*
margin: 0;
padding: 0;
*/
font-family: "Arial", sans-serif;
font-size: 10px;
/*
font-size: 0.95em;
text-align: center;
*/
}
#chart{
background-color: #F5F2EB;
/* border: 1px solid #CCC;*/
border: 1px solid black;
}
/*.box rect {
fill: steelblue;
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}*/
.axis path,
.axis line {
fill: none;
stroke: black;
/* stroke: #000;*/
shape-rendering: crispEdges;
}
.axis text {
/*.axis {*/
/*
font-family: sans-serif;
*/
/*font-format: "bl_p"*/
font-family: "Arial", sans-serif;
font-size: 10px;
}
.label {
/*
font-family: sans-serif;
*/
font-family: "Arial", sans-serif;
font-size: 10px;
}
.dot {
stroke: #000;
}
/*
.tooltip {
position: absolute;
width: 200px;
height: 28px;
pointer-events: none;
}
*/
.d3-tip {
line-height: 1;
/*font-weight: bold;*/
/* padding: 12px;*/
padding: 8px;
background: rgba(0, 0, 0, 0.8);
/* color: #fff;*/
/* color: blue;*/
border-radius: 2px;
}
/* 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: rgba(0, 0, 0, 0.8);
/* color: blue;*/
/*Unicode Character 'BLACK DOWN-POINTING TRIANGLE*/
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
/*body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}*/
/*.whisker line {*/
.whisker
{
/* fill: #fff;*/
/* fill: steelblue;*/
/* stroke: #000;*/
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.whiskers_hline
{
/* fill: #fff;*/
/* fill: steelblue;*/
/* stroke: #000;*/
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
/*.median line {*/
.median
{
/* stroke: #000;*/
/* stroke: crimson;*/
stroke: navy;
/* stroke: blue;*/
stroke-width: 2px;
shape-rendering: crispEdges;
}
/*.box rect {*/
.box
{
/* fill: #fff;*/
/* fill: steelblue;*/
fill: lightsteelblue;
/* stroke: #000;*/
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
/*circle
{
fill: green;
stroke: black;
shape-rendering: crispEdges;
}*/
/*this is a psedo-class*/
circle:hover
{
fill: orange;
/* stroke: orange;*/
stroke: black;
opacity: 1;
}
.outlier
{
opacity: 1;
/* fill: magenta;*/
/* fill: red;*/
fill: crimson;
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.point
{
/* opacity: 0.25;*/
/* opacity: 1; */
/* fill: green;*/
fill: lime;
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
/*.axis path
{
fill: none;
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.axis line
{
fill: none;
stroke: black;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.axis text
{
font-size: 10px;
}*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment