Skip to content

Instantly share code, notes, and snippets.

@mwdchang
Created April 21, 2015 05:34
Show Gist options
  • Save mwdchang/fe01ddeeea4c9d9d0eda to your computer and use it in GitHub Desktop.
Save mwdchang/fe01ddeeea4c9d9d0eda to your computer and use it in GitHub Desktop.
Scroll Demo
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
</head>
<body>
<span> Mouse over letters to hightlight list, unviewable items are indicated with top/bottom bar:</span><br>
<svg id="blahblah" width="200" height="50"></svg>
<div id="list1"></div>
</body>
<script>
// This product includes color specifications and designs developed by Cynthia Brewer (http://colorbrewer.org/).
var colorbrewer = {YlGn: {
3: ["#f7fcb9","#addd8e","#31a354"],
4: ["#ffffcc","#c2e699","#78c679","#238443"],
5: ["#ffffcc","#c2e699","#78c679","#31a354","#006837"],
6: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#31a354","#006837"],
7: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"],
8: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"],
9: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"]
},YlGnBu: {
3: ["#edf8b1","#7fcdbb","#2c7fb8"],
4: ["#ffffcc","#a1dab4","#41b6c4","#225ea8"],
5: ["#ffffcc","#a1dab4","#41b6c4","#2c7fb8","#253494"],
6: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#2c7fb8","#253494"],
7: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"],
8: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"],
9: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"]
},GnBu: {
3: ["#e0f3db","#a8ddb5","#43a2ca"],
4: ["#f0f9e8","#bae4bc","#7bccc4","#2b8cbe"],
5: ["#f0f9e8","#bae4bc","#7bccc4","#43a2ca","#0868ac"],
6: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#43a2ca","#0868ac"],
7: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"],
8: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"],
9: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"]
},BuGn: {
3: ["#e5f5f9","#99d8c9","#2ca25f"],
4: ["#edf8fb","#b2e2e2","#66c2a4","#238b45"],
5: ["#edf8fb","#b2e2e2","#66c2a4","#2ca25f","#006d2c"],
6: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#2ca25f","#006d2c"],
7: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"],
8: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"],
9: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"]
},PuBuGn: {
3: ["#ece2f0","#a6bddb","#1c9099"],
4: ["#f6eff7","#bdc9e1","#67a9cf","#02818a"],
5: ["#f6eff7","#bdc9e1","#67a9cf","#1c9099","#016c59"],
6: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#1c9099","#016c59"],
7: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"],
8: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"],
9: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"]
},PuBu: {
3: ["#ece7f2","#a6bddb","#2b8cbe"],
4: ["#f1eef6","#bdc9e1","#74a9cf","#0570b0"],
5: ["#f1eef6","#bdc9e1","#74a9cf","#2b8cbe","#045a8d"],
6: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#2b8cbe","#045a8d"],
7: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"],
8: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"],
9: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"]
},BuPu: {
3: ["#e0ecf4","#9ebcda","#8856a7"],
4: ["#edf8fb","#b3cde3","#8c96c6","#88419d"],
5: ["#edf8fb","#b3cde3","#8c96c6","#8856a7","#810f7c"],
6: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8856a7","#810f7c"],
7: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"],
8: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"],
9: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"]
},RdPu: {
3: ["#fde0dd","#fa9fb5","#c51b8a"],
4: ["#feebe2","#fbb4b9","#f768a1","#ae017e"],
5: ["#feebe2","#fbb4b9","#f768a1","#c51b8a","#7a0177"],
6: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#c51b8a","#7a0177"],
7: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"],
8: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"],
9: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"]
},PuRd: {
3: ["#e7e1ef","#c994c7","#dd1c77"],
4: ["#f1eef6","#d7b5d8","#df65b0","#ce1256"],
5: ["#f1eef6","#d7b5d8","#df65b0","#dd1c77","#980043"],
6: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#dd1c77","#980043"],
7: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"],
8: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"],
9: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"]
},OrRd: {
3: ["#fee8c8","#fdbb84","#e34a33"],
4: ["#fef0d9","#fdcc8a","#fc8d59","#d7301f"],
5: ["#fef0d9","#fdcc8a","#fc8d59","#e34a33","#b30000"],
6: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#e34a33","#b30000"],
7: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"],
8: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"],
9: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"]
},YlOrRd: {
3: ["#ffeda0","#feb24c","#f03b20"],
4: ["#ffffb2","#fecc5c","#fd8d3c","#e31a1c"],
5: ["#ffffb2","#fecc5c","#fd8d3c","#f03b20","#bd0026"],
6: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#f03b20","#bd0026"],
7: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"],
8: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"],
9: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"]
},YlOrBr: {
3: ["#fff7bc","#fec44f","#d95f0e"],
4: ["#ffffd4","#fed98e","#fe9929","#cc4c02"],
5: ["#ffffd4","#fed98e","#fe9929","#d95f0e","#993404"],
6: ["#ffffd4","#fee391","#fec44f","#fe9929","#d95f0e","#993404"],
7: ["#ffffd4","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"],
8: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"],
9: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"]
},Purples: {
3: ["#efedf5","#bcbddc","#756bb1"],
4: ["#f2f0f7","#cbc9e2","#9e9ac8","#6a51a3"],
5: ["#f2f0f7","#cbc9e2","#9e9ac8","#756bb1","#54278f"],
6: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#756bb1","#54278f"],
7: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"],
8: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"],
9: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"]
},Blues: {
3: ["#deebf7","#9ecae1","#3182bd"],
4: ["#eff3ff","#bdd7e7","#6baed6","#2171b5"],
5: ["#eff3ff","#bdd7e7","#6baed6","#3182bd","#08519c"],
6: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#3182bd","#08519c"],
7: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"],
8: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"],
9: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"]
},Greens: {
3: ["#e5f5e0","#a1d99b","#31a354"],
4: ["#edf8e9","#bae4b3","#74c476","#238b45"],
5: ["#edf8e9","#bae4b3","#74c476","#31a354","#006d2c"],
6: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#31a354","#006d2c"],
7: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"],
8: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"],
9: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"]
},Oranges: {
3: ["#fee6ce","#fdae6b","#e6550d"],
4: ["#feedde","#fdbe85","#fd8d3c","#d94701"],
5: ["#feedde","#fdbe85","#fd8d3c","#e6550d","#a63603"],
6: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#e6550d","#a63603"],
7: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"],
8: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"],
9: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"]
},Reds: {
3: ["#fee0d2","#fc9272","#de2d26"],
4: ["#fee5d9","#fcae91","#fb6a4a","#cb181d"],
5: ["#fee5d9","#fcae91","#fb6a4a","#de2d26","#a50f15"],
6: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#de2d26","#a50f15"],
7: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"],
8: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"],
9: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"]
},Greys: {
3: ["#f0f0f0","#bdbdbd","#636363"],
4: ["#f7f7f7","#cccccc","#969696","#525252"],
5: ["#f7f7f7","#cccccc","#969696","#636363","#252525"],
6: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#636363","#252525"],
7: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"],
8: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"],
9: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"]
},PuOr: {
3: ["#f1a340","#f7f7f7","#998ec3"],
4: ["#e66101","#fdb863","#b2abd2","#5e3c99"],
5: ["#e66101","#fdb863","#f7f7f7","#b2abd2","#5e3c99"],
6: ["#b35806","#f1a340","#fee0b6","#d8daeb","#998ec3","#542788"],
7: ["#b35806","#f1a340","#fee0b6","#f7f7f7","#d8daeb","#998ec3","#542788"],
8: ["#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788"],
9: ["#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788"],
10: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],
11: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"]
},BrBG: {
3: ["#d8b365","#f5f5f5","#5ab4ac"],
4: ["#a6611a","#dfc27d","#80cdc1","#018571"],
5: ["#a6611a","#dfc27d","#f5f5f5","#80cdc1","#018571"],
6: ["#8c510a","#d8b365","#f6e8c3","#c7eae5","#5ab4ac","#01665e"],
7: ["#8c510a","#d8b365","#f6e8c3","#f5f5f5","#c7eae5","#5ab4ac","#01665e"],
8: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e"],
9: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e"],
10: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],
11: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"]
},PRGn: {
3: ["#af8dc3","#f7f7f7","#7fbf7b"],
4: ["#7b3294","#c2a5cf","#a6dba0","#008837"],
5: ["#7b3294","#c2a5cf","#f7f7f7","#a6dba0","#008837"],
6: ["#762a83","#af8dc3","#e7d4e8","#d9f0d3","#7fbf7b","#1b7837"],
7: ["#762a83","#af8dc3","#e7d4e8","#f7f7f7","#d9f0d3","#7fbf7b","#1b7837"],
8: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837"],
9: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837"],
10: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],
11: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"]
},PiYG: {
3: ["#e9a3c9","#f7f7f7","#a1d76a"],
4: ["#d01c8b","#f1b6da","#b8e186","#4dac26"],
5: ["#d01c8b","#f1b6da","#f7f7f7","#b8e186","#4dac26"],
6: ["#c51b7d","#e9a3c9","#fde0ef","#e6f5d0","#a1d76a","#4d9221"],
7: ["#c51b7d","#e9a3c9","#fde0ef","#f7f7f7","#e6f5d0","#a1d76a","#4d9221"],
8: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221"],
9: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221"],
10: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],
11: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"]
},RdBu: {
3: ["#ef8a62","#f7f7f7","#67a9cf"],
4: ["#ca0020","#f4a582","#92c5de","#0571b0"],
5: ["#ca0020","#f4a582","#f7f7f7","#92c5de","#0571b0"],
6: ["#b2182b","#ef8a62","#fddbc7","#d1e5f0","#67a9cf","#2166ac"],
7: ["#b2182b","#ef8a62","#fddbc7","#f7f7f7","#d1e5f0","#67a9cf","#2166ac"],
8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac"],
9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac"],
10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],
11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"]
},RdGy: {
3: ["#ef8a62","#ffffff","#999999"],
4: ["#ca0020","#f4a582","#bababa","#404040"],
5: ["#ca0020","#f4a582","#ffffff","#bababa","#404040"],
6: ["#b2182b","#ef8a62","#fddbc7","#e0e0e0","#999999","#4d4d4d"],
7: ["#b2182b","#ef8a62","#fddbc7","#ffffff","#e0e0e0","#999999","#4d4d4d"],
8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d"],
9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d"],
10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],
11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"]
},RdYlBu: {
3: ["#fc8d59","#ffffbf","#91bfdb"],
4: ["#d7191c","#fdae61","#abd9e9","#2c7bb6"],
5: ["#d7191c","#fdae61","#ffffbf","#abd9e9","#2c7bb6"],
6: ["#d73027","#fc8d59","#fee090","#e0f3f8","#91bfdb","#4575b4"],
7: ["#d73027","#fc8d59","#fee090","#ffffbf","#e0f3f8","#91bfdb","#4575b4"],
8: ["#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4"],
9: ["#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4"],
10: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],
11: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"]
},Spectral: {
3: ["#fc8d59","#ffffbf","#99d594"],
4: ["#d7191c","#fdae61","#abdda4","#2b83ba"],
5: ["#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba"],
6: ["#d53e4f","#fc8d59","#fee08b","#e6f598","#99d594","#3288bd"],
7: ["#d53e4f","#fc8d59","#fee08b","#ffffbf","#e6f598","#99d594","#3288bd"],
8: ["#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd"],
9: ["#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd"],
10: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],
11: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"]
},RdYlGn: {
3: ["#fc8d59","#ffffbf","#91cf60"],
4: ["#d7191c","#fdae61","#a6d96a","#1a9641"],
5: ["#d7191c","#fdae61","#ffffbf","#a6d96a","#1a9641"],
6: ["#d73027","#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"],
7: ["#d73027","#fc8d59","#fee08b","#ffffbf","#d9ef8b","#91cf60","#1a9850"],
8: ["#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850"],
9: ["#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850"],
10: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],
11: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"]
},Accent: {
3: ["#7fc97f","#beaed4","#fdc086"],
4: ["#7fc97f","#beaed4","#fdc086","#ffff99"],
5: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0"],
6: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f"],
7: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17"],
8: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"]
},Dark2: {
3: ["#1b9e77","#d95f02","#7570b3"],
4: ["#1b9e77","#d95f02","#7570b3","#e7298a"],
5: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e"],
6: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02"],
7: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d"],
8: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"]
},Paired: {
3: ["#a6cee3","#1f78b4","#b2df8a"],
4: ["#a6cee3","#1f78b4","#b2df8a","#33a02c"],
5: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99"],
6: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c"],
7: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f"],
8: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00"],
9: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6"],
10: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a"],
11: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99"],
12: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"]
},Pastel1: {
3: ["#fbb4ae","#b3cde3","#ccebc5"],
4: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4"],
5: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6"],
6: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc"],
7: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd"],
8: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec"],
9: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]
},Pastel2: {
3: ["#b3e2cd","#fdcdac","#cbd5e8"],
4: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4"],
5: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9"],
6: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae"],
7: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc"],
8: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"]
},Set1: {
3: ["#e41a1c","#377eb8","#4daf4a"],
4: ["#e41a1c","#377eb8","#4daf4a","#984ea3"],
5: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00"],
6: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33"],
7: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628"],
8: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf"],
9: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"]
},Set2: {
3: ["#66c2a5","#fc8d62","#8da0cb"],
4: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3"],
5: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854"],
6: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f"],
7: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494"],
8: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"]
},Set3: {
3: ["#8dd3c7","#ffffb3","#bebada"],
4: ["#8dd3c7","#ffffb3","#bebada","#fb8072"],
5: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3"],
6: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462"],
7: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69"],
8: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5"],
9: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9"],
10: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd"],
11: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5"],
12: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"]
}};
////////////////////////////////////////////////////////////////////////////////
// Constructor
// id - name/id of the widget, this need to be unique
// w - width
// h - height
// label - text label for the widget
////////////////////////////////////////////////////////////////////////////////
function ListWidget(container, id, w, h, label) {
// Data
this.selectedTermsList = [];
// Position and size attributes
this.width = w;
this.height = h;
// Identifier attributes
this.container = container;
this.widgetId = id;
this.widgetLabelId = id + "_label";
// Label
this.labelName = label;
this.label = null;
// Reference to the widget and widget components
this.widget = null;
this.topIndicator = null;
this.bottomIndicator = null;
this.upArrow = null;
this.downArrow = null;
this.scrollbar = null;
this.scrollbarIndicator = null;
// Calculate the widget offsets, refer to
// ListWidget schematics...you are unlikely going to understand this.
// DO NOT CHANGE THE ORDER !!!!
this.rightMarginW = this.width * 0.1;
this.rightMarginH = this.height;
this.leftMarginW = this.width * 0.1;
this.leftMarginH = this.height;
this.topMarginH = this.height*0.15;
this.topMarginW = this.width - (this.rightMarginW + this.leftMarginW);
this.bottomMarginH = this.height*0.15;
this.bottomMarginW = this.width - (this.rightMarginW + this.leftMarginW);
this.topIndicatorH = this.height*0.015;
this.topIndicatorW = this.topMarginW;
this.bottomIndicatorH = this.height*0.015;
this.bottomIndicatorW = this.bottomMarginW;
this.contentW = this.width - (this.leftMarginW + this.rightMarginW);
this.contentH = this.height - (this.topMarginH + this.bottomMarginH + this.topIndicatorH + this.bottomIndicatorH);
this.upArrowW = this.rightMarginW;
this.upArrowH = this.rightMarginH*0.1;
this.downArrowW = this.rightMarginW;
this.downArrowH = this.rightMarginH*0.1;
this.scrollW = this.rightMarginW;
this.scrollH = this.contentH;
// Element attributes
this.barHeight = 20;
this.offset = 0;
this.barFont = "10px Verdana";
// Data used for display
this.displayData = [];
this.dataLength = 0;
// Function objects, these should be implemented by the controller
// Each components should get its own set of listeners,
// do not share unless there is a reason to
this.nothing = function() { console.log("Not implemented"); }; // DO NOT OVERRIDE THIS !!!
this.mouseoverFunc = this.nothing;
this.mouseoutFunc = this.nohintg;
this.mouseclickFunc = this.nothing;
this.root_action = this.nothing;
// Colours
this.colourIndicatorOff = d3.rgb(68, 68, 68);
this.colourIndicatorOn = d3.rgb(0, 170, 255);
this.colourCoordHighlight = d3.rgb(44, 127, 184);
this.colourText = d3.rgb(35, 35, 35);
this.colourArrow = d3.rgb(188, 188, 188);
this.colourArrowOutline = d3.rgb(222, 222, 222);
this.colourArrowHighlight = d3.rgb(0, 170, 255);
this.colourNormal = d3.rgb(245, 245, 245);
this.colourOutline = d3.rgb(55, 55, 55);
//this.colourNormal = d3.rgb(132, 77, 199);
this.colourSelected = d3.rgb(66, 132, 198);
// Chop off the first one (white) ... because it looks weird
this.colourHighlight = d3.scale.ordinal().domain([0, 1]).range(colorbrewer.Reds[8].slice(1));
//this.colourHighlight = d3.scale.ordinal().domain([0, 1]).range(colorbrewer.Purples[8]);
//this.colourHighlight = d3.scale.ordinal().domain([0, 1]).range(colorbrewer.YlOrRd[9]);
//this.colourHighlight = d3.rgb(255, 127, 0);
}
////////////////////////////////////////////////////////////////////////////////
// Prototype functions
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Initializes a container group and setup a scrollable transformation
// based on the number of items in displayData
////////////////////////////////////////////////////////////////////////////////
ListWidget.prototype.init = function() {
// Selft-reference
var myRef = this;
// Initialize the main container
this.widget = d3.select("#"+myRef.container).append("svg")
.attr("id", myRef.widgetId)
.attr("class", "taglist")
.attr("height", myRef.contentH+60)
.append("g")
.attr("transform", "translate(" + myRef.leftMarginW + "," + (myRef.topMarginH + myRef.topIndicatorH) + ")")
.append("g")
.append("svg")
.attr("width", myRef.contentW)
.attr("height", myRef.contentH)
.append("g")
.call(
d3.behavior.drag()
.on("drag", function(d, i) {
myRef.offset += d3.event.dy;
if (myRef.offset > 0)
myRef.offset = 0;
if (myRef.offset < -(myRef.displayData.length*myRef.barHeight)+myRef.contentH)
myRef.offset = Math.min(0, -(myRef.displayData.length*myRef.barHeight)+myRef.contentH);
d3.select(this).attr("transform", "translate(0," + myRef.offset +")");
var show = -myRef.offset / myRef.barHeight; // Number of items shown
var unit = myRef.contentH/myRef.displayData.length;
myRef.scrollbarIndicator.attr("y", show*unit + (myRef.topMarginH+myRef.topIndicatorH));
})
)
;
// Create a data-scroll indicator at the top of the widget
this.topIndicator = d3.select("#"+myRef.widgetId)
.append("rect")
.attr("class", "nav_indicator")
.attr("x", myRef.leftMarginW)
.attr("y", myRef.topMarginH)
.attr("width", myRef.contentW)
.attr("height", myRef.topIndicatorH)
.attr("fill", myRef.colourIndicatorOff)
;
// Create a data-scroll indicator at the bottom of the widget
this.bottomIndicator = d3.select("#"+myRef.widgetId)
.append("rect")
.attr("class", "nav_indicator")
.attr("x", myRef.leftMarginW)
.attr("y", (myRef.topMarginH+myRef.topIndicatorH+myRef.contentH))
.attr("width", myRef.contentW)
.attr("height", myRef.bottomIndicatorH)
.attr("fill", myRef.colourIndicatorOff)
;
// Create arrows
this.upArrow = d3.select("#"+myRef.widgetId)
.append("svg:path")
.attr("fill", this.colourArrow)
.attr("stroke", this.colourArrowOutline)
.attr("id", "upArrow")
.attr("transform", "translate(" + (myRef.width-0.5*myRef.rightMarginW) + "," + myRef.topMarginH + ")")
.attr("d", d3.svg.symbol().type("triangle-up").size(50))
.on("mouseover", function(d) { d3.select(this).attr("fill", myRef.colourArrowHighlight); })
.on("mouseout", function(d) { d3.select(this).attr("fill", myRef.colourArrow); })
.on("mousedown", function(d) {
d3.event.preventDefault();
d3.event.stopPropagation();
myRef.offset += myRef.barHeight;
if (myRef.offset > 0)
myRef.offset = 0;
if (myRef.offset < -(myRef.displayData.length*myRef.barHeight)+myRef.contentH)
myRef.offset = Math.min(0, -(myRef.displayData.length*myRef.barHeight)+myRef.contentH);
myRef.widget.attr("transform", "translate(0," + myRef.offset +")");
var show = -myRef.offset / myRef.barHeight; // Number of items shown
var unit = myRef.contentH/myRef.displayData.length;
myRef.scrollbarIndicator.attr("y", show*unit+(myRef.topMarginH+myRef.topIndicatorH));
})
;
this.downArrow = d3.select("#" + myRef.widgetId)
.append("svg:path")
.attr("fill", this.colourArrow)
.attr("stroke", this.colourArrowOutline)
.attr("id", "downArrow")
.attr("transform", "translate(" + (myRef.width-0.5*myRef.rightMarginW) + "," + (myRef.height-myRef.bottomMarginH) + ")")
.attr("d", d3.svg.symbol().type("triangle-down").size(50))
.on("mouseover", function(d) { d3.select(this).attr("fill", myRef.colourArrowHighlight); })
.on("mouseout", function(d) { d3.select(this).attr("fill", myRef.colourArrow); })
.on("mousedown", function(d) {
d3.event.preventDefault();
d3.event.stopPropagation();
myRef.offset -= myRef.barHeight;
if (myRef.offset > 0)
myRef.offset = 0;
if (myRef.offset < -(myRef.displayData.length*myRef.barHeight)+myRef.contentH)
myRef.offset = Math.min(0, -(myRef.displayData.length*myRef.barHeight)+myRef.contentH);
myRef.widget.attr("transform", "translate(0," + myRef.offset +")");
var show = -myRef.offset / myRef.barHeight; // Number of items shown
var unit = myRef.contentH/myRef.displayData.length;
myRef.scrollbarIndicator.attr("y", show*unit + (myRef.topMarginH+myRef.topIndicatorH));
})
;
this.scrollbar = d3.select("#" + myRef.widgetId)
.append("rect")
//.attr("transform", "translate(" + (20+this.width) + "," + 30 + ")")
.attr("x", (myRef.leftMarginW+myRef.contentW+0.5*myRef.rightMarginW)-1)
.attr("y", (myRef.topMarginH+myRef.topIndicatorH)+1)
.attr("width", 1)
.attr("height", myRef.scrollH-1)
.attr("fill", "#222222")
.style("opacity", 0.5)
;
this.scrollbarIndicator = d3.select("#" + myRef.widgetId)
.append("rect")
//.attr("transform", "translate(" + (19+this.width) + "," + 30 + ")")
.attr("x", (myRef.leftMarginW+myRef.contentW+0.5*myRef.rightMarginW) - 3)
.attr("y", (myRef.topMarginH+myRef.topIndicatorH))
.attr("width", 5)
.attr("height", 0)
.attr("fill", "#FFAA00")
.style("opacity", 0.8)
.call(
d3.behavior.drag()
.on("drag", function(d, i) {
var y1 = parseFloat(myRef.scrollbarIndicator.attr("y")) - (myRef.topMarginH+myRef.topIndicatorH);
var y2 = d3.event.dy;
var y3 = y1+y2;
var h = parseFloat(myRef.scrollbarIndicator.attr("height"));
y3 = Math.max(0, y3);
y3 = Math.min( (myRef.contentH-h), y3);
myRef.scrollbarIndicator.attr("y", y3 + (myRef.topMarginH+myRef.topIndicatorH));
var offset = (-y3/myRef.contentH)*myRef.barHeight*myRef.displayData.length;
myRef.offset = offset;
myRef.widget.attr("transform", "translate(0," + myRef.offset +")");
})
)
;
// Text tends to be a little quirky, we need a way to
// find out how tall they are, they are also not centred
// at the corner...
this.label = d3.select("#"+this.widgetId)
.append("g")
.attr("transform", "translate(" + myRef.leftMarginW + "," + 10 + ")")
;
}
////////////////////////////////////////////////////////////////////////////////
// Render
//
// We expect that the data is of the following format:
// [ {name:xxx, freq:xxx}, {name:xxx, freq:xxx} ]
////////////////////////////////////////////////////////////////////////////////
ListWidget.prototype.render = function( vdata ) {
// Reset the transformation
this.widget.attr("transform", "translate(0,0)");
this.offset = 0;
this.displayData = vdata;
this.dataLength = this.displayData.length;
var myRef = this;
var show = this.contentH / this.barHeight; // Number of items shown
var unit = this.contentH /this.displayData.length;
// TODO: Fix Sort
myRef.displayData = _.sortBy(myRef.displayData, function(item) {
var a_idx = myRef.selectedTermsList.indexOf(item.name);
if (a_idx === -1) return 1;
return 0;
});
/*
myRef.displayData = myRef.displayData.sort(function(a, b) {
var a_idx = myRef.selectedTermsList.indexOf(a.name);
var b_idx = myRef.selectedTermsList.indexOf(b.name);
if (a_idx === -1 && b_idx === -1) return b.freq-a.freq;
if (a_idx === -1 && b.idx !== -1) return -1;
if (a_idx !== -1 && b.idx === -1) return 1;
return b.freq-a.freq;
});
*/
// Remove the data nodes
this.widget.data([this.displayData] ).selectAll("rect").remove();
this.widget.data([this.displayData] ).selectAll("text").remove();
this.widget.data([this.displayData] ).selectAll("circle").remove();
this.label.selectAll("#label").remove();
// Calculate the max and min frequencies
var freqMax = Number.MIN_VALUE;
var freqMin = Number.MAX_VALUE;
for (var i=0; i < this.displayData.length; i++) {
if (this.displayData[i].freq > freqMax) freqMax = this.displayData[i].freq;
if (this.displayData[i].freq < freqMin) freqMin = this.displayData[i].freq;
}
//console.log("Max value = " + freqMax + " Min Value = " + freqMin);
this.label.append("text")
.attr("id", "label")
.attr("y", function(d,i) { return 10; })
.attr("dy", ".35em")
.style("fill", myRef.colourText)
.style("font", "16px sans-serif")
.text(this.labelName + this.dataLength)
;
// Render horizontal rectangle bars
this.widget.selectAll("rect")
.data(this.displayData.map(function(d,i) {
//if (typeof d == "object") return {val:d.name, freq:d.freq, idx:i};
if (typeof d == "object") return {val:d.name, freq:d.freq, idx:i};
return {val:d, freq:0, idx:i};
}))
.enter()
.append("rect")
.attr("id", "rectBar")
.attr("x", 20)
.attr("y", function(d, i) { return 1+i*myRef.barHeight; })
.attr("rx", 3)
.attr("ry", 3)
//.attr("width", function(d, i) { return 0; })
.attr("width", function(d, i) { return (myRef.contentW-30); })
.attr("height", myRef.barHeight-2)
.style("stroke", myRef.colourOutline)
.style("strke-width", "0.5")
.style("fill", function(d) {
if (myRef.selectedTermsList.indexOf(d.val) !== -1) {
d.c = myRef.colourSelected;
} else {
d.c = myRef.colourNormal;
}
return d.c;
})
.style("opacity", function(d) {
return 1.0;
/*
if (myRef.filter && d.val in myRef.filter) {
d.opacity = 1;
} else {
d.opacity = 0;
}
return d.opacity;
*/
})
.style("pointer-events", "none")
.style("cursor", "pointer")
.on("mouseover", myRef.mouseoverFunc)
.on("mouseout", myRef.mouseoutFunc)
.on("click", myRef.mouseclickFunc)
.transition()
.duration(1000)
.each("end", function(d, i) {
d3.select(this).style("pointer-events", "all")
;
})
;
// Render list of circles beside the bar that is sized with
// respect to the frequency
this.widget.selectAll("circle")
.data(this.displayData.map(function(d,i) {
if (typeof d == "object") return {val:d.name, freq:d.freq?d.freq:0, idx:i};
return {val:d, freq:0, idx:i};
}))
.enter()
.append("circle")
.attr("cy", function(d, i) { return i*myRef.barHeight+0.5*myRef.barHeight; })
.attr("cx", 10)
.attr("r", function(d, i) {
return 0;
/*
if (d.freq > 0) return 1 + 5*Math.sqrt( d.freq / freqMax);
else return 0;
*/
})
.attr("fill", function(d, i) {
return d3.rgb(0, 0, 0)
})
.style("opacity", function(d, i) {
if ( d.freq > 0) return 1;
return 0;
})
;
// Render text for bar
this.widget.selectAll("text")
.data(this.displayData.map(function(d,i) {
//if (typeof d == "object") return {val:d.name};
if (typeof d == "object") {
var tmp = d.name;
if (tmp.length > 20) tmp = tmp.substring(0,18) + "...";
return {val:tmp, freq:d.freq};
}
return {val:d};
}))
.enter()
.append("text")
.attr("y", function(d,i) { return i*myRef.barHeight+0.5*myRef.barHeight; })
.attr("x", 25)
.attr("dy", ".35em")
.style("fill", myRef.colourText)
//.style("font", compute_font(13))
.style("font", myRef.barFont)
.style("pointer-events", "none")
.text(function(d) { return d.val + " (" + d.freq + ")";})
;
this.scrollbarIndicator.attr("y", (myRef.topMarginH+myRef.topIndicatorH)).attr("height", Math.min(myRef.contentH, show*unit));
}
////////////////////////////////////////////////////////////////////////////////
// Highlight
////////////////////////////////////////////////////////////////////////////////
ListWidget.prototype.highlight = function( termList, termFreqList, selected ) {
var myRef = this;
var termMax = _.max(termFreqList);
myRef.widget.selectAll("rect")
.filter(function(d, i) {
var contained = termList.indexOf(d.val) !== -1;
if (contained === true) {
if (i*myRef.barHeight + myRef.offset < 0)
myRef.topIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOn);
if (i*myRef.barHeight + myRef.offset > myRef.contentH)
myRef.bottomIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOn);
}
return contained;
})
.transition()
.duration(300)
.style("fill", function(d, i) {
if (d.val === selected) return myRef.colourSelected;
var idx = termList.indexOf(d.val);
var freq = termFreqList[idx];
var power = freq / termMax;
return myRef.colourHighlight(power);
});
/*
.style("opacity", function(d, i) {
if (d.val === selected) return 1.0;
var idx = termList.indexOf(d.val);
var freq = termFreqList[idx];
var ratio = freq / termMax;
return 0.5 + 0.5*ratio;
});
*/
};
ListWidget.prototype.unHighlight = function() {
var myRef = this;
myRef.widget.selectAll("rect")
.style("fill", function(d) { return d.c; })
.style("opacity", 1);
myRef.topIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOff);
myRef.bottomIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOff);
}
////////////////////////////////////////////////////////////////////////////////
// Highlight the list widget with respect to a corresponding
// artifact
//
// ar - an artifact node
////////////////////////////////////////////////////////////////////////////////
ListWidget.prototype.highlight2 = function( ar ) {
var myRef = this;
// Pre-compute whether each entity will take part, this way
// we can reuse it for various elements in the widget rather
// than re-calculating
// Check if list item is in artifact(ar)'s entity list
// if yes then push in true, else false
var flags = [];
for (var i = 0; i < this.displayData.length; i ++) {
flags.push( DataParser.containsEntity(ar, this.displayData[i].name));
}
// High light the circles
this.widget.selectAll("circle")
.transition()
.duration(300)
.attr("fill", function(d, i) {
if ( flags[i] ) return d3.rgb(255, 128, 0);
return d3.rgb(0, 0, 0);
})
;
// High light the bars
this.widget.selectAll("#rectBar")
.transition()
.duration(300)
.attr("fill", function(d, i) {
if (flags[i]) {
//top
if (i*myRef.barHeight + myRef.offset < 0)
myRef.topIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOn);
//bottom
if (i*myRef.barHeight + myRef.offset > myRef.contentH)
myRef.bottomIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOn);
return d.c;
}
//return null;
return d.c;
})
.style("opacity", function(d, i) {
if (flags[i]) {
return 1.0;
}
return d.opacity;
})
;
this.widget.selectAll("text")
.transition()
.duration(300)
.style("fill", function(d, i) {
if (flags[i]) {
return myRef.colourText;
}
return myRef.colourText;
})
;
// Reset the indicators on mouse out
if ( ar == null) {
myRef.topIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOff);
myRef.bottomIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOff);
}
}
////////////////////////////////////////////////////////////////////////////////
// Highlight the coordianted brushing stuff
//
// selected - An associated array containing the currently selected
// filters
// coord - An associated array or the related entities in
// the form { entity1:occ, entity2:occ, ...}
////////////////////////////////////////////////////////////////////////////////
ListWidget.prototype.coordHighlight = function( selected, coord ) {
var myRef = this;
// Pre-compute the max and min for the co-occurring entities
var coordMax = Number.MIN_VALUE;
var coordMin = Number.MAX_VALUE;
if (coord != null) {
for (var e in coord) {
if (coord[e].freq > coordMax) { coordMax = coord[e].freq; }
if (coord[e].freq < coordMin) { coordMin = coord[e].freq; }
}
} else {
// Just in case...don't want a divide by zero here
coordMax = 1;
coordMin = 1;
}
//console.log("max : " + coordMax);
//console.log("min : " + coordMin);
this.widget.selectAll("circle")
.transition()
.duration(300)
.attr("fill", function(d, i) {
if (selected == null && coord == null) return d.c;
if (selected[ d.val ] ) {
return d3.rgb(255, 128, 0);
} else if (coord[ d.val ] && ! selected[ d.val ]) {
//top
if (i*myRef.barHeight + myRef.offset < 0) {
myRef.topIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOn);
}
//bottom
if (i*myRef.barHeight + myRef.offset > myRef.contentH) {
myRef.bottomIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOn);
}
return myRef.colourCoordHighlight;
}
return d.c;
})
.style("opacity", function(d, i) {
if ( coord != null && coord[ d.val ] ) {
return (coord[d.val].freq - coordMin + 1)/( coordMax - coordMin + 1);
}
return 1;
})
;
this.widget.selectAll("#rectBar")
.transition()
.duration(300)
.attr("fill", function(d, i) {
if (selected == null && coord == null) return d.c;
if (selected[ d.val ] || (myRef.filter && d.val in myRef.filter) ) {
return d.c;
} else if (coord[ d.val ] && ! selected[ d.val ]) {
//top
if (i*myRef.barHeight + myRef.offset < 0) {
myRef.topIndicator.attr("fill", myRef.colourIndicatorOn);
}
//bottom
if (i*myRef.barHeight + myRef.offset > myRef.contentH) {
myRef.bottomIndicator.attr("fill", myRef.colourIndicatorOn);
}
return myRef.colourCoordHighlight;
}
return d.c;
})
.style("opacity", function(d, i) {
if (myRef.filter && d.val in myRef.filter) return d.opacity;
if (selected == null && coord == null) return d.opacity;
if (selected[d.val]) {
return 1.0;
}
// Intensity Formula
// Linear : I = (freq - min + 1)/ (max - min + 1)
if (coord[ d.val ] ) {
return (coord[d.val].freq - coordMin + 1)/( coordMax - coordMin + 1);
}
return d.opacity;
})
;
this.widget.selectAll("text")
.transition()
.duration(300)
.style("fill", function(d, i) {
if (selected == null && coord == null) return myRef.colourText;
if (coord[ d.val ] || selected[ d.val ] ) {
return myRef.colourText;
}
return myRef.colourText;
})
;
// Reset the indicators on mouse out
if (selected == null && coord == null) {
myRef.topIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOff);
myRef.bottomIndicator.transition().duration(300).attr("fill", myRef.colourIndicatorOff);
}
}
var widget = new ListWidget("list1", "Test", 200, 300, "# items: ");
widget.init();
widget.render( [
{ name:'a', freq:1 },
{ name:'b', freq:1 },
{ name:'c', freq:1 },
{ name:'d', freq:1 },
{ name:'e', freq:1 },
{ name:'f', freq:1 },
{ name:'g', freq:1 },
{ name:'h', freq:1 },
{ name:'i', freq:1 },
{ name:'j', freq:1 },
{ name:'k', freq:1 },
{ name:'l', freq:1 },
{ name:'m', freq:1 },
{ name:'n', freq:1 },
{ name:'o', freq:1 },
{ name:'p', freq:1 },
{ name:'q', freq:1 },
{ name:'r', freq:1 }
])
var x = d3.select('#blahblah').append('g');
x.append('text').attr('x', 20).attr('y', 35).style('font-size', 30).text('a').on('mouseover', function() {
widget.highlight( ['a'], [100], null);
}).on('mouseout', function() {
widget.unHighlight();
});
x.append('text').attr('x', 40).attr('y', 35).style('font-size', 30).text('q').on('mouseover', function() {
widget.highlight( ['q'], [100], null);
}).on('mouseout', function() {
widget.unHighlight();
});
// widget.highlight( ['q'], [100], null);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment