Last active
October 6, 2015 20:53
-
-
Save yogi87/4224f00f568a7d05c020 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ts -- juttle timeseries utilities | |
// | |
import 'https://gist.githubusercontent.com/welch/3f7b696beab6ba1b55bb/raw/stdj.juttle' as stdj; | |
// | |
// downsample: thin a series of values by retaining its extreme values over successive intervals | |
// parameters: | |
// in -- name of value field | |
// every -- interval of each downsample | |
// | |
export sub downsample(in, every) { | |
reduce -every every _downsample_max = max(in), _downsample_min = min(in) | |
| put *in = (Math.abs(_downsample_max) >= Math.abs(_downsample_min)) ? _downsample_max : _downsample_min | |
| remove _downsample_min, _downsample_max | |
} | |
// | |
// downsample_by: thin multiple series of values identified by the named field | |
// parameters: | |
// in -- name of value field | |
// every -- interval of each downsample | |
// by -- name of field identifying each series. | |
// | |
export sub downsample_by(in, every, by) { | |
reduce -every every _downsample_max = max(in), _downsample_min = min(in) by by | |
| put *in = (Math.abs(_downsample_max) >= Math.abs(_downsample_min)) ? _downsample_max : _downsample_min | |
| remove _downsample_min, _downsample_max | |
} | |
// | |
// lag: return the value of a field from N points ago. | |
// | |
// Note: this must be run as a windowed reducer, eg, reduce -every :h: -over :h: | |
// | |
// (running this as a windowed reducer means its reset() function will be called | |
// at the beginning of each new interval rather than the reducer being torn down and | |
// rebuilt. This allows the reducer to propagate values across intervals.) | |
// | |
// Note 2: if you want to lag by an amount of time rather than a number of | |
// points, use a windowed first() | |
// | |
export reducer lag(field, N, initial) { | |
var lagged = []; | |
var i = 0, n = 0; | |
function update() { | |
lagged[i] = *field; | |
n = Math.min(n + 1, N + 1); | |
i = (i + 1) % (N + 1); | |
} | |
function result() { | |
if (n < N + 1) { | |
return initial; | |
} else { | |
return lagged[i]; | |
} | |
} | |
function reset() { | |
// never reset | |
} | |
} | |
// | |
// delta: return the difference betwen the current value of a field | |
// and that from the previous point. | |
// | |
// Note: this must be run as a windowed reducer, eg, reduce -every :h: -over :h: | |
// | |
// (running this as a windowed reducer means its reset() function will be called | |
// at the beginning of each new interval rather than the reducer being torn down and | |
// rebuilt. This allows the reducer to propagate values across intervals.) | |
// | |
// Note 2: if you want a delta over an amount of time rather than a number of | |
// points, use a windowed (last() - first()) | |
// | |
export reducer delta(in) { | |
var last = null; | |
var this = null; | |
function update() { | |
last = this; | |
this = *in; | |
} | |
function result() { | |
return (last != null) ? this - last : this - this; | |
} | |
function reset() { | |
// don't reset | |
} | |
} | |
// | |
// chart_by: an inline chart. if by is null, chart will guess field | |
// which it should use (and may do a poor job of it) | |
export sub chart_by(by, title) { | |
( | |
@timechart -title title -id title -display.dataDensity 0 -keyField by; | |
merge; | |
) | |
} | |
export sub chart_by_every(by, title, every) { | |
( | |
@timechart -title title -id title -display.dataDensity 0 -keyField by -display.duration every; | |
merge; | |
) | |
} | |
// | |
// split_chart: inline chart that includes a split. Send it points having | |
// multiple value fields on them to see each field plotted | |
// as its own series. | |
// | |
export sub split_chart(title) { | |
( | |
split | @timechart -title title -id title -display.dataDensity 0; | |
merge; | |
) | |
} | |
export sub split_chart_every(title, every) { | |
( | |
split | @timechart -title title -id title -display.dataDensity 0 -display.duration every; | |
merge; | |
) | |
} | |
export sub split_chart_end(title) { | |
split | @timechart -title title -id title -display.dataDensity 0; | |
} | |
export sub split_chart_range(title, from, to) { | |
( | |
split | filter time > from time < to | | |
@timechart -title title -id title -display.dataDensity 0; | |
merge; | |
) | |
} | |
// | |
// dual_chart_by: an inline chart with two veritical axes for overlaying | |
// a differently scaled series | |
// parameters: | |
// by -- name of field holding series names (including secondary) | |
// secondary -- name of secondary series (all others go to primary axis) | |
// | |
export sub dual_chart_by(title, by, secondary) { | |
( | |
@timechart -id title -o { | |
keyField: by, | |
title: title, | |
display: { dataDensity: 0 }, | |
yScales: { secondary: { } }, | |
series: [ | |
{ name: secondary, yScale: 'secondary' } | |
] | |
}; | |
merge; | |
) | |
} | |
// | |
// split_dual_chart: an inline split chart with two veritical axes for overlaying | |
// a differently scaled series | |
// parameters: | |
// secondary -- name of secondary series (all others go to primary axis) | |
// | |
export sub split_dual_chart(title, secondary) { | |
( | |
split | @timechart -id title -o { | |
keyField: 'name', | |
title: title, | |
display: { dataDensity: 0 }, | |
yScales: { secondary: { } }, | |
series: [ | |
{ name: secondary, yScale: 'secondary' } | |
] | |
}; | |
merge; | |
) | |
} | |
// split_dual_chart_by: an inline split chart with two veritical axes for overlaying | |
// a differently scaled series | |
// parameters: | |
// by -- name of field holding series names (including secondary) | |
// secondary -- name of secondary series (all others go to primary axis) | |
// | |
export sub split_dual_chart_by(title, by, secondary) { | |
( | |
split by | @timechart -id title -o { | |
keyField: [by,'name'], | |
title: title, | |
display: { dataDensity: 0 }, | |
yScales: { secondary: { } }, | |
series: [ | |
{ name: secondary, yScale: 'secondary' } | |
] | |
}; | |
merge; | |
) | |
} | |
export sub run() { | |
emit -limit 100 -every :.1s: | |
| put c = count(), x = c * ((c % 2 == 0)? 1 : -1) | |
| downsample -in "x" -every :.2s: | |
| put c = count(), z = c/2 | |
| split_dual_chart -title 'testing' -secondary 'c' | |
| stdj.end | |
} | |
run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment