Skip to content

Instantly share code, notes, and snippets.

@mhkeller
Last active July 17, 2018 16:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhkeller/5f8970c4cb74ac8f4070584aa1354598 to your computer and use it in GitHub Desktop.
Save mhkeller/5f8970c4cb74ac8f4070584aa1354598 to your computer and use it in GitHub Desktop.
A boilerplate client-side javascript setup
/* --------------------------------------------
*
* Main.js
* Install browserify dependencies with `npm install --save <package name>`
* e.g. `npm install --save d3
*
* --------------------------------------------
*/
/* --------------------------------------------
* Load our other modules
*/
// var chartFactory = require('./modules/chart-factory.js')
var d3 = require('d3')
/* --------------------------------------------
* All things having to do with baking out DOM elements
*/
var gfx = {
init: function () {
// var myChart = chartFactory()
// .prefix('prefix-')
// d3.select('#sketch-container').selectAll('.prefix-charts').data(datasets.ds.firstData.data).enter()
// .append('div')
// .classed('prefix-chart-wrapper', true)
// .call(myChart)
}
}
/* --------------------------------------------
* Massage the data
*/
var transform = {
init: function (cb) {
return function (err, firstData) {
if (err) {
console.error(err)
}
console.log('~~== datasets ==~~', Array.prototype.slice.call(arguments, 1, arguments.length))
// var firstData_sorted = this.sortByDate(firstData);
// datasets.ds.firstData = {
// data: firstData_sorted
// }
// Call this to let init know we're done and proceed to the next step in `init.`
cb()
}
}
/* --------------------------------------------
* Transformation functions go here, for example:
*/
// sortByKey: function (data, key) {
// return data.sort(function (a, b) {
// return a[key] - b[key]
// })
// }
}
/*
* Our load step and where we'll eventually store cleaned data objects
*/
var ds = {
init: function (cb) {
d3.queue()
.defer(d3.csv, 'data/filename.csv')
.await(transform.init(cb).bind(transform))
}
}
/* --------------------------------------------
* Load our data and then tell it what to do next
*/
ds.init(gfx.init.bind(gfx))
var d3 = require('d3')
// var _ = require('underscore')
module.exports = myModule
function myModule () {
// Declare chart variables
var margin
var chartContainer
var svg
var width
var height
var x
var y
var xKey
var yKey
var line
// var mobileId
// var isMobile
function chart (selection) {
selection.each(renderSelection)
// What to do for each div captured by our selector
function renderSelection (ds, i) {
setValues.call(this, ds)
bakeLayout.call(this, ds)
renderChartElements.call(this, ds)
}
// Measure DOM elements and set scales from data accordingly
function setValues (ds) {
// if (mobileId && d3.select(mobileId)) {
// isMobile = (d3.select(mobileId).style('display') === 'none')
// } else {
// isMobile = null
// }
margin = {top: 0, right: 20, bottom: 20, left: 20}
// Set dimensions from div dimensions
var canvasWidth = this.getBoundingClientRect().width
var canvasHeight = this.getBoundingClientRect().height
width = canvasWidth - margin.left - margin.right
height = canvasHeight - margin.top - margin.bottom
var xExtent = d3.extent(ds, function (d) { return d[xKey] })
var yExtent = d3.extent(ds, function (d) { return d[yKey] })
x = d3.scaleLinear()
.domain(xExtent)
.range([0, width])
y = d3.scaleLinear()
.domain(yExtent)
.range([height, 0])
line = d3.line()
.curve(d3.curveBasis)
.x(function (d) { return x(d[xKey]) })
.y(function (d) { return y(d[yKey]) })
}
// Render the main svg components, i.e. nothing that represents data itself
function bakeLayout (d) {
chartContainer = d3.select(this).append('div')
.classed('chart-container', true)
svg = chartContainer.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
// X Axis
svg.append('g')
.attr('class', 'x-axis axis')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(x))
// Y Axis
var d3yAxis = svg.append('g')
.attr('class', 'y-axis axis')
.attr('transform', 'translate(0,0)')
.call(d3.axisLeft(y))
d3yAxis.append('text')
.attr('transform', 'rotate(-90)')
.attr('y', 6)
.attr('dy', '.71em')
.style('text-anchor', 'end')
}
// Render elements bound to data elements
function renderChartElements (ds) {
svg.append('path')
.attr('class', 'line')
.style('fill', 'none')
.style('stroke-width', '1px') // Delete this line and put it in your stylesheet
.style('stroke', '#000') // Delete this line and put it in your stylesheet
.attr('d', function (d) { return line(d) })
svg.append('text')
.datum(function (d) { return ds[ds.length - 1] }) // Get the final value
.attr('transform', function (d) { return 'translate(' + x(d[xKey]) + ',' + y(d[yKey]) + ')' })
.attr('x', 3)
.attr('dy', '0.35em')
.style('font', '10px sans-serif') // Delete this line and put it in your stylesheet
.text(function (d) { return d[yKey] })
}
// function clearSelection () {
// // Clear the contents of this element
// d3.select(this).html('')
// }
// function relayout () {
// selection.each(clearSelection)
// selection.each(renderSelection)
// }
// var relayoutDebounced = _.debounce(relayout, 200)
// d3.select(window).on('resize.' + prefix + '-mymodule', relayoutDebounced)
}
chart.xKey = function (_) {
if (!_) {
return _
}
xKey = _
return chart
}
chart.yKey = function (_) {
if (!_) {
return _
}
yKey = _
return chart
}
// chart.mobileId = function (_) {
// if (!_) {
// return _
// }
// mobileId = _
// return chart
// }
return chart
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment