|
<!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> |