|
/* global d3 spinner scatterplot tooltip window document */ |
|
|
|
// Quick fix for resizing some things for mobile-ish viewers |
|
// vanilla JS window width and height |
|
// https://gist.github.com/joshcarr/2f861bd37c3d0df40b30 |
|
|
|
const wV = window; |
|
const dV = document; |
|
const eV = dV.documentElement; |
|
const gV = dV.getElementsByTagName('body')[0]; |
|
const xV = wV.innerWidth || eV.clientWidth || gV.clientWidth; |
|
const yV = wV.innerHeight || eV.clientHeight || gV.clientHeight; |
|
|
|
// Quick fix for resizing some things for mobile-ish viewers |
|
const mobileScreen = (xV < 500); |
|
|
|
// This component manages an svg element, and |
|
// either displays a spinner or text, |
|
// depending on the value of the `loading` state. |
|
const svg = d3.component('svg') |
|
.render(function (selection, d) { |
|
const svgSelection = selection |
|
.attr('width', d.width) |
|
.attr('height', d.height) |
|
.call(spinner, !d.loading ? [] : { |
|
x: d.width / 2, |
|
y: d.height / 2, |
|
speed: 0.2, |
|
}); |
|
const tipCallbacks = tooltip(svgSelection, d); |
|
svgSelection |
|
.call(scatterplot, d.loading ? [] : d, tipCallbacks); |
|
}); |
|
|
|
const label = d3.component('label', 'col-sm-2 col-form-label') |
|
.render(function (selection, d) { |
|
selection.text(d); |
|
}); |
|
|
|
const option = d3.component('option') |
|
.render(function (selection, d) { |
|
selection.text(d); |
|
}); |
|
|
|
const select = d3.component('select', 'form-control') |
|
.render(function (selection, d) { |
|
selection |
|
.call(option, d.columns) |
|
.property('value', d.value) |
|
.on('change', function () { |
|
d.action(this.value); |
|
}); |
|
}); |
|
|
|
const rowComponent = d3.component('div', 'row'); |
|
const colSm10 = d3.component('div', 'col-sm-10'); |
|
const menu = d3.component('div', 'col-sm-4') |
|
.render(function (selection, d) { |
|
const row = rowComponent(selection).call(label, d.label); |
|
colSm10(row).call(select, d); |
|
}); |
|
|
|
const menus = d3.component('div', 'container-fluid') |
|
.create(function (selection) { |
|
selection.style('opacity', 0); |
|
}) |
|
.render(function (selection, d) { |
|
rowComponent(selection).call(menu, [ |
|
{ |
|
label: 'X', |
|
value: d.x, |
|
action: d.setX, |
|
columns: d.numericColumns, |
|
}, |
|
{ |
|
label: 'Y', |
|
value: d.y, |
|
action: d.setY, |
|
columns: d.numericColumns, |
|
}, |
|
{ |
|
label: 'Color', |
|
value: d.color, |
|
action: d.setColor, |
|
columns: d.ordinalColumns, |
|
}, |
|
{ |
|
label: 'Radius', |
|
value: d.radius, |
|
action: d.setRadius, |
|
columns: d.numericColumns, |
|
}, |
|
], d); |
|
if (!d.loading && selection.style('opacity') === '0') { |
|
selection.transition().duration(2000) |
|
.style('opacity', 1); |
|
} |
|
}); |
|
|
|
const app = d3.component('div') |
|
.render(function (selection, d) { |
|
selection |
|
.call(svg, d) |
|
.call(menus, d); |
|
}); |