Skip to content

Instantly share code, notes, and snippets.

@tophtucker
Last active October 8, 2017 20:28
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 tophtucker/1b7340c8d940265ca2d6 to your computer and use it in GitHub Desktop.
Save tophtucker/1b7340c8d940265ca2d6 to your computer and use it in GitHub Desktop.
Neat lil functions
// http://stackoverflow.com/a/4467559/120290
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
function lerp(array0,array1) {
var scales = d3.range(array0.length).map(function(n) {
return d3.scale.linear()
.range([array0[n], array1[n]]);
});
return function(t) {
return scales.map(function(d,i) {
return d(t);
})
}
}
// https://en.wikipedia.org/wiki/Square_wave
function makeSquareWave(numberOfTerms, frequency, amplitude) {
return function(t) {
var terms = d3.range(numberOfTerms).map(function(i) {
var k = i + 1; //1-indexed
return Math.sin( 2 * Math.PI * (2 * k - 1) * frequency * t ) / (2 * k - 1)
})
return amplitude * 4/Math.PI * d3.sum(terms);
}
}
function pulseWave(x) {
return Math.pow(Math.cos(x),2) / Math.exp(Math.abs(x));
}
function pulseWave2(x) {
return Math.cos(x) / Math.abs(x);
}
// exponentially settle on set font size
lineSel.style('font-size', function(d,i) {
var baseRate = parseFloat(d3.select(this.parentNode.parentNode).style('font-size'));
var size = baseRate*Math.pow(1.1,lineSel.size() - i - 1);
d3.select(this.parentNode).style('font-size', size + 'px');
return size + 'px';
});
// get scroll speed
function ScrollSpeed(container) {
this.scrolls = [];
container.addEventListener('scroll', function(e) {
scrolls.push({t: Date.now(), y: e.currentTarget.scrollTop});
if(scrolls.length > 100) scrolls.shift();
})
this.getSpeed = function() {
var now = Date.now();
var scrollSamples = scrolls.filter(function(d) { return now - d.t < 400 });
if(scrollSamples.length > 1) {
var s0 = scrollSamples[0];
var s1 = scrollSamples[scrollSamples.length-1];
scrollSpeed = (s1.y - s0.y) / (s1.t - s0.t);
} else {
scrollSpeed = 0;
}
// in pixels per millisecond
return scrollSpeed;
}
}
// Responsive type size
// http://madebymike.com.au/writing/fluid-type-calc-examples/
font-size: 14px;
@media screen and (min-width: 320px) {
font-size: calc(14px + 8 * ((100vw - 320px) / 960));
}
@media screen and (min-width: 1280px) {
font-size: 22px;
}
// Find the nth item in a 2D array
function nthItemIn2DArray(array, n) {
// assume [[0,1,2],[3,4,5]];
// width of row is 3, height (number of rows) is 2
const widthOfRow = array[0].length
// "integer division" gets you the row number
const i = Math.floor(n / widthOfRow)
// remainder gets you the column number within row
const j = n % widthOfRow
return array[i][j]
}
function getRandomTimeSeries(numPoints) {
var data = d3.range(numPoints).map(d => ({
date: d3.interpolateDate(new Date("2000/01/01"), new Date("2016/10/01"))(d/numPoints),
price: undefined
}))
data.forEach(function(d,i,arr) {
if(i==0) {
d.price = d3.randomNormal(75, 30)()
} else {
d.price = arr[i-1].price * d3.randomNormal(1, .02)()
}
})
return data
}
// this is basically the same as getRandomTimeSeries above, but look how much cleaner it is!
function randomWalk(n) {
return d3.range(n)
.map(d3.randomNormal(1, .02))
.reduce(
(acc, cur, i) => (acc.push(i ? acc[i-1] * cur : 1), acc),
[]
)
}
function stringToColor(ticker) {
var domain = ["A".charCodeAt(0), "Z".charCodeAt(0) + 1]
var range = [0, 360]
var hue = ticker.split('')
.map(d => d.toUpperCase().charCodeAt(0) - "A".charCodeAt(0))
.map((d, i) => d * Math.pow((domain[1] - domain[0]), -(i + 1)))
.reduce((a, b) => a + b)
return "hsl(" + (hue * 360) + ", 100%, 50%)"
}
function getRandomTicker() {
var length = Math.ceil(Math.random()*4);
var chars = 'abcdefghijklmnopqrstuvwxyz';
return d3.range(length).map(() => chars[Math.floor(Math.random()*chars.length)].toUpperCase()).join('');
}
function padExtent(extent) {
var d = extent[1] - extent[0]
return [
extent[0] - d * .25,
extent[1] + d * .25
]
}
function downsample(array, amount) {
var numberOfElements = Math.round(
d3.scaleLinear()
.domain([0, 1])
.range([array.length, 2])
(amount)
)
var scaleSampleIndexToArrayIndex = d3.scaleLinear()
.domain([0, numberOfElements - 1])
.range([0, array.length - 1])
return d3.range(numberOfElements).map(n =>
array[Math.round(scaleSampleIndexToArrayIndex(n))]
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment