├── .gitignore ├── README.md ├── app.js ├── bin └── www ├── data └── ndx.csv ├── package.json ├── public ├── javascripts │ ├── app.js │ └── colorbrewer.js └── stylesheets │ └── style.css ├── routes ├── index.js └── users.js └── views ├── error.jade ├── index.jade └── layout.jade /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | node_modules 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dc.js-server-side-crossfilter 2 | Uses crossfilter on the server to render dc.js charts 3 | 4 | 5 | ## Running 6 | * git clone the repo 7 | * run `npm install` 8 | * Open `localhost:3000` 9 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | var anyToJSON = require('anytojson'); 8 | var crossfilter = require('crossfilter'); 9 | var d3 = require('d3'); 10 | 11 | var routes = require('./routes/index'); 12 | var users = require('./routes/users'); 13 | 14 | var app = express(); 15 | 16 | // view engine setup 17 | app.set('views', path.join(__dirname, 'views')); 18 | app.set('view engine', 'jade'); 19 | 20 | // uncomment after placing your favicon in /public 21 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 22 | app.use(logger('dev')); 23 | app.use(bodyParser.json()); 24 | app.use(bodyParser.urlencoded({ extended: false })); 25 | app.use(cookieParser()); 26 | app.use(express.static(path.join(__dirname, 'public'))); 27 | 28 | 29 | var dimensions = {}; 30 | var groups = {}; 31 | 32 | app.get("/refresh", function(req, res, next){ 33 | var results = {}; 34 | filter = req.param("filter") ? JSON.parse(req.param("filter")) : {} 35 | console.log(filter); 36 | for(dimension in groups){ 37 | console.log(dimension); 38 | var group = groups[dimension]; 39 | if(filter[dimension]){ 40 | console.log(dimension); 41 | dimensions[dimension].filter(filter[dimension]); 42 | } 43 | results[dimension]= {values:group.all(),top: group.top(1)[0].value}; 44 | } 45 | res.writeHead(200, { 'content-type': 'application/json' }); 46 | res.end((JSON.stringify(results))); 47 | 48 | }); 49 | 50 | 51 | 52 | app.use('/', routes); 53 | app.use('/users', users); 54 | 55 | // catch 404 and forward to error handler 56 | app.use(function(req, res, next) { 57 | var err = new Error('Not Found'); 58 | err.status = 404; 59 | next(err); 60 | }); 61 | 62 | // error handlers 63 | 64 | // development error handler 65 | // will print stacktrace 66 | if (app.get('env') === 'development') { 67 | app.use(function(err, req, res, next) { 68 | res.status(err.status || 500); 69 | res.render('error', { 70 | message: err.message, 71 | error: err 72 | }); 73 | }); 74 | } 75 | 76 | // production error handler 77 | // no stacktraces leaked to user 78 | app.use(function(err, req, res, next) { 79 | res.status(err.status || 500); 80 | res.render('error', { 81 | message: err.message, 82 | error: {} 83 | }); 84 | }); 85 | 86 | 87 | anyToJSON.csv({path: "data/ndx.csv"}, function(data){ 88 | var dateFormat = d3.time.format('%m/%d/%Y'); 89 | var numberFormat = d3.format('.2f'); 90 | 91 | data.forEach(function (d) { 92 | d.dd = dateFormat.parse(d.date); 93 | d.month = d3.time.month(d.dd); // pre-calculate month for better performance 94 | d.close = +d.close; // coerce to number 95 | d.open = +d.open; 96 | }); 97 | //console.log(data); 98 | 99 | 100 | var ndx = crossfilter(data); 101 | var all = ndx.groupAll(); 102 | console.log("..."); 103 | var dimension = ndx.dimension(function(d){return d.open}); 104 | var group = dimension.group(); 105 | 106 | 107 | 108 | 109 | //### Create Crossfilter Dimensions and Groups 110 | 111 | //See the [crossfilter API](https://github.com/square/crossfilter/wiki/API-Reference) for reference. 112 | var ndx = crossfilter(data); 113 | var all = ndx.groupAll(); 114 | 115 | // Dimension by year 116 | var yearlyDimension = ndx.dimension(function (d) { 117 | return d3.time.year(d.dd).getFullYear(); 118 | }); 119 | // Maintain running tallies by year as filters are applied or removed 120 | var yearlyPerformanceGroup = yearlyDimension.group().reduce( 121 | /* callback for when data is added to the current filter results */ 122 | function (p, v) { 123 | ++p.count; 124 | p.absGain += v.close - v.open; 125 | p.fluctuation += Math.abs(v.close - v.open); 126 | p.sumIndex += (v.open + v.close) / 2; 127 | p.avgIndex = p.sumIndex / p.count; 128 | p.percentageGain = p.avgIndex ? (p.absGain / p.avgIndex) * 100 : 0; 129 | p.fluctuationPercentage = p.avgIndex ? (p.fluctuation / p.avgIndex) * 100 : 0; 130 | return p; 131 | }, 132 | /* callback for when data is removed from the current filter results */ 133 | function (p, v) { 134 | --p.count; 135 | p.absGain -= v.close - v.open; 136 | p.fluctuation -= Math.abs(v.close - v.open); 137 | p.sumIndex -= (v.open + v.close) / 2; 138 | p.avgIndex = p.count ? p.sumIndex / p.count : 0; 139 | p.percentageGain = p.avgIndex ? (p.absGain / p.avgIndex) * 100 : 0; 140 | p.fluctuationPercentage = p.avgIndex ? (p.fluctuation / p.avgIndex) * 100 : 0; 141 | return p; 142 | }, 143 | /* initialize p */ 144 | function () { 145 | return { 146 | count: 0, 147 | absGain: 0, 148 | fluctuation: 0, 149 | fluctuationPercentage: 0, 150 | sumIndex: 0, 151 | avgIndex: 0, 152 | percentageGain: 0 153 | }; 154 | } 155 | ); 156 | // Dimension by full date 157 | var dateDimension = ndx.dimension(function (d) { 158 | return d.dd; 159 | }); 160 | 161 | // Dimension by month 162 | var moveMonths = ndx.dimension(function (d) { 163 | return d.month; 164 | }); 165 | // Group by total movement within month 166 | var monthlyMoveGroup = moveMonths.group().reduceSum(function (d) { 167 | return Math.abs(d.close - d.open); 168 | }); 169 | // Group by total volume within move, and scale down result 170 | var volumeByMonthGroup = moveMonths.group().reduceSum(function (d) { 171 | return d.volume / 500000; 172 | }); 173 | var indexAvgByMonthGroup = moveMonths.group().reduce( 174 | function (p, v) { 175 | ++p.days; 176 | p.total += (v.open + v.close) / 2; 177 | p.avg = Math.round(p.total / p.days); 178 | return p; 179 | }, 180 | function (p, v) { 181 | --p.days; 182 | p.total -= (v.open + v.close) / 2; 183 | p.avg = p.days ? Math.round(p.total / p.days) : 0; 184 | return p; 185 | }, 186 | function () { 187 | return {days: 0, total: 0, avg: 0}; 188 | } 189 | ); 190 | // Create categorical dimension 191 | var gainOrLoss = ndx.dimension(function (d) { 192 | return d.open > d.close ? 'Loss' : 'Gain'; 193 | }); 194 | // Produce counts records in the dimension 195 | var gainOrLossGroup = gainOrLoss.group(); 196 | 197 | // Determine a histogram of percent changes 198 | var fluctuation = ndx.dimension(function (d) { 199 | return Math.round((d.close - d.open) / d.open * 100); 200 | }); 201 | var fluctuationGroup = fluctuation.group(); 202 | 203 | // Summarize volume by quarter 204 | var quarter = ndx.dimension(function (d) { 205 | var month = d.dd.getMonth(); 206 | if (month <= 2) { 207 | return 'Q1'; 208 | } else if (month > 2 && month <= 5) { 209 | return 'Q2'; 210 | } else if (month > 5 && month <= 8) { 211 | return 'Q3'; 212 | } else { 213 | return 'Q4'; 214 | } 215 | }); 216 | var quarterGroup = quarter.group().reduceSum(function (d) { 217 | return d.volume; 218 | }); 219 | // Counts per weekday 220 | var dayOfWeek = ndx.dimension(function (d) { 221 | var day = d.dd.getDay(); 222 | var name = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 223 | return day + '.' + name[day]; 224 | }); 225 | var dayOfWeekGroup = dayOfWeek.group(); 226 | 227 | console.log(dimension); 228 | dimensions.yearlyDimension = yearlyDimension; 229 | dimensions.dayOfWeekGroup = dayOfWeek; 230 | 231 | groups.yearlyPerformanceGroup = yearlyPerformanceGroup; 232 | groups.monthlyMoveGroup = monthlyMoveGroup; 233 | groups.volumeByMonthGroup = volumeByMonthGroup; 234 | groups.indexAvgByMonthGroup = indexAvgByMonthGroup; 235 | groups.quarterGroup = quarterGroup; 236 | groups.dayOfWeekGroup = dayOfWeekGroup; 237 | 238 | 239 | }); 240 | 241 | module.exports = app; 242 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('dcServer:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dcServer", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "anytojson": "^2.0.6", 10 | "body-parser": "~1.13.2", 11 | "cookie-parser": "~1.3.5", 12 | "crossfilter": "^1.3.12", 13 | "d3": "^3.5.6", 14 | "debug": "~2.2.0", 15 | "express": "~4.13.1", 16 | "jade": "~1.11.0", 17 | "morgan": "~1.10.0", 18 | "serve-favicon": "~2.3.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/javascripts/app.js: -------------------------------------------------------------------------------- 1 | var dayOfWeekChart = dc.rowChart("#day-of-week-chart"); 2 | 3 | var filteredData = {}; 4 | var queryFilter = {}; 5 | 6 | var dateFormat = d3.time.format('%m/%d/%Y'); 7 | var numberFormat = d3.format('.2f'); 8 | 9 | 10 | var refresh = function(queryFilter){ 11 | d3.json("/refresh?filter="+JSON.stringify(queryFilter), function(d){ 12 | console.log(d); 13 | filteredData = d; 14 | //init(); 15 | }); 16 | } 17 | 18 | var dayOfWeekDim = { 19 | filter: function(f){ 20 | if(f){ 21 | queryFilter["dayOfWeekGroup"]=f; 22 | refresh(queryFilter); 23 | } 24 | }, 25 | filterAll: function(){ 26 | 27 | } 28 | }; 29 | var dayOfWeekGroup = { 30 | all: function(){ 31 | console.log(filteredData); 32 | return filteredData["dayOfWeekGroup"].values; 33 | }, 34 | order: function(){ 35 | 36 | }, 37 | top: function(){ 38 | } 39 | }; 40 | 41 | dayOfWeekChart.width(280) 42 | .height(300) 43 | .dimension(dayOfWeekDim) 44 | .group(dayOfWeekGroup) 45 | .renderLabel(true) 46 | .elasticX(true) 47 | .margins({top: 10, right: 20, bottom: 20, left: 20}) 48 | dayOfWeekChart.filterHandler(function(dimension, filters){ 49 | if(filters) 50 | dimension.filter(filters); 51 | else 52 | dimension.filter(null); 53 | return filters; 54 | }); 55 | 56 | 57 | var yearlyDimension = { 58 | filter: function(f){ 59 | if(f){ 60 | queryFilter["yearlyDimension"]=f; 61 | refresh(queryFilter); 62 | } 63 | }, 64 | filterAll: function(){ 65 | 66 | } 67 | }; 68 | 69 | var yearlyPerformanceGroup = { 70 | all: function(){ 71 | console.log(filteredData); 72 | return filteredData["yearlyPerformanceGroup"].values; 73 | }, 74 | order: function(){ 75 | 76 | }, 77 | top: function(){ 78 | } 79 | }; 80 | 81 | 82 | var yearlyBubbleChart = dc.bubbleChart("#yearly-bubble-chart"); 83 | yearlyBubbleChart.width(900) 84 | .height(250) 85 | .transitionDuration(1500) 86 | .margins({top: 10, right: 50, bottom: 30, left: 40}) 87 | .dimension(yearlyDimension) 88 | .group(yearlyPerformanceGroup) 89 | .colors(colorbrewer.RdYlGn[9]) 90 | .colorDomain([-500, 500]) 91 | .colorAccessor(function (d) { 92 | return d.value.absGain; 93 | }) 94 | .keyAccessor(function (p) { 95 | return p.value.absGain; 96 | }) 97 | .valueAccessor(function (p) { 98 | return p.value.percentageGain; 99 | }) 100 | .radiusValueAccessor(function (p) { 101 | return p.value.fluctuationPercentage; 102 | }) 103 | .renderLabel(true) 104 | .label(function (p) { 105 | return p.key; 106 | }) 107 | .renderTitle(true) 108 | .maxBubbleRelativeSize(0.3) 109 | .x(d3.scale.linear().domain([-2500, 2500])) 110 | .y(d3.scale.linear().domain([-100, 100])) 111 | .r(d3.scale.linear().domain([0, 4000])) 112 | .title(function (p) { 113 | return [ 114 | p.key, 115 | 'Index Gain: ' + numberFormat(p.value.absGain), 116 | 'Index Gain in Percentage: ' + numberFormat(p.value.percentageGain) + '%', 117 | 'Fluctuation / Index Ratio: ' + numberFormat(p.value.fluctuationPercentage) + '%' 118 | ].join('\n'); 119 | }) 120 | 121 | function init(){ 122 | 123 | d3.json("/refresh?filter={}", function(d){ 124 | filteredData = d; 125 | dc.renderAll(); 126 | //init(); 127 | }); 128 | } 129 | 130 | init(); 131 | -------------------------------------------------------------------------------- /public/javascripts/colorbrewer.js: -------------------------------------------------------------------------------- 1 | colorbrewer = {YlGn: { 2 | 3: ["#f7fcb9","#addd8e","#31a354"], 3 | 4: ["#ffffcc","#c2e699","#78c679","#238443"], 4 | 5: ["#ffffcc","#c2e699","#78c679","#31a354","#006837"], 5 | 6: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#31a354","#006837"], 6 | 7: ["#ffffcc","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"], 7 | 8: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"], 8 | 9: ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"] 9 | },YlGnBu: { 10 | 3: ["#edf8b1","#7fcdbb","#2c7fb8"], 11 | 4: ["#ffffcc","#a1dab4","#41b6c4","#225ea8"], 12 | 5: ["#ffffcc","#a1dab4","#41b6c4","#2c7fb8","#253494"], 13 | 6: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#2c7fb8","#253494"], 14 | 7: ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"], 15 | 8: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"], 16 | 9: ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"] 17 | },GnBu: { 18 | 3: ["#e0f3db","#a8ddb5","#43a2ca"], 19 | 4: ["#f0f9e8","#bae4bc","#7bccc4","#2b8cbe"], 20 | 5: ["#f0f9e8","#bae4bc","#7bccc4","#43a2ca","#0868ac"], 21 | 6: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#43a2ca","#0868ac"], 22 | 7: ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"], 23 | 8: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"], 24 | 9: ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"] 25 | },BuGn: { 26 | 3: ["#e5f5f9","#99d8c9","#2ca25f"], 27 | 4: ["#edf8fb","#b2e2e2","#66c2a4","#238b45"], 28 | 5: ["#edf8fb","#b2e2e2","#66c2a4","#2ca25f","#006d2c"], 29 | 6: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#2ca25f","#006d2c"], 30 | 7: ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"], 31 | 8: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"], 32 | 9: ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"] 33 | },PuBuGn: { 34 | 3: ["#ece2f0","#a6bddb","#1c9099"], 35 | 4: ["#f6eff7","#bdc9e1","#67a9cf","#02818a"], 36 | 5: ["#f6eff7","#bdc9e1","#67a9cf","#1c9099","#016c59"], 37 | 6: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#1c9099","#016c59"], 38 | 7: ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"], 39 | 8: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"], 40 | 9: ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"] 41 | },PuBu: { 42 | 3: ["#ece7f2","#a6bddb","#2b8cbe"], 43 | 4: ["#f1eef6","#bdc9e1","#74a9cf","#0570b0"], 44 | 5: ["#f1eef6","#bdc9e1","#74a9cf","#2b8cbe","#045a8d"], 45 | 6: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#2b8cbe","#045a8d"], 46 | 7: ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"], 47 | 8: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"], 48 | 9: ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"] 49 | },BuPu: { 50 | 3: ["#e0ecf4","#9ebcda","#8856a7"], 51 | 4: ["#edf8fb","#b3cde3","#8c96c6","#88419d"], 52 | 5: ["#edf8fb","#b3cde3","#8c96c6","#8856a7","#810f7c"], 53 | 6: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8856a7","#810f7c"], 54 | 7: ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"], 55 | 8: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"], 56 | 9: ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"] 57 | },RdPu: { 58 | 3: ["#fde0dd","#fa9fb5","#c51b8a"], 59 | 4: ["#feebe2","#fbb4b9","#f768a1","#ae017e"], 60 | 5: ["#feebe2","#fbb4b9","#f768a1","#c51b8a","#7a0177"], 61 | 6: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#c51b8a","#7a0177"], 62 | 7: ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"], 63 | 8: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"], 64 | 9: ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"] 65 | },PuRd: { 66 | 3: ["#e7e1ef","#c994c7","#dd1c77"], 67 | 4: ["#f1eef6","#d7b5d8","#df65b0","#ce1256"], 68 | 5: ["#f1eef6","#d7b5d8","#df65b0","#dd1c77","#980043"], 69 | 6: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#dd1c77","#980043"], 70 | 7: ["#f1eef6","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"], 71 | 8: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"], 72 | 9: ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"] 73 | },OrRd: { 74 | 3: ["#fee8c8","#fdbb84","#e34a33"], 75 | 4: ["#fef0d9","#fdcc8a","#fc8d59","#d7301f"], 76 | 5: ["#fef0d9","#fdcc8a","#fc8d59","#e34a33","#b30000"], 77 | 6: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#e34a33","#b30000"], 78 | 7: ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"], 79 | 8: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"], 80 | 9: ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"] 81 | },YlOrRd: { 82 | 3: ["#ffeda0","#feb24c","#f03b20"], 83 | 4: ["#ffffb2","#fecc5c","#fd8d3c","#e31a1c"], 84 | 5: ["#ffffb2","#fecc5c","#fd8d3c","#f03b20","#bd0026"], 85 | 6: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#f03b20","#bd0026"], 86 | 7: ["#ffffb2","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"], 87 | 8: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"], 88 | 9: ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"] 89 | },YlOrBr: { 90 | 3: ["#fff7bc","#fec44f","#d95f0e"], 91 | 4: ["#ffffd4","#fed98e","#fe9929","#cc4c02"], 92 | 5: ["#ffffd4","#fed98e","#fe9929","#d95f0e","#993404"], 93 | 6: ["#ffffd4","#fee391","#fec44f","#fe9929","#d95f0e","#993404"], 94 | 7: ["#ffffd4","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"], 95 | 8: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"], 96 | 9: ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"] 97 | },Purples: { 98 | 3: ["#efedf5","#bcbddc","#756bb1"], 99 | 4: ["#f2f0f7","#cbc9e2","#9e9ac8","#6a51a3"], 100 | 5: ["#f2f0f7","#cbc9e2","#9e9ac8","#756bb1","#54278f"], 101 | 6: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#756bb1","#54278f"], 102 | 7: ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"], 103 | 8: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"], 104 | 9: ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"] 105 | },Blues: { 106 | 3: ["#deebf7","#9ecae1","#3182bd"], 107 | 4: ["#eff3ff","#bdd7e7","#6baed6","#2171b5"], 108 | 5: ["#eff3ff","#bdd7e7","#6baed6","#3182bd","#08519c"], 109 | 6: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#3182bd","#08519c"], 110 | 7: ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"], 111 | 8: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"], 112 | 9: ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"] 113 | },Greens: { 114 | 3: ["#e5f5e0","#a1d99b","#31a354"], 115 | 4: ["#edf8e9","#bae4b3","#74c476","#238b45"], 116 | 5: ["#edf8e9","#bae4b3","#74c476","#31a354","#006d2c"], 117 | 6: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#31a354","#006d2c"], 118 | 7: ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"], 119 | 8: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"], 120 | 9: ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"] 121 | },Oranges: { 122 | 3: ["#fee6ce","#fdae6b","#e6550d"], 123 | 4: ["#feedde","#fdbe85","#fd8d3c","#d94701"], 124 | 5: ["#feedde","#fdbe85","#fd8d3c","#e6550d","#a63603"], 125 | 6: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#e6550d","#a63603"], 126 | 7: ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"], 127 | 8: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"], 128 | 9: ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"] 129 | },Reds: { 130 | 3: ["#fee0d2","#fc9272","#de2d26"], 131 | 4: ["#fee5d9","#fcae91","#fb6a4a","#cb181d"], 132 | 5: ["#fee5d9","#fcae91","#fb6a4a","#de2d26","#a50f15"], 133 | 6: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#de2d26","#a50f15"], 134 | 7: ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"], 135 | 8: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"], 136 | 9: ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"] 137 | },Greys: { 138 | 3: ["#f0f0f0","#bdbdbd","#636363"], 139 | 4: ["#f7f7f7","#cccccc","#969696","#525252"], 140 | 5: ["#f7f7f7","#cccccc","#969696","#636363","#252525"], 141 | 6: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#636363","#252525"], 142 | 7: ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"], 143 | 8: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"], 144 | 9: ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"] 145 | },PuOr: { 146 | 3: ["#f1a340","#f7f7f7","#998ec3"], 147 | 4: ["#e66101","#fdb863","#b2abd2","#5e3c99"], 148 | 5: ["#e66101","#fdb863","#f7f7f7","#b2abd2","#5e3c99"], 149 | 6: ["#b35806","#f1a340","#fee0b6","#d8daeb","#998ec3","#542788"], 150 | 7: ["#b35806","#f1a340","#fee0b6","#f7f7f7","#d8daeb","#998ec3","#542788"], 151 | 8: ["#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788"], 152 | 9: ["#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788"], 153 | 10: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"], 154 | 11: ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"] 155 | },BrBG: { 156 | 3: ["#d8b365","#f5f5f5","#5ab4ac"], 157 | 4: ["#a6611a","#dfc27d","#80cdc1","#018571"], 158 | 5: ["#a6611a","#dfc27d","#f5f5f5","#80cdc1","#018571"], 159 | 6: ["#8c510a","#d8b365","#f6e8c3","#c7eae5","#5ab4ac","#01665e"], 160 | 7: ["#8c510a","#d8b365","#f6e8c3","#f5f5f5","#c7eae5","#5ab4ac","#01665e"], 161 | 8: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e"], 162 | 9: ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e"], 163 | 10: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"], 164 | 11: ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"] 165 | },PRGn: { 166 | 3: ["#af8dc3","#f7f7f7","#7fbf7b"], 167 | 4: ["#7b3294","#c2a5cf","#a6dba0","#008837"], 168 | 5: ["#7b3294","#c2a5cf","#f7f7f7","#a6dba0","#008837"], 169 | 6: ["#762a83","#af8dc3","#e7d4e8","#d9f0d3","#7fbf7b","#1b7837"], 170 | 7: ["#762a83","#af8dc3","#e7d4e8","#f7f7f7","#d9f0d3","#7fbf7b","#1b7837"], 171 | 8: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837"], 172 | 9: ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837"], 173 | 10: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"], 174 | 11: ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"] 175 | },PiYG: { 176 | 3: ["#e9a3c9","#f7f7f7","#a1d76a"], 177 | 4: ["#d01c8b","#f1b6da","#b8e186","#4dac26"], 178 | 5: ["#d01c8b","#f1b6da","#f7f7f7","#b8e186","#4dac26"], 179 | 6: ["#c51b7d","#e9a3c9","#fde0ef","#e6f5d0","#a1d76a","#4d9221"], 180 | 7: ["#c51b7d","#e9a3c9","#fde0ef","#f7f7f7","#e6f5d0","#a1d76a","#4d9221"], 181 | 8: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221"], 182 | 9: ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221"], 183 | 10: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"], 184 | 11: ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"] 185 | },RdBu: { 186 | 3: ["#ef8a62","#f7f7f7","#67a9cf"], 187 | 4: ["#ca0020","#f4a582","#92c5de","#0571b0"], 188 | 5: ["#ca0020","#f4a582","#f7f7f7","#92c5de","#0571b0"], 189 | 6: ["#b2182b","#ef8a62","#fddbc7","#d1e5f0","#67a9cf","#2166ac"], 190 | 7: ["#b2182b","#ef8a62","#fddbc7","#f7f7f7","#d1e5f0","#67a9cf","#2166ac"], 191 | 8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac"], 192 | 9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac"], 193 | 10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"], 194 | 11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"] 195 | },RdGy: { 196 | 3: ["#ef8a62","#ffffff","#999999"], 197 | 4: ["#ca0020","#f4a582","#bababa","#404040"], 198 | 5: ["#ca0020","#f4a582","#ffffff","#bababa","#404040"], 199 | 6: ["#b2182b","#ef8a62","#fddbc7","#e0e0e0","#999999","#4d4d4d"], 200 | 7: ["#b2182b","#ef8a62","#fddbc7","#ffffff","#e0e0e0","#999999","#4d4d4d"], 201 | 8: ["#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d"], 202 | 9: ["#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d"], 203 | 10: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"], 204 | 11: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"] 205 | },RdYlBu: { 206 | 3: ["#fc8d59","#ffffbf","#91bfdb"], 207 | 4: ["#d7191c","#fdae61","#abd9e9","#2c7bb6"], 208 | 5: ["#d7191c","#fdae61","#ffffbf","#abd9e9","#2c7bb6"], 209 | 6: ["#d73027","#fc8d59","#fee090","#e0f3f8","#91bfdb","#4575b4"], 210 | 7: ["#d73027","#fc8d59","#fee090","#ffffbf","#e0f3f8","#91bfdb","#4575b4"], 211 | 8: ["#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4"], 212 | 9: ["#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4"], 213 | 10: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"], 214 | 11: ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"] 215 | },Spectral: { 216 | 3: ["#fc8d59","#ffffbf","#99d594"], 217 | 4: ["#d7191c","#fdae61","#abdda4","#2b83ba"], 218 | 5: ["#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba"], 219 | 6: ["#d53e4f","#fc8d59","#fee08b","#e6f598","#99d594","#3288bd"], 220 | 7: ["#d53e4f","#fc8d59","#fee08b","#ffffbf","#e6f598","#99d594","#3288bd"], 221 | 8: ["#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd"], 222 | 9: ["#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd"], 223 | 10: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"], 224 | 11: ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"] 225 | },RdYlGn: { 226 | 3: ["#fc8d59","#ffffbf","#91cf60"], 227 | 4: ["#d7191c","#fdae61","#a6d96a","#1a9641"], 228 | 5: ["#d7191c","#fdae61","#ffffbf","#a6d96a","#1a9641"], 229 | 6: ["#d73027","#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"], 230 | 7: ["#d73027","#fc8d59","#fee08b","#ffffbf","#d9ef8b","#91cf60","#1a9850"], 231 | 8: ["#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850"], 232 | 9: ["#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850"], 233 | 10: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"], 234 | 11: ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"] 235 | },Accent: { 236 | 3: ["#7fc97f","#beaed4","#fdc086"], 237 | 4: ["#7fc97f","#beaed4","#fdc086","#ffff99"], 238 | 5: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0"], 239 | 6: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f"], 240 | 7: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17"], 241 | 8: ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"] 242 | },Dark2: { 243 | 3: ["#1b9e77","#d95f02","#7570b3"], 244 | 4: ["#1b9e77","#d95f02","#7570b3","#e7298a"], 245 | 5: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e"], 246 | 6: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02"], 247 | 7: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d"], 248 | 8: ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"] 249 | },Paired: { 250 | 3: ["#a6cee3","#1f78b4","#b2df8a"], 251 | 4: ["#a6cee3","#1f78b4","#b2df8a","#33a02c"], 252 | 5: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99"], 253 | 6: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c"], 254 | 7: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f"], 255 | 8: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00"], 256 | 9: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6"], 257 | 10: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a"], 258 | 11: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99"], 259 | 12: ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"] 260 | },Pastel1: { 261 | 3: ["#fbb4ae","#b3cde3","#ccebc5"], 262 | 4: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4"], 263 | 5: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6"], 264 | 6: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc"], 265 | 7: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd"], 266 | 8: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec"], 267 | 9: ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"] 268 | },Pastel2: { 269 | 3: ["#b3e2cd","#fdcdac","#cbd5e8"], 270 | 4: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4"], 271 | 5: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9"], 272 | 6: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae"], 273 | 7: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc"], 274 | 8: ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"] 275 | },Set1: { 276 | 3: ["#e41a1c","#377eb8","#4daf4a"], 277 | 4: ["#e41a1c","#377eb8","#4daf4a","#984ea3"], 278 | 5: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00"], 279 | 6: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33"], 280 | 7: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628"], 281 | 8: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf"], 282 | 9: ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"] 283 | },Set2: { 284 | 3: ["#66c2a5","#fc8d62","#8da0cb"], 285 | 4: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3"], 286 | 5: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854"], 287 | 6: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f"], 288 | 7: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494"], 289 | 8: ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"] 290 | },Set3: { 291 | 3: ["#8dd3c7","#ffffb3","#bebada"], 292 | 4: ["#8dd3c7","#ffffb3","#bebada","#fb8072"], 293 | 5: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3"], 294 | 6: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462"], 295 | 7: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69"], 296 | 8: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5"], 297 | 9: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9"], 298 | 10: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd"], 299 | 11: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5"], 300 | 12: ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"] 301 | }}; 302 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1 Dc.js Demo 5 | div(id='day-of-week-chart') 6 | div(id='yearly-bubble-chart') 7 | script(src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js") 8 | script(src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js") 9 | script(src="https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.3/dc.min.js") 10 | script(src="javascripts/colorbrewer.js") 11 | script(src="javascripts/app.js") 12 | -------------------------------------------------------------------------------- /views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/dc/1.7.3/dc.min.css') 7 | body 8 | block content 9 | --------------------------------------------------------------------------------