Skip to content

Commit

Permalink
Refactor around how visualizations/*.js are required (#913)
Browse files Browse the repository at this point in the history
* Refactor around how visualizations/*.js are required

* Reactifying FilterBox further

* Fixing the auto-refresh on filtering events

* Fixing preselected filters
  • Loading branch information
mistercrunch committed Aug 12, 2016
1 parent 198226a commit e243a14
Show file tree
Hide file tree
Showing 21 changed files with 468 additions and 359 deletions.
2 changes: 1 addition & 1 deletion caravel/assets/javascripts/dashboard/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ function dashboardContainer(dashboardData) {
refreshExcept(sliceId) {
const immune = this.metadata.filter_immune_slices || [];
this.slices.forEach(function (slice) {
if (slice.data.sliceId !== sliceId && immune.indexOf(slice.data.sliceId) === -1) {
if (slice.data.slice_id !== sliceId && immune.indexOf(slice.data.sliceId) === -1) {
slice.render();
}
});
Expand Down
3 changes: 0 additions & 3 deletions caravel/assets/javascripts/explore/explore.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,6 @@ $(document).ready(function () {

initExploreView();

// Dynamically register this visualization
px.registerViz(data.viz_name || 'table');

slice = px.Slice(data);

$('.slice').data('slice', slice);
Expand Down
232 changes: 12 additions & 220 deletions caravel/assets/javascripts/modules/caravel.js
Original file line number Diff line number Diff line change
@@ -1,210 +1,19 @@
import $ from 'jquery';
const d3 = require('d3');
const Mustache = require('mustache');
const utils = require('./utils');
// vis sources
/* eslint camel-case: 0 */
const sourceMap = {
area: 'nvd3_vis.js',
bar: 'nvd3_vis.js',
bubble: 'nvd3_vis.js',
big_number: 'big_number.js',
big_number_total: 'big_number.js',
compare: 'nvd3_vis.js',
dist_bar: 'nvd3_vis.js',
directed_force: 'directed_force.js',
filter_box: 'filter_box.js',
heatmap: 'heatmap.js',
iframe: 'iframe.js',
line: 'nvd3_vis.js',
markup: 'markup.js',
separator: 'markup.js',
para: 'parallel_coordinates.js',
pie: 'nvd3_vis.js',
box_plot: 'nvd3_vis.js',
pivot_table: 'pivot_table.js',
sankey: 'sankey.js',
sunburst: 'sunburst.js',
table: 'table.js',
word_cloud: 'word_cloud.js',
world_map: 'world_map.js',
treemap: 'treemap.js',
cal_heatmap: 'cal_heatmap.js',
horizon: 'horizon.js',
mapbox: 'mapbox.jsx',
histogram: 'histogram.js',
};
const color = function () {
// Color related utility functions go in this object
const bnbColors = [
'#ff5a5f', // rausch
'#7b0051', // hackb
'#007A87', // kazan
'#00d1c1', // babu
'#8ce071', // lima
'#ffb400', // beach
'#b4a76c', // barol
'#ff8083',
'#cc0086',
'#00a1b3',
'#00ffeb',
'#bbedab',
'#ffd266',
'#cbc29a',
'#ff3339',
'#ff1ab1',
'#005c66',
'#00b3a5',
'#55d12e',
'#b37e00',
'#988b4e',
];
const spectrums = {
blue_white_yellow: [
'#00d1c1',
'white',
'#ffb400',
],
fire: [
'white',
'yellow',
'red',
'black',
],
white_black: [
'white',
'black',
],
black_white: [
'black',
'white',
],
};
const colorBnb = function () {
// Color factory
const seen = {};
return function (s) {
if (!s) {
return;
}
let stringifyS = String(s);
// next line is for caravel series that should have the same color
stringifyS = stringifyS.replace('---', '');
if (seen[stringifyS] === undefined) {
seen[stringifyS] = Object.keys(seen).length;
}
/* eslint consistent-return: 0 */
return this.bnbColors[seen[stringifyS] % this.bnbColors.length];
};
};
const colorScalerFactory = function (colors, data, accessor) {
// Returns a linear scaler our of an array of color
if (!Array.isArray(colors)) {
/* eslint no-param-reassign: 0 */
colors = spectrums[colors];
}
let ext = [
0,
1,
];
if (data !== undefined) {
ext = d3.extent(data, accessor);
}
const points = [];
const chunkSize = (ext[1] - ext[0]) / colors.length;
$.each(colors, function (i) {
points.push(i * chunkSize);
});
return d3.scale.linear().domain(points).range(colors);
};
return {
bnbColors,
category21: colorBnb(),
colorScalerFactory,
};
};
import vizMap from '../../visualizations/main.js';

/* eslint wrap-iife: 0*/
const px = function () {
const visualizations = {};
let slice;
function getParam(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
const regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
const formattedName = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
const regex = new RegExp('[\\?&]' + formattedName + '=([^&#]*)');
const results = regex.exec(location.search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
}
function UTC(dttm) {
return new Date(
dttm.getUTCFullYear(),
dttm.getUTCMonth(),
dttm.getUTCDate(),
dttm.getUTCHours(),
dttm.getUTCMinutes(),
dttm.getUTCSeconds()
);
}
const tickMultiFormat = d3.time.format.multi([
[
'.%L',
function (d) {
return d.getMilliseconds();
},
],
// If there are millisections, show only them
[
':%S',
function (d) {
return d.getSeconds();
},
],
// If there are seconds, show only them
[
'%a %b %d, %I:%M %p',
function (d) {
return d.getMinutes() !== 0;
},
],
// If there are non-zero minutes, show Date, Hour:Minute [AM/PM]
[
'%a %b %d, %I %p',
function (d) {
return d.getHours() !== 0;
},
],
// If there are hours that are multiples of 3, show date and AM/PM
[
'%a %b %d',
function (d) {
return d.getDate() !== 1;
},
],
// If not the first of the month, do "month day, year."
[
'%B %Y',
function (d) {
return d.getMonth() !== 0 && d.getDate() === 1;
},
],
// If the first of the month, do "month day, year."
[
'%Y',
function () {
return true;
},
], // fall back on month, year
]);
function formatDate(dttm) {
const d = UTC(new Date(dttm));
// d = new Date(d.getTime() - 1 * 60 * 60 * 1000);
return tickMultiFormat(d);
}
function timeFormatFactory(d3timeFormat) {
const f = d3.time.format(d3timeFormat);
return function (dttm) {
const d = UTC(new Date(dttm));
return f(d);
};
}
function initFavStars() {
const baseUrl = '/caravel/favstar/';
// Init star behavihor for favorite
Expand Down Expand Up @@ -267,12 +76,12 @@ const px = function () {
containerId,
selector,
querystring(params) {
params = params || {};
const newParams = params || {};
const parser = document.createElement('a');
parser.href = data.json_endpoint;
if (dashboard !== undefined) {
const flts =
params.extraFilters === false ? '' :
newParams.extraFilters === false ? '' :
encodeURIComponent(JSON.stringify(dashboard.filters));
qrystr = parser.search + '&extra_filters=' + flts;
} else if ($('#query').length === 0) {
Expand All @@ -293,10 +102,10 @@ const px = function () {
return Mustache.render(s, context);
},
jsonEndpoint(params) {
params = params || {};
const newParams = params || {};
const parser = document.createElement('a');
parser.href = data.json_endpoint;
let endpoint = parser.pathname + this.querystring({ extraFilters: params.extraFilters });
let endpoint = parser.pathname + this.querystring({ extraFilters: newParams.extraFilters });
endpoint += '&json=true';
endpoint += '&force=' + this.force;
return endpoint;
Expand Down Expand Up @@ -413,9 +222,10 @@ const px = function () {
},
render(force) {
if (force === undefined) {
force = false;
this.force = false;
} else {
this.force = force;
}
this.force = force;
token.find('img.loading').show();
container.css('height', this.height());
dttm = 0;
Expand Down Expand Up @@ -457,32 +267,14 @@ const px = function () {
}
},
};
const visType = data.form_data.viz_type;
px.registerViz(visType);
slice.viz = visualizations[data.form_data.viz_type](slice);
slice.viz = vizMap[data.form_data.viz_type](slice);
return slice;
};
function registerViz(name) {
const visSource = sourceMap[name];
if (visSource) {
/* eslint global-require: 0 */
const visFactory = require('../../visualizations/' + visSource);
if (typeof visFactory === 'function') {
visualizations[name] = visFactory;
}
} else {
throw new Error('require(' + name + ') failed.');
}
}
// Export public functions
return {
color: color(),
formatDate,
getParam,
initFavStars,
registerViz,
Slice,
timeFormatFactory,
};
}();
module.exports = px;
85 changes: 85 additions & 0 deletions caravel/assets/javascripts/modules/colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import $ from 'jquery';
const d3 = require('d3');

// Color related utility functions go in this object
export const bnbColors = [
'#ff5a5f', // rausch
'#7b0051', // hackb
'#007A87', // kazan
'#00d1c1', // babu
'#8ce071', // lima
'#ffb400', // beach
'#b4a76c', // barol
'#ff8083',
'#cc0086',
'#00a1b3',
'#00ffeb',
'#bbedab',
'#ffd266',
'#cbc29a',
'#ff3339',
'#ff1ab1',
'#005c66',
'#00b3a5',
'#55d12e',
'#b37e00',
'#988b4e',
];

const spectrums = {
blue_white_yellow: [
'#00d1c1',
'white',
'#ffb400',
],
fire: [
'white',
'yellow',
'red',
'black',
],
white_black: [
'white',
'black',
],
black_white: [
'black',
'white',
],
};

export const category21 = (function () {
// Color factory
const seen = {};
return function (s) {
if (!s) {
return;
}
let stringifyS = String(s);
// next line is for caravel series that should have the same color
stringifyS = stringifyS.replace('---', '');
if (seen[stringifyS] === undefined) {
seen[stringifyS] = Object.keys(seen).length;
}
/* eslint consistent-return: 0 */
return bnbColors[seen[stringifyS] % bnbColors.length];
};
}());

export const colorScalerFactory = function (colors, data, accessor) {
// Returns a linear scaler our of an array of color
if (!Array.isArray(colors)) {
/* eslint no-param-reassign: 0 */
colors = spectrums[colors];
}
let ext = [0, 1];
if (data !== undefined) {
ext = d3.extent(data, accessor);
}
const points = [];
const chunkSize = (ext[1] - ext[0]) / colors.length;
$.each(colors, function (i) {
points.push(i * chunkSize);
});
return d3.scale.linear().domain(points).range(colors);
};
Loading

0 comments on commit e243a14

Please sign in to comment.