master
parent f29c758ac8
commit 2e23d57d8d
  1. 54
      css/style.css
  2. 508
      index.html
  3. 1564
      js/tsne_vis.js
  4. 12
      modules/bootstrap.min.js
  5. 5
      modules/d3-legend/Gruntfile.js
  6. 204
      modules/d3-legend/LICENSE
  7. 35
      modules/d3-legend/README.md
  8. 2
      modules/d3-legend/bower.json
  9. 6141
      modules/d3-legend/d3-legend.js
  10. 58
      modules/d3-legend/d3-legend.min.js
  11. 68
      modules/d3-legend/docs/color.md
  12. 3
      modules/d3-legend/docs/contents.md
  13. 4
      modules/d3-legend/docs/d3-legend.min.js
  14. 389
      modules/d3-legend/docs/docs.js
  15. 3
      modules/d3-legend/docs/docs.min.js
  16. 8
      modules/d3-legend/docs/helpers.md
  17. 743
      modules/d3-legend/docs/index.html
  18. 318
      modules/d3-legend/docs/legends.js
  19. 4
      modules/d3-legend/docs/markdown.js
  20. 64
      modules/d3-legend/docs/size.md
  21. 56
      modules/d3-legend/docs/symbol.md
  22. 14
      modules/d3-legend/index.js
  23. 1012
      modules/d3-legend/indexRollup.js
  24. 1
      modules/d3-legend/indexRollup.js.map
  25. 1004
      modules/d3-legend/indexRollupNext.js
  26. 1
      modules/d3-legend/indexRollupNext.js.map
  27. 6402
      modules/d3-legend/package-lock.json
  28. 56
      modules/d3-legend/package.json
  29. 26
      modules/d3-legend/rollup.config.js
  30. 378
      modules/d3-legend/src/color.js
  31. 12
      modules/d3-legend/src/helpers.js
  32. 260
      modules/d3-legend/src/legend.js
  33. 367
      modules/d3-legend/src/size.js
  34. 305
      modules/d3-legend/src/symbol.js
  35. 14
      modules/d3-legend/src/web.js
  36. 1
      modules/d3-legend/test/mocha.opts
  37. 20
      modules/d3-legend/test/test.js
  38. 153
      modules/d3-legend/test/test.legendcolor.js
  39. 75
      modules/d3-legend/test/test.legendsize.js
  40. 75
      modules/d3-legend/test/test.legendsymbol.js
  41. 7
      modules/d3-legend/tsconfig.json
  42. 84
      modules/d3-legend/types/d3-svg-legend.d.ts
  43. 37
      modules/d3-star/d3-starPlot.js
  44. 3
      modules/three.js-r101/.gitattributes
  45. 28
      modules/three.js-r101/.github/CONTRIBUTING.md
  46. 41
      modules/three.js-r101/.github/ISSUE_TEMPLATE.md
  47. 10
      modules/three.js-r101/.gitignore
  48. 8
      modules/three.js-r101/.npmignore
  49. 5
      modules/three.js-r101/.travis.yml
  50. 965
      modules/three.js-r101/three.js
  51. BIN
      textures/circle-sprite.png

@ -1,10 +1,15 @@
/* Custom styling */
/* Main html/body configurations */
html, body {
max-width: 100%;
margin-top: 15px;
font: serif;
}
.container-fluid {
margin-top: 5px;
}
#param-correlation {
flex: 1;
display: flex;
@ -103,6 +108,7 @@ cursor: default;
border: 1px solid black;
position: absolute;
display: block;
z-index: 2;
}
/* Styling of the overview canvas */
@ -117,7 +123,7 @@ cursor: default;
#knnBarChart {
width: 50vw;
height: 4.2vw;
margin-top: 4.4vw;
margin-top: 7.2vw;
border: 1px solid black;
position: absolute;
display: block;
@ -153,6 +159,7 @@ cursor: default;
width: 11vw;
height: 11vw;
position: absolute;
border: 1px solid black;
}
/* Number of Points font-size */
@ -173,14 +180,6 @@ svg#legend4 {
overflow: auto;
}
/* This is the styling for the thumbnails list*/
#ThumbNailsList{
border: 1px solid black;
width: 15.4vw;
height: 13vw;
padding: 10px 10px 10px 10px;
}
/* ShepardHeatmap Styling for the different rectangles used there */
rect {
stroke: #E6E6E6;
@ -269,6 +268,12 @@ rect {
.show {display:block;}
/* This is for the Correlation bar chart */
#correlation{
margin-left: 10px;
margin-top: -20px;
border: 1px solid black;
}
.y.axis line {
fill: none;
}
@ -300,7 +305,7 @@ rect {
/*shape-rendering: crispEdges;*/
}
/* Styling for the annotation circle */
.annotation circle {
fill: none;
stroke: black;
@ -320,4 +325,29 @@ rect {
#toggleAnnotator {
color: darkgray;
}
}
#selectionLabel{
border: 1px solid grey;
}
#starPlot{
border: 1px solid grey;
margin-left:10px;
}
.parent-row{
display: flex;
}
.children-columns{
display: flex;
}
#extra-information {
margin-top: 25px;
margin-left: 10px;
}
#kNNInfo {
margin-top: 40px;
}

@ -1,249 +1,335 @@
<html>
<head>
<!-- Ignore Favicon -> Solved the warning... -->
<!-- Ignore Favicon -> Solved the warning in console of the browser. -->
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<!-- Importing D3 module -->
<script src='./modules/d3v3/d3.min.js'></script>
<script src='./modules/d3/d3.min.js'></script>
<script src='./modules/d3-star/d3-starPlot.js'></script>
<script src='./modules/d3-annotations/d3-annotator.js'></script>
<script src="./modules/d3-tip/tip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.13.0/d3-legend.js"></script>
<script src="./modules/savage.toggle-switch.js" type="text/javascript"></script>
<script src="./modules/papa/papaparse.min.js"></script>
<script src="./modules/jquery/jquery.min.js"></script>
<!-- Basic scripts -->
<script src="./js/tsne.js"></script>
<script src="./js/checkbox.js"></script>
<script src="./js/data_form_handler.js"></script>
<script src="./lasso.js"></script>
<!-- CSS -->
<link rel="stylesheet" href="./css/style.css"/>
<link rel="stylesheet" href="./css/bootstrap.min.css"/>
<link rel="stylesheet" href="./css/dc.css"/>
<!-- Bootstrap -->
<script src="./modules/bootstrap.min.js"></script>
<!-- To be removed!!!-->
<script src='./modules/three.js-r101/three.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js'></script>
</head>
<!-- Importing D3 minified versions v3 and v5. -->
<script src='./modules/d3v3/d3.min.js'></script>
<script src='./modules/d3/d3.min.js'></script>
<!-- Importing additional modules such as starPlot, annotator, tip, legend, switch, papaParse, and Jquery. -->
<script src='./modules/d3-star/d3-starPlot.js'></script>
<script src='./modules/d3-annotations/d3-annotator.js'></script>
<script src="./modules/d3-tip/tip.js"></script>
<script src="./modules/d3-legend/d3-legend.min.js"></script>
<script src="./modules/savage.toggle-switch.js" type="text/javascript"></script>
<script src="./modules/papa/papaparse.min.js"></script>
<script src="./modules/jquery/jquery.min.js"></script>
<body>
<!-- Basic scripts that we execute. -->
<script src="./js/tsne.js"></script>
<script src="./js/checkbox.js"></script>
<script src="./js/data_form_handler.js"></script>
<script src="./lasso.js"></script>
<!-- CSS - Styling -->
<link rel="stylesheet" href="./css/style.css"/>
<link rel="stylesheet" href="./css/bootstrap.min.css"/>
<link rel="stylesheet" href="./css/dc.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<!-- Bootstrap -->
<script src="./modules/bootstrap.min.js"></script>
</head>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">t-SNE Overview</h3>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">t-SNE Overview</h3>
</div>
<div class="row">
<div class="panel-body">
<div class="col-md-6">
<canvas id = "tSNEcanvas"></canvas>
</div>
<div class="col-md-2">
<div class="legend" id = "legend3"></div>
</div>
</div>
</div>
<div id="control-panel">
<div class="param">
<label for="param-lim">Points radius scaling factor</label>
<input id="param-lim" type="range" min="0.25" max="4" value="2", step="0.25">
<output for="param-lim" id="param-lim-value">2</output>
</div>
</div>
</div>
</div>
<div class="row">
<div class="panel-body">
<div class="col-md-6">
<canvas id = "tSNEcanvas"></canvas>
</div>
<div class="col-md-2">
<div class="legend" id = "legend3"></div>
<div class="col-md-6">
<svg id="SvgAnnotator"></svg>
<svg id="modtSNEcanvas_svg"></svg>
<div id="modtSNEDiv">
<canvas id = "modtSNEcanvas" ></canvas>
</div>
</div>
<div class="col-md-1" style="width: 3.499999995%">
<svg id="legend1"></svg>
</div>
<div class="col-md-2" style="width: 21.499999995%">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Select different modes</h3>
</div>
<div class="panel-body">
<div id="resetAllFilters" style="margin-bottom: 40px">
<button class="btn btn-info btn-block active" onclick="setLayerProj();">Layer: t-SNE projection</button>
<button class="btn btn-info btn-block" onclick="setLayerComp();">Layer: kNN limiter and data features comparison</button>
<button class="btn btn-info btn-block" onclick="setLayerSche();">Layer: Schema investigation</button>
</div>
</div>
<button class="btn btn-info btn-block" onclick="setReset();">Reset all filters</button>
<label style="margin-top: 15px">
<input id="controls" type="checkbox">
Hide annotations' controllers
</label>
</div>
</div>
</div>
<div id="control-panel">
<div class="param">
<label for="param-lim">Points radius scaling factor</label>
<input id="param-lim" type="range" min="0.25" max="4" value="2", step="0.25">
<output for="param-lim" id="param-lim-value">2</output>
</div>
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Shepard Heatmap</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<svg id="sheparheat"></svg>
</div>
<div class="col-md-2">
<svg id="legend4"></svg>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-md-offset-6">
<svg id="correlation"></svg>
</div>
</div>
</div>
<div class="col-md-6">
<svg id="SvgAnnotator"></svg>
<svg id="modtSNEcanvas_svg"></svg>
<canvas id = "modtSNEcanvas" ></canvas>
</div>
<div class="col-md-1">
<svg id="legend1"></svg>
</div>
<div class="col-md-2">
<div id="ThumbNailsList">
<label for="male">Neighborhood Preservation</label>
<select id="param-neighborHood" name ="param-neighborHood">
<option selected="selected" value="color">Color</option>
<option value="size">Size</option>
</select>
<output for="param-neighborHood" id="param-neighborHood-value"></output>
<label for="male">Final Cost (Kullback-Leibler)</label>
<label>Vice versa</label>
<div id="param-correlation">
<div class="param">
<label for="param-corr">Correlation threshold</label>
<input id="param-corr" type="range" min="0" max="750" value="150", step="50">
<output for="param-corr" id="param-corr-value">150</output>
</div>
Type the text of the form: <textarea type="text" id="comment" name="textforAnnotator">Please, provide your comment.</textarea>
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">t-SNE Parameters</h3>
</div>
<div class="panel-body">
<div id="control-panel" data-sr="enter left over 8s">
<div class="param">
<label id="data" for="param-dataset">Data sets</label>
<select id="param-dataset" name="param-dataset" onChange="changeDataset(this.value);">
<option value="winequality-red.csv">Red Wine - Quality</option>
<option value="iris.csv" selected>Iris</option>
<option value="mnist.csv" >Mnist</option>
<option value="Frogs_MFCCs_s.csv" >Frogs</option>
<option value="empty">Add New File</option>
</select>
</div>
<div class="param">
<label for="param-perplexity">Perplexity</label>
<input id="param-perplexity" type="range" min="2" max="100" value="30", step="1">
<output for="param-perplexity" id="param-perplexity-value">30</output>
</div>
<div class="param">
<label for="param-learningrate">Learning rate</label>
<input id="param-learningrate" type="range" min="1" max="300" value="10", step="1">
<output for="param-learningrate" id="param-learningrate-value">10</output>
</div>
<div class="param">
<label for="param-maxiter">Max iterations</label>
<input id="param-maxiter" type="range" min="10" max="1000" value="10", step="10">
<output for="param-maxiter" id="param-maxiter-value">10</output>
</div>
<div class="param">
<label for="param-distance">Distance metric</label>
<select id="param-distance" name="param-distance">
<option value="euclideanDist" selected>Euclidean distance</option>
<option value="jaccardDist">Jaccard dissimilarity</option>
</select>
<output for="param-distance" id="param-distance-value"></output>
</div>
<div class="param">
<label for="param-transform">Data transform</label>
<select id="param-transform" name="param-transform">
<option value="noTrans" selected>No transform</option>
<option value="logTrans">Log10</option>
<option value="asinhTrans">asinh</option>
<option value="binTrans">Binarize</option>
</select>
<output for="param-transform" id="param-transform-value"></output>
</div>
<p><div id="run-button"><button class="btn btn-primary btn-block" onclick="getData();">Run New t-SNE</button></div></p>
</div>
<p><div id="toggleAnnotator"><button class="btn btn-primary btn-block" onclick="setAnnotator();">Add a new comment</button></div></p>
<p><div id="continue"><button class="btn btn-primary btn-block" onclick="setContinue();">Continue with the analysis</button></div></p>
</div>
</div>
</div>
<div class="col-md-3 col-md-offset-6">
<div id="starPlot"></div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Shepard Heatmap</h3>
</div>
<div class="panel-body">
</div>
<div class="row">
<div class="col-md-6">
<svg id="sheparheat"></svg>
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Visual Mapping Parameters</h3>
</div>
<div class="row">
<div class="panel-body">
<div class="col-md-12">
<div id="ThumbNailsList">
<label for="male">Neighborhood Preservation</label>
<select id="param-neighborHood" name ="param-neighborHood">
<option selected="selected" value="color">Color</option>
<option value="size">Size</option>
</select>
<output for="param-neighborHood" id="param-neighborHood-value"></output>
<label for="male">Final Cost (Kullback-Leibler)</label>
<label id="selectionLabel" style="margin-top:4px">Vice versa</label>
<div id="param-correlation">
<div class="param">
<label for="param-corr">Correlation threshold</label>
<input id="param-corr" type="range" min="0" max="750" value="150", step="50">
<output for="param-corr" id="param-corr-value">150</output>
</div>
Visualization annotating form: <textarea type="text" id="comment" name="textforAnnotator" style="margin-top:4px" placeholder="Please, provide your comment."></textarea>
</div>
<div id="commBtn">
<div class="param" style="margin-top:4px">
<div id="toggleAnnotator"><button class="btn btn-default btn-block" onclick="setAnnotator();">Add a new comment</button></div>
</div>
<div class="param" style="margin-top:4px">
<div id="continue"><button class="btn btn-default btn-block active" onclick="setContinue();">Continue with the analysis</button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-2">
<svg id="legend4"></svg>
<div class = col-md-6>
<svg id="knnBarChart"></svg>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-md-offset-6">
<svg id="correlation"></svg>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">t-SNE Parameters</h3>
</div>
<div class="panel-body">
<div id="control-panel" data-sr="enter left over 8s">
<div class="param">
<label id="data" for="param-dataset">Data sets</label>
<select id="param-dataset" name="param-dataset" onChange="changeDataset(this.value);">
<option value="winequality-red.csv">Red Wine - Quality</option>
<option value="iris.csv" selected>Iris</option>
<option value="mnist.csv" >Mnist</option>
<option value="Frogs_MFCCs_s.csv" >Frogs</option>
<option value="empty">Add New File</option>
</select>
<div class="col-md-3" id="extra-information" style="width: 24.5999995%">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">t-SNE and data set's extra information</h3>
</div>
<div class="panel-body">
<div id="cost"></div>
<br>
<div id="datasetDetails"></div>
</div>
</div>
<div class="panel panel-default" id="kNNInfo">
<div class="panel-heading">
<h3 class="panel-title">kNN barchart information</h3>
</div>
<div class="panel-body">
<div id="cost"></div>
<br>
<div id="datasetDetails"></div>
</div>
</div>
</div>
<div class="param">
<label for="param-perplexity">Perplexity</label>
<input id="param-perplexity" type="range" min="2" max="100" value="30", step="1">
<output for="param-perplexity" id="param-perplexity-value">30</output>
</div>
<div class="param">
<label for="param-learningrate">Learning rate</label>
<input id="param-learningrate" type="range" min="1" max="300" value="10", step="1">
<output for="param-learningrate" id="param-learningrate-value">10</output>
</div>
<div class="param">
<label for="param-maxiter">Max iterations</label>
<input id="param-maxiter" type="range" min="10" max="1000" value="10", step="10">
<output for="param-maxiter" id="param-maxiter-value">10</output>
</div>
<div class="param">
<label for="param-distance">Distance metric</label>
<select id="param-distance" name="param-distance">
<option value="euclideanDist" selected>Euclidean distance</option>
<option value="jaccardDist">Jaccard dissimilarity</option>
</select>
<output for="param-distance" id="param-distance-value"></output>
</div>
<div class="param">
<label for="param-transform">Data transform</label>
<select id="param-transform" name="param-transform">
<option value="noTrans" selected>No transform</option>
<option value="logTrans">Log10</option>
<option value="asinhTrans">asinh</option>
<option value="binTrans">Binarize</option>
</select>
<output for="param-transform" id="param-transform-value"></output>
</div>
<p><div id="run-button"><button class="btn btn-primary btn-block" onclick="getData();">Run New tSNE</button></div></p>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-md-offset-6">
<div id="starPlot"></div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Switch Mode</h3>
</div>
<div class="panel-body">
<div id="cost"></div>
<div id="datasetDetails"></div>
<div id="toggleLassoAndLine"></div>
</div>
</div>
</div>
<div class = col-md-6>
<svg id="knnBarChart"></svg>
</div>
</div>
</div>
<script>
$('#param-lim').bind('input', function () { $('#param-lim-value').text($('#param-lim').val()); });
/* This script is used in order to give functionalities to the different buttons provide through the front-end. */
$('#param-lim').bind('input', function () { $('#param-lim-value').text($('#param-lim').val()); });
$('#param-corr').bind('input', function () { $('#param-corr-value').text($('#param-corr').val()); });
$('#param-perplexity').bind('input', function () { $('#param-perplexity-value').text($('#param-perplexity').val()); });
$('#param-earlyexag').bind('input', function () { $('#param-earlyexag-value').text($('#param-earlyexag').val()); });
$('#param-learningrate').bind('input', function () { $('#param-learningrate-value').text($('#param-learningrate').val()); });
$('#param-maxiter').bind('input', function () { $('#param-maxiter-value').text($('#param-maxiter').val()); });
SaVaGe.ToggleSwitch({container: "#toggleLassoAndLine", onChange: function(toggler){ setToggle(toggler.getValue()); }} );
// Get the container element
var btnContainer = document.getElementById("commBtn");
// Get all buttons with class="btn" inside the container
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
let current = document.getElementById("commBtn").getElementsByClassName("active");
console.log(current);
current[0].className = current[0].className.replace("btn btn-default btn-block active", "btn btn-default btn-block");
this.className += " active";
});
}
// Get the container element
var btnContainer2 = document.getElementById("resetAllFilters");
// Get all buttons with class="btn" inside the container
var btns2 = btnContainer2.getElementsByClassName("btn");
for (var i = 0; i < btns2.length; i++) {
btns2[i].addEventListener("click", function() {
let current = document.getElementsByClassName("active");
console.log(current);
current[0].className = current[0].className.replace("btn btn-info btn-block active", "btn btn-info btn-block");
this.className += " active";
});
}
</script>
<script>
/* On resize refresh the shepardHeatmap */
window.onresize = function(event) {
if ( document.getElementById('cost').hasChildNodes() ) {
// Clear legend for the shepardHeatmap
var svgLegend = d3.select("#legend4");
svgLegend.selectAll("*").remove();
// Clear the SheapHeardmap before refreshing
var svg = d3.select("#sheparheat");
svg.selectAll("*").remove();
// Call the ShepardHeatmap again to be redrawn
ShepardHeatMap();
<script>
/* On resize refresh the shepardHeatmap */
window.onresize = function(event) {
if ( document.getElementById('cost').hasChildNodes() ) {
// Clear legend for the shepardHeatmap
var svgLegend = d3.select("#legend4");
svgLegend.selectAll("*").remove();
// Clear the SheapHeardmap before refreshing
var svg = d3.select("#sheparheat");
svg.selectAll("*").remove();
// Call the ShepardHeatmap again to be redrawn
ShepardHeatMap();
}
}
}
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
}
</script>
</script>
<!--
Load the visualization script
-->
<script src="./js/tsne_vis.js"></script>
<!-- Load the core visualization script. -->
<script src="./js/tsne_vis.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -5,11 +5,14 @@ module.exports = function(grunt){
// configure plugins
grunt.initConfig({
browserify: {
dist: {
files: {
'd3-legend.js': ['src/web.js'],
},
options: {
browserifyOptions: { debug: true },
transform: [ ['babelify', {'presets': ['es2015']}] ]
}
},
docs: {

@ -1,5 +1,203 @@
Copyright (c) 2015, Susie Lu
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2015, Susie Lu
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -2,40 +2,45 @@
Full documentation: [http://d3-legend.susielu.com](http://d3-legend.susielu.com)
## Looking for compatibility with d3 v3?
- You can see the code for the d3 legend that works with d3 v3 in the [v3 branch](https://github.com/susielu/d3-legend/tree/v3)
- [Documentation](http://d3-legend-v3.susielu.com) for the v3 version of the legend
## d3-legend v4 updates (npm version 2.0.0 and higher)
- Flattened naming for accessing functions
- d3.legend.color => d3.legendColor
- d3.legend.size => d3.legendSize
- d3.legend.symbol => d3.legendSymbol
- NPM package no longer binds to global d3, is now just an object with the three legend functions
## Usage
### Using just the minified file
You must inclue the [d3 library](http://d3js.org/) before including the legend file. Then you can simply add the compiled js file to your website:
You must include the [d3 library](http://d3js.org/) before including the legend file. Then you can simply add the compiled js file to your website:
- d3-legend.min.js
- d3-legend.js (Human readable version)
### Using CDN
You can also add latest version of [d3-legend hosted on cdnjs](https://cdnjs.com/libraries/d3-legend/1.13.0).
You can also add the latest version of [d3-legend hosted on cdnjs](https://cdnjs.com/libraries/d3-legend).
### Using npm
Already using d3? Great! You can add the d3 legend as a node module by running:
You can add the d3 legend as a node module by running:
`npm i d3-svg-legend -S`
If not, install both this way:
To use the version compatible with d3v3 run:
`npm i d3-svg-legend@1.x -S`
`npm i d3@^3.0.0 d3-svg-legend -S`
Using the import syntax `import legend from 'd3-svg-legend'` gives access to the three legend types as an object. You can also import them independently for example `import { legendColor } from 'd3-svg-legend'`
Please note, d3 is now a peer dependency, you will have to have the npm d3 module separately. This component works with any 3.x version of d3.
If you `require('d3-svg-legend')` we attach to d3 as `d3.legend`. If you'd like to use d3-legend without extending d3, `require('d3-svg-legend/no-extend')`. For example:
```
var d3 = require('d3')
var legend = require('d3-svg-legend/no-extend')
var svg = d3.select("#svg-color-quant");
var quantize = d3.scale.quantize()
var quantize = d3.scaleQuantize()
.domain([ 0, 0.15 ])
.range(d3.range(9).map(function(i) { return "q" + i + "-9"; }));
@ -43,7 +48,7 @@ svg.append("g")
.attr("class", "legendQuant")
.attr("transform", "translate(20,20)");
var colorLegend = legend.color()
var colorLegend = d3.legendColor()
.labelFormat(d3.format(".2f"))
.useClass(true)
.scale(quantize);
@ -54,4 +59,4 @@ svg.select(".legendQuant")
```
## Feedback
I would love to hear from you about any additional features that would be useful, please say hi on twitter [@DataToViz](https://www.twitter.com/DataToViz).
I would love to hear from you about any additional features that would be useful, please say hi on twitter [@DataToViz](https://www.twitter.com/DataToViz).

@ -21,6 +21,6 @@
"tests"
],
"dependencies": {
"d3": "~3.5.6"
"d3": "^4.3.0"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,75 +1,103 @@
d3.legend.**color()**
d3.**legendColor()**
Constructs a new color legend. The legend component expects a d3 scale as the basic input, but also has a number of optional parameters for changing the default display such as vertical or horizontal orientation, shape of the symbol next to the label, symbol sizing, and label formatting.
color.**scale(d3.scale)**
legendColor.**scale(d3.scale)**
Creates a new d3 legend based on the scale. The code determines the type of scale and generates the appropriate symbol and label pairs.
color.**cells(number or [numbers])**
legendColor.**cells(number or [numbers])**
This parameter is only valid for continuous scales (like linear and log). When there is no indication from the domain or range for the number of steps in the legend you may want to display, it defaults to five steps in equal increments. You can pass the cells function a single number which will create equal increments for that number of steps, or an array of the [specific steps](#color-linear-custom) you want the legend to display.
color.**orient(string)**
legendColor.**cellFilter(function)**
This function is run as a filter function against the array of cells. If you have a function(d){ return true or false }, d has a .data and a .label property as it iterates over each cell it will display. Create a false condition for any cells you want to exclude from being displayed. An example: [Color - Ordinal Scale Legend, custom shape](#color-ordinal).
legendColor.**orient(string)**
Accepts "vertical" or "horizontal" for legend orientation. Default set to "vertical."
color.**ascending(boolean)**
legendColor.**ascending(boolean)**
If you pass this a true, it will reverse the order of the scale.
color.**shape(string[, path-string])**
legendColor.**shape(string[, path-string])**
Accepts "rect", "circle", "line", or "path". If you choose "path," you must also pass a second parameter as a path string. Defaults to "rect." An example: [Color - Ordinal Scale Legend, custom shape](#color-ordinal).
color.**shapeWidth(number)**
legendColor.**shapeWidth(number)**
Only applies to shape of "rect" or "line." Default set to 15px.
color.**shapeHeight(number)**
legendColor.**shapeHeight(number)**
Only applies to shape of "rect." Default set to 15px.
color.**shapeRadius(number)**
legendColor.**shapeRadius(number)**
Only applies to shape of "circle." Default set to 10px.
color.**shapePadding(number)**
legendColor.**shapePadding(number)**
Applies to all shapes. Determines vertical or horizontal spacing between shapes depending on the respective orient setting. Default set to 2px.
color.**useClass(boolean)**
legendColor.**useClass(boolean)**
The default behavior is for the legend to set the fill of the legend's symbols (except for the "line" shape which uses stroke). If you set useClass to `true` then it will apply the scale's output as classes to the shapes instead of the fill or stroke. An example: [Color - Quantile Scale Legend](#color-quant).
color.**classPrefix(string)**
legendColor.**classPrefix(string)**
Adds this string to the beginning of all of the components of the legend that have a class. This allows for namespacing of the classes.
color.**title(string)**
legendColor.**title(string)**
Sets the legend's title to the string. Automatically moves the legend cells down based on the size of the title. An example: [Symbol - Ordinal Scale](#symbol-ordinal).
color.**labels([string])**
legendColor.**titleWidth(number)**
Will break the legend title into multiple lines based on the width in pixels. An example: [Color - Quantile Scale Legend](#color-quant).
legendColor.**labels([string] or function(options))**
Passing a string:
Sets the legend labels to the array of strings passed to the legend. If the array is not the same length as the array the legend calculates, it merges the values and gives the calculated labels for the remaining items. An example: [Size - Linear Scale Legend, Lines](#size-line).
color.**labelAlign(string)**
Passing a function:
This function is called for each generated label and gives you the options:
- i: current index
- genLength: total length of generated labels
- generatedLabels: array of generated labels
- domain: array from input scale
- range: array from input scale
This allows you to make any custom functions to handle labels. An example: [Color - Threshold Scale, Custom Labels](#color-threshold)
List of [helper functions](#helpers).
legendColor.**labelAlign(string)**
Only used if the legend's orient is set to "horizontal." Accepts "start", "middle", or "end" as inputs to determine if the labels are aligned on the left, middle or right under the symbol in a horizontal legend. An example: [Size - Linear Scale Legend, Lines](#size-line).
color.**labelFormat(d3.format)**
legendColor.**labelFormat(d3.format or d3.format string)**
Takes a [d3.format](https://github.com/mbostock/d3/wiki/Formatting) and applies that styling to the legend labels. Default is set to `d3.format(".01f")`.
color.**labelOffset(number)**
legendColor.**locale(d3.format locale)**
Takes a [d3.format locale](https://github.com/d3/d3-format/tree/master/locale) and applies it to the legend labels. Default is set to [US english](https://github.com/d3/d3-format/blob/master/locale/en-US.json).
legendColor.**labelOffset(number)**
A value that determines how far the label is from the symbol in each legend item. Default set to 10px.
color.**labelDelimiter(string)**
legendColor.**labelDelimiter(string)**
Change the default "to" text when working with a quant scale.
color.**on(string, function)**
legendColor.**labelWrap(number)**
Add text wrapping to the cell labels. In orient horizontal you can use this in combination with shapePadding to get the desired spacing. An exampe: [Size - Linear Scale](#size-line). In orient vertical this will automatically scale the cells to fit the label.An example: [Symbol - Ordinal Scale](#symbol-ordinal)
legendColor.**on(string, function)**
There are three custom event types you can bind to the legend: "cellover", "cellout", and "cellclick" An exampe: [Symbol - Ordinal Scale](#symbol-ordinal)
There are three custom event types you can bind to the legend: "cellover", "cellout", and "cellclick" An example: [Symbol - Ordinal Scale](#symbol-ordinal)

@ -2,6 +2,7 @@
- [Documentation](#color-doc)
- [Examples](#color-examples)
- [Quantile Scale Legend](#color-quant)
- [Threshold Scale Legend](#color-threshold)
- [Linear Scale Legend - Horizontal](#color-linear)
- [Linear Scale Legend - 10 cells](#color-linear-10)
- [Linear Scale Legend - Custom cells](#color-linear-custom)
@ -17,4 +18,4 @@
- [Examples](#symbol-examples)
- [Ordinal Scale Legend - Custom Symbols](#symbol-ordinal)
- [Summary of Functions](#summary) - table of which functions are shared across legend types
- [Summary of Functions](#summary) - table of which functions are shared across legend types

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,8 @@
d3.**legendHelpers()**
Convenience functions for using this module
legendHelpers.**thresholdLabels**
Changes the labels so the first one label says "Less than _first-threshold_" and the last one says "More than _last-threshold_".
Example: [Color - Threshold Scale, Custom Labels](#color-threshold)

@ -1,5 +1,6 @@
<!DOCTYPE html>
<meta charset="utf-8">
<head>
@ -14,119 +15,162 @@
<link rel="stylesheet" href="prism.css">
<style>
svg {
padding: 10px 15px;
margin-bottom: 5px;
display: block;
background: white;
border: 1px solid $grey;
}
svg {
padding: 10px 15px;
margin-bottom: 5px;
display: block;
background: white;
border: 1px solid $grey;
}
pre[class*="language-"]{
margin-top: 0px;
margin-bottom: 30px;
border: 1px solid #E4E4E4;
}
pre[class*="language-"] {
margin-top: 0px;
margin-bottom: 30px;
border: 1px solid #E4E4E4;
}
:not(pre) > code[class*="language-"], pre[class*="language-"] {
background: #FFFFFF;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #FFFFFF;
}
.token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted {
color: #323232;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #323232;
}
.token.function {
color: #989898;
}
.token.function {
color: #989898;
}
.token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted {
color: #00993C;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #00993C;
}
h4 {
display: inline-block;
}
h4 {
display: inline-block;
}
strong {
color: #272727;
}
strong {
color: #272727;
}
text {
font: 12px sans-serif;
}
text {
font: 12px sans-serif;
}
hr {
border-top: 1px solid #999;
}
hr {
border-top: 1px solid #999;
}
table tbody tr:not(:last-child) td{
border-bottom: 2px solid #E7E7E7;
}
table tbody tr:not(:last-child) td {
border-bottom: 2px solid #E7E7E7;
}
table tbody td:not(:last-child), table thead th:not(:last-child) {
border-right: 2px solid #e7e7e7
}
table tbody td:not(:last-child),
table thead th:not(:last-child) {
border-right: 2px solid #e7e7e7
}
table td:not(:first-child){
width: 60px;
}
table td:not(:first-child) {
width: 60px;
}
table td.included{
background-color: rgb(102, 178, 155);
}
table td.included {
background-color: rgb(102, 178, 155);
}
@media only screen and (max-width: 480px){
table {
font-size: 11px;
@media only screen and (max-width: 480px) {
table {
font-size: 11px;
}
}
}
#contents ul li {
font-size: 16px;
}
#contents ul li {
font-size: 16px;
}
.legendSize rect, .legendSize circle{
fill: rgb(46, 73, 123);
}
.legendSize rect,
.legendSize circle {
fill: rgb(46, 73, 123);
}
.legendSizeHorz circle{
stroke: rgb(71, 187, 94);
fill: none;
}
.legendSizeHorz circle {
stroke: rgb(71, 187, 94);
fill: none;
}
.legendSizeLine line {
stroke: rgb(46, 73, 123);
}
.legendSymbol path {
fill: rgb(64, 108, 189);
}
.q0-9 {
fill: rgb(247, 251, 255);
}
.q1-9 {
fill: rgb(222, 235, 247);
}
.q2-9 {
fill: rgb(198, 219, 239);
}
.q3-9 {
fill: rgb(158, 202, 225);
}
.legendSizeLine line {
stroke: rgb(46, 73, 123);
}
.q4-9 {
fill: rgb(107, 174, 214);
}
.legendSymbol path {
fill: rgb(64, 108, 189);
}
.q5-9 {
fill: rgb(66, 146, 198);
}
.q6-9 {
fill: rgb(33, 113, 181);
}
.q0-9 { fill:rgb(247,251,255); }
.q1-9 { fill:rgb(222,235,247); }
.q2-9 { fill:rgb(198,219,239); }
.q3-9 { fill:rgb(158,202,225); }
.q4-9 { fill:rgb(107,174,214); }
.q5-9 { fill:rgb(66,146,198); }
.q6-9 { fill:rgb(33,113,181); }
.q7-9 { fill:rgb(8,81,156); }
.q8-9 { fill:rgb(8,48,107); }
.q7-9 {
fill: rgb(8, 81, 156);
}
.q8-9 {
fill: rgb(8, 48, 107);
}
</style>
</head>
<body>
<header>
<div class="container">
<div class="txt-center">
<h1 class="column12">d3 SVG Legend</h1>
<h1 class="column12">d3 SVG Legend (v4)</h1>
<div class="column6 prefix3">
<p>Tired of making legends for your data visualizations? Me too, enjoy.</p>
<p>A library to make legends in svg-land easy as pie.</p>
<img src="d3-legend.jpg">
<p>By <a href="http://www.susielu.com">Susie Lu</a></p>
<p>By
<a href="http://www.susielu.com">Susie Lu</a>
</p>
</div>
<nav class="column6 prefix3 nav nav-small">
<a href="#usage">Usage</a>
@ -134,6 +178,7 @@
<a href="#color">Color</a>
<a href="#size">Size</a>
<a href="#symbol">Symbol</a>
<a href="#helpers">Helpers</a>
<a href="#summary">Summary of Functions</a>
</nav>
</div>
@ -149,28 +194,51 @@