Skip to content

Instantly share code, notes, and snippets.

@vijithassar
Last active October 11, 2016 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vijithassar/9e5348184bd183fd1597556ef44f5fc4 to your computer and use it in GitHub Desktop.
Save vijithassar/9e5348184bd183fd1597556ef44f5fc4 to your computer and use it in GitHub Desktop.
batch configuration methods

Since Mike originally intended the reusable chart pattern as a straw man proposal for further refinement, here's a simple extension which I've found helpful on some recent projects. In addition to the configuration methods, a single multiple-input wrapper method can be defined (it's called .set() in this example) which can then be used to run other individual configuration methods based on an input hashmap which specifies method names and arguments as keys and values. Here, it's used to safely run methods which set size and position attributes for circles and squares which have slight semantic differences (r/cx/cy vs height/width/x/y, respectively) without needing to know which shape it's operating on. This small addition allows for the flexibility and syntactic clarity of the individual methods while also retaining the option for fast one-shot configurations based on a single object.

<!DOCTYPE html>
<html>
<head>
<title>batch configuration methods</title>
<meta charset="utf-8">
</head>
<body>
<div class="target"></div>
<div class="scripts">
<script type="text/javascript" src="https://d3js.org/d3.v4.js"></script>
<script type="text/javascript" src="./wormhole.js"></script>
</div>
</body>
</html>
(function() {
'use strict'
var height,
width,
duration,
svg,
wrapper,
factory,
circle,
rect
height = 500
width = 960
duration = 500
svg = d3.select('div.target')
.append('svg')
.attr('height', height)
.attr('width', width)
wrapper = svg.append('g')
.classed('wrapper', true)
wrapper.append('rect')
.attr('height', height)
.attr('width', width)
.style('fill', 'black')
factory = function(type) {
var f,
color,
r,
cx,
cy,
height,
width,
x,
y,
increase,
transform
increase = 10
transform = 'translate(0,0)scale(' + increase + ')'
f = function(selection) {
var start,
item
start = d3.mouse(wrapper.node())
item = selection.append(type)
.classed('marker', true)
.attr('transform', 'translate(' + start[0] + ',' + start[1] + ')')
.style('fill-opacity', 0.1)
.style('fill', color)
.style('stroke', 'white')
.transition()
.duration(duration)
.attr('transform', transform)
.remove()
if (r) {item.attr('r', r)}
if (cx) {item.attr('cx', cx)}
if (cy) {item.attr('cy', cy)}
if (height) {item.attr('height', height)}
if (width) {item.attr('width', width)}
if (x) {item.attr('x', x)}
if (y) {item.attr('y', y)}
}
f.color = function(value) {
if (! arguments.length) {
return color
} else {
color = value
return f
}
}
if (type === 'circle') {
f.r = function(value) {
if (! arguments.length) {
return r
} else {
r = value
return f
}
}
f.cx = function(value) {
if (! arguments.length) {
return cx
} else {
cx = value
return cx
}
}
f.cy = function(value) {
if (! arguments.length) {
return cy
} else {
cy = value
return f
}
}
}
if (type === 'rect') {
f.x = function(value) {
if (! arguments.length) {
return x
} else {
x = value
return f
}
}
f.y = function(value) {
if (! arguments.length) {
return y
} else {
y = value
return f
}
}
f.height = function(value) {
if (! arguments.length) {
return height
} else {
height = value
return f
}
}
f.width = function(value) {
if (! arguments.length) {
return width
} else {
width = value
return f
}
}
}
f.set = function(values) {
Object.keys(values).forEach(function(key) {
if (typeof f[key] === 'function') {f[key](values[key])}
})
}
return f
}
circle = factory('circle')
rect = factory('rect')
wrapper.on('mousemove', function() {
var position,
now,
hue,
marker,
size,
size_modifier,
parameters
position = d3.mouse(this)
now = Math.round(d3.now())
hue = now / 10 % 360
marker = now % 1000 > 500 ? circle : rect
size = 50
size_modifier = now / 1000 % 5
parameters = {
r: size * size_modifier,
cx: position[0],
cy: position[1],
height: size * 2 * size_modifier,
width: size * 2 * size_modifier,
x: position[0],
y: position[1],
color: d3.hsl(hue, 0.5, 0.5)
}
marker.set(parameters)
wrapper.call(marker)
})
}).call(this)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment