update uplot

This commit is contained in:
REJack 2020-11-29 03:57:24 +01:00
parent 2c98813cc1
commit 5fc36f6176
6 changed files with 627 additions and 572 deletions

6
package-lock.json generated
View file

@ -11348,9 +11348,9 @@
}
},
"uplot": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/uplot/-/uplot-1.4.4.tgz",
"integrity": "sha512-vgV84+by3fGTU4bdpffSvA9FX8ide6MsmlBzOASPDdZCquXmCA+T2qodeNdnBen+7YOeqD9H91epVnF0dQgVKw=="
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/uplot/-/uplot-1.4.6.tgz",
"integrity": "sha512-nw3LdjLFhAqKQF/Rv7QjZICVnjJemOQVj2L3b7889gHBrnC1LwltkzTcawDcbMe6pxo++0KVev9xSC0YCw+m5w=="
},
"upper-case": {
"version": "1.1.3",

View file

@ -126,7 +126,7 @@
"sweetalert2": "^10.10.2",
"tempusdominus-bootstrap-4": "^5.39.0",
"toastr": "^2.1.4",
"uplot": "^1.4.4"
"uplot": "^1.4.6"
},
"devDependencies": {
"@babel/core": "^7.11.6",

View file

@ -4,7 +4,7 @@
*
* uPlot.js (μPlot)
* A small, fast chart for time series, lines, areas, ohlc & bars
* https://github.com/leeoniya/uPlot (v1.4.4)
* https://github.com/leeoniya/uPlot (v1.4.6)
*/
'use strict';
@ -551,8 +551,6 @@ var onlyWhole = function (v) { return v % 1 == 0; };
var allMults = [1,2,2.5,5];
var wholeMults = allMults.filter(onlyWhole);
// ...0.01, 0.02, 0.025, 0.05, 0.1, 0.2, 0.25, 0.5
var decIncrs = genIncrs(10, -16, 0, allMults);
@ -564,61 +562,196 @@ var wholeIncrs = oneIncrs.filter(onlyWhole);
var numIncrs = decIncrs.concat(oneIncrs);
var s = 1,
m = 60,
h = m * m,
d = h * 24,
mo = d * 30,
y = d * 365;
var NL = "\n";
// min of 1e-3 prevents setting a temporal x ticks too small since Date objects cannot advance ticks smaller than 1ms
var timeIncrs = genIncrs(10, -3, 0, wholeMults).concat([
// minute divisors (# of secs)
1,
5,
10,
15,
30,
// hour divisors (# of mins)
m,
m * 5,
m * 10,
m * 15,
m * 30,
// day divisors (# of hrs)
h,
h * 2,
h * 3,
h * 4,
h * 6,
h * 8,
h * 12,
// month divisors TODO: need more?
d,
d * 2,
d * 3,
d * 4,
d * 5,
d * 6,
d * 7,
d * 8,
d * 9,
d * 10,
d * 15,
// year divisors (# months, approx)
mo,
mo * 2,
mo * 3,
mo * 4,
mo * 6,
// century divisors
y,
y * 2,
y * 5,
y * 10,
y * 25,
y * 50,
y * 100 ]);
var yyyy = "{YYYY}";
var NLyyyy = NL + yyyy;
var md = "{M}/{D}";
var NLmd = NL + md;
var NLmdyy = NLmd + "/{YY}";
var aa = "{aa}";
var hmm = "{h}:{mm}";
var hmmaa = hmm + aa;
var NLhmmaa = NL + hmmaa;
var ss = ":{ss}";
var _ = null;
function genTimeStuffs(ms) {
var s = ms * 1e3,
m = s * 60,
h = m * 60,
d = h * 24,
mo = d * 30,
y = d * 365;
// min of 1e-3 prevents setting a temporal x ticks too small since Date objects cannot advance ticks smaller than 1ms
var subSecIncrs = ms == 1 ? genIncrs(10, 0, 3, allMults).filter(onlyWhole) : genIncrs(10, -3, 0, allMults);
var timeIncrs = subSecIncrs.concat([
// minute divisors (# of secs)
s,
s * 5,
s * 10,
s * 15,
s * 30,
// hour divisors (# of mins)
m,
m * 5,
m * 10,
m * 15,
m * 30,
// day divisors (# of hrs)
h,
h * 2,
h * 3,
h * 4,
h * 6,
h * 8,
h * 12,
// month divisors TODO: need more?
d,
d * 2,
d * 3,
d * 4,
d * 5,
d * 6,
d * 7,
d * 8,
d * 9,
d * 10,
d * 15,
// year divisors (# months, approx)
mo,
mo * 2,
mo * 3,
mo * 4,
mo * 6,
// century divisors
y,
y * 2,
y * 5,
y * 10,
y * 25,
y * 50,
y * 100 ]);
// [0]: minimum num secs in the tick incr
// [1]: default tick format
// [2-7]: rollover tick formats
// [8]: mode: 0: replace [1] -> [2-7], 1: concat [1] + [2-7]
var _timeAxisStamps = [
// tick incr default year month day hour min sec mode
[y, yyyy, _, _, _, _, _, _, 1],
[d * 28, "{MMM}", NLyyyy, _, _, _, _, _, 1],
[d, md, NLyyyy, _, _, _, _, _, 1],
[h, "{h}" + aa, NLmdyy, _, NLmd, _, _, _, 1],
[m, hmmaa, NLmdyy, _, NLmd, _, _, _, 1],
[s, ss, NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
[ms, ss + ".{fff}", NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1] ];
// the ensures that axis ticks, values & grid are aligned to logical temporal breakpoints and not an arbitrary timestamp
// https://www.timeanddate.com/time/dst/
// https://www.timeanddate.com/time/dst/2019.html
// https://www.epochconverter.com/timezones
function timeAxisSplits(tzDate) {
return function (self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) {
var splits = [];
var isYr = foundIncr >= y;
var isMo = foundIncr >= mo && foundIncr < y;
// get the timezone-adjusted date
var minDate = tzDate(scaleMin);
var minDateTs = minDate * ms;
// get ts of 12am (this lands us at or before the original scaleMin)
var minMin = mkDate(minDate[getFullYear](), isYr ? 0 : minDate[getMonth](), isMo || isYr ? 1 : minDate[getDate]());
var minMinTs = minMin * ms;
if (isMo || isYr) {
var moIncr = isMo ? foundIncr / mo : 0;
var yrIncr = isYr ? foundIncr / y : 0;
// let tzOffset = scaleMin - minDateTs; // needed?
var split = minDateTs == minMinTs ? minDateTs : mkDate(minMin[getFullYear]() + yrIncr, minMin[getMonth]() + moIncr, 1) * ms;
var splitDate = new Date(split / ms);
var baseYear = splitDate[getFullYear]();
var baseMonth = splitDate[getMonth]();
for (var i = 0; split <= scaleMax; i++) {
var next = mkDate(baseYear + yrIncr * i, baseMonth + moIncr * i, 1);
var offs = next - tzDate(next * ms);
split = (+next + offs) * ms;
if (split <= scaleMax)
{ splits.push(split); }
}
}
else {
var incr0 = foundIncr >= d ? d : foundIncr;
var tzOffset = floor(scaleMin) - floor(minDateTs);
var split$1 = minMinTs + tzOffset + incrRoundUp(minDateTs - minMinTs, incr0);
splits.push(split$1);
var date0 = tzDate(split$1);
var prevHour = date0[getHours]() + (date0[getMinutes]() / m) + (date0[getSeconds]() / h);
var incrHours = foundIncr / h;
var minSpace = self.axes[axisIdx]._space;
var pctSpace = foundSpace / minSpace;
while (1) {
split$1 = roundDec(split$1 + foundIncr, ms == 1 ? 0 : 3);
if (split$1 > scaleMax)
{ break; }
if (incrHours > 1) {
var expectedHour = floor(roundDec(prevHour + incrHours, 6)) % 24;
var splitDate$1 = tzDate(split$1);
var actualHour = splitDate$1.getHours();
var dstShift = actualHour - expectedHour;
if (dstShift > 1)
{ dstShift = -1; }
split$1 -= dstShift * h;
prevHour = (prevHour + incrHours) % 24;
// add a tick only if it's further than 70% of the min allowed label spacing
var prevSplit = splits[splits.length - 1];
var pctIncr = roundDec((split$1 - prevSplit) / foundIncr, 3);
if (pctIncr * pctSpace >= .7)
{ splits.push(split$1); }
}
else
{ splits.push(split$1); }
}
}
return splits;
}
}
return [
timeIncrs,
_timeAxisStamps,
timeAxisSplits ];
}
var ref = genTimeStuffs(1);
var timeIncrsMs = ref[0];
var _timeAxisStampsMs = ref[1];
var timeAxisSplitsMs = ref[2];
var ref$1 = genTimeStuffs(1e-3);
var timeIncrsS = ref$1[0];
var _timeAxisStampsS = ref$1[1];
var timeAxisSplitsS = ref$1[2];
// base 2
var binIncrs = genIncrs(2, -53, 53, [1]);
@ -639,36 +772,6 @@ function timeAxisStamps(stampCfg, fmtDate) {
); });
}
var NL = "\n";
var yyyy = "{YYYY}";
var NLyyyy = NL + yyyy;
var md = "{M}/{D}";
var NLmd = NL + md;
var NLmdyy = NLmd + "/{YY}";
var aa = "{aa}";
var hmm = "{h}:{mm}";
var hmmaa = hmm + aa;
var NLhmmaa = NL + hmmaa;
var ss = ":{ss}";
var _ = null;
// [0]: minimum num secs in the tick incr
// [1]: default tick format
// [2-7]: rollover tick formats
// [8]: mode: 0: replace [1] -> [2-7], 1: concat [1] + [2-7]
var _timeAxisStamps = [
// tick incr default year month day hour min sec mode
[y, yyyy, _, _, _, _, _, _, 1],
[d * 28, "{MMM}", NLyyyy, _, _, _, _, _, 1],
[d, md, NLyyyy, _, _, _, _, _, 1],
[h, "{h}" + aa, NLmdyy, _, NLmd, _, _, _, 1],
[m, hmmaa, NLmdyy, _, NLmd, _, _, _, 1],
[s, ss, NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
[1e-3, ss + ".{fff}", NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1] ];
// TODO: will need to accept spaces[] and pull incr into the loop when grid will be non-uniform, eg for log scales.
// currently we ignore this for months since they're *nearly* uniform and the added complexity is not worth it
function timeAxisVals(tzDate, stamps) {
@ -725,93 +828,6 @@ function mkDate(y, m, d) {
return new Date(y, m, d);
}
// the ensures that axis ticks, values & grid are aligned to logical temporal breakpoints and not an arbitrary timestamp
// https://www.timeanddate.com/time/dst/
// https://www.timeanddate.com/time/dst/2019.html
// https://www.epochconverter.com/timezones
function timeAxisSplits(tzDate) {
return function (self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) {
var splits = [];
var isYr = foundIncr >= y;
var isMo = foundIncr >= mo && foundIncr < y;
// get the timezone-adjusted date
var minDate = tzDate(scaleMin);
var minDateTs = minDate / 1e3;
// get ts of 12am (this lands us at or before the original scaleMin)
var minMin = mkDate(minDate[getFullYear](), isYr ? 0 : minDate[getMonth](), isMo || isYr ? 1 : minDate[getDate]());
var minMinTs = minMin / 1e3;
if (isMo || isYr) {
var moIncr = isMo ? foundIncr / mo : 0;
var yrIncr = isYr ? foundIncr / y : 0;
// let tzOffset = scaleMin - minDateTs; // needed?
var split = minDateTs == minMinTs ? minDateTs : mkDate(minMin[getFullYear]() + yrIncr, minMin[getMonth]() + moIncr, 1) / 1e3;
var splitDate = new Date(split * 1e3);
var baseYear = splitDate[getFullYear]();
var baseMonth = splitDate[getMonth]();
for (var i = 0; split <= scaleMax; i++) {
var next = mkDate(baseYear + yrIncr * i, baseMonth + moIncr * i, 1);
var offs = next - tzDate(next / 1e3);
split = (+next + offs) / 1e3;
if (split <= scaleMax)
{ splits.push(split); }
}
}
else {
var incr0 = foundIncr >= d ? d : foundIncr;
var tzOffset = floor(scaleMin) - floor(minDateTs);
var split$1 = minMinTs + tzOffset + incrRoundUp(minDateTs - minMinTs, incr0);
splits.push(split$1);
var date0 = tzDate(split$1);
var prevHour = date0[getHours]() + (date0[getMinutes]() / m) + (date0[getSeconds]() / h);
var incrHours = foundIncr / h;
var minSpace = self.axes[axisIdx]._space;
var pctSpace = foundSpace / minSpace;
while (1) {
split$1 = roundDec(split$1 + foundIncr, 3);
if (split$1 > scaleMax)
{ break; }
if (incrHours > 1) {
var expectedHour = floor(roundDec(prevHour + incrHours, 6)) % 24;
var splitDate$1 = tzDate(split$1);
var actualHour = splitDate$1.getHours();
var dstShift = actualHour - expectedHour;
if (dstShift > 1)
{ dstShift = -1; }
split$1 -= dstShift * h;
prevHour = (prevHour + incrHours) % 24;
// add a tick only if it's further than 70% of the min allowed label spacing
var prevSplit = splits[splits.length - 1];
var pctIncr = roundDec((split$1 - prevSplit) / foundIncr, 3);
if (pctIncr * pctSpace >= .7)
{ splits.push(split$1); }
}
else
{ splits.push(split$1); }
}
}
return splits;
}
}
function timeSeriesStamp(stampCfg, fmtDate) {
return fmtDate(stampCfg);
}
@ -1235,7 +1251,7 @@ function uPlot(opts, data, then) {
{ opts = p.opts(self, opts) || opts; }
});
var ms = opts.ms || 1e-3;
var series = self.series = setDefaults(opts.series || [], xSeriesOpts, ySeriesOpts, false);
var axes = self.axes = setDefaults(opts.axes || [], xAxisOpts, yAxisOpts, true);
@ -1311,11 +1327,11 @@ function uPlot(opts, data, then) {
gutters._y = gutters.y(self);
// self.tz = opts.tz || Intl.DateTimeFormat().resolvedOptions().timeZone;
var _tzDate = (opts.tzDate || (function (ts) { return new Date(ts * 1e3); }));
var _tzDate = (opts.tzDate || (function (ts) { return new Date(ts / ms); }));
var _fmtDate = (opts.fmtDate || fmtDate);
var _timeAxisSplits = timeAxisSplits(_tzDate);
var _timeAxisVals = timeAxisVals(_tzDate, timeAxisStamps(_timeAxisStamps, _fmtDate));
var _timeAxisSplits = (ms == 1 ? timeAxisSplitsMs(_tzDate) : timeAxisSplitsS(_tzDate));
var _timeAxisVals = timeAxisVals(_tzDate, timeAxisStamps((ms == 1 ? _timeAxisStampsMs : _timeAxisStampsS), _fmtDate));
var _timeSeriesVal = timeSeriesVal(_tzDate, timeSeriesStamp(_timeSeriesStamp, _fmtDate));
var legend = assign({show: true, live: true}, opts.legend);
@ -1471,9 +1487,13 @@ function uPlot(opts, data, then) {
function convergeSize() {
var converged = false;
var cycleNum = 0;
while (!converged) {
var axesConverged = axesCalc();
var guttersConverged = guttersCalc();
cycleNum++;
var axesConverged = axesCalc(cycleNum);
var guttersConverged = guttersCalc(cycleNum);
converged = axesConverged && guttersConverged;
@ -1685,7 +1705,7 @@ function uPlot(opts, data, then) {
axis.size = fnOrSelf(axis.size);
axis.space = fnOrSelf(axis.space);
axis.rotate = fnOrSelf(axis.rotate);
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? wholeIncrs : (isTime ? timeIncrs : numIncrs)));
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? wholeIncrs : (isTime ? (ms == 1 ? timeIncrsMs : timeIncrsS) : numIncrs)));
axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
var av = axis.values;
@ -1704,7 +1724,7 @@ function uPlot(opts, data, then) {
axis.font = pxRatioFont(axis.font);
axis.labelFont = pxRatioFont(axis.labelFont);
axis._size = axis.size(self, null, i);
axis._size = axis.size(self, null, i, 0);
axis._space =
axis._rotate =
@ -1789,7 +1809,7 @@ function uPlot(opts, data, then) {
if (xScaleDistr == 3)
{ (assign = rangeLog(_min, _min, scales[xScaleKey].log, false), _min = assign[0], _max = assign[1]); }
else if (scales[xScaleKey].time)
{ _max = _min + 86400; }
{ _max = _min + 86400 / ms; }
else
{ (assign$1 = rangeNum(_min, _max, 0.1, true), _min = assign$1[0], _max = assign$1[1]); }
}
@ -2330,7 +2350,7 @@ function uPlot(opts, data, then) {
ctx.translate(-offset, -offset);
}
function axesCalc() {
function axesCalc(cycleNum) {
// log("axesCalc()", arguments);
var converged = true;
@ -2387,7 +2407,7 @@ function uPlot(opts, data, then) {
var oldSize = axis._size;
axis._size = axis.size(self, values, i);
axis._size = ceil(axis.size(self, values, i, cycleNum));
if (oldSize != null && axis._size != oldSize) // ready && ?
{ converged = false; }
@ -2396,14 +2416,14 @@ function uPlot(opts, data, then) {
return converged;
}
function guttersCalc() {
function guttersCalc(cycleNum) {
var converged = true;
var _x = gutters._x;
var _y = gutters._y;
gutters._x = gutters.x(self);
gutters._y = gutters.y(self);
gutters._x = ceil(gutters.x(self, cycleNum));
gutters._y = ceil(gutters.y(self, cycleNum));
if (gutters._x != _x || gutters._y != _y)
{ converged = false; }

View file

@ -4,7 +4,7 @@
*
* uPlot.js (μPlot)
* A small, fast chart for time series, lines, areas, ohlc & bars
* https://github.com/leeoniya/uPlot (v1.4.4)
* https://github.com/leeoniya/uPlot (v1.4.6)
*/
function debounce(fn, time) {
@ -551,8 +551,6 @@ const onlyWhole = v => v % 1 == 0;
const allMults = [1,2,2.5,5];
const wholeMults = allMults.filter(onlyWhole);
// ...0.01, 0.02, 0.025, 0.05, 0.1, 0.2, 0.25, 0.5
const decIncrs = genIncrs(10, -16, 0, allMults);
@ -564,62 +562,193 @@ const wholeIncrs = oneIncrs.filter(onlyWhole);
const numIncrs = decIncrs.concat(oneIncrs);
let s = 1,
m = 60,
h = m * m,
d = h * 24,
mo = d * 30,
y = d * 365;
const NL = "\n";
// min of 1e-3 prevents setting a temporal x ticks too small since Date objects cannot advance ticks smaller than 1ms
const timeIncrs = genIncrs(10, -3, 0, wholeMults).concat([
// minute divisors (# of secs)
1,
5,
10,
15,
30,
// hour divisors (# of mins)
m,
m * 5,
m * 10,
m * 15,
m * 30,
// day divisors (# of hrs)
h,
h * 2,
h * 3,
h * 4,
h * 6,
h * 8,
h * 12,
// month divisors TODO: need more?
d,
d * 2,
d * 3,
d * 4,
d * 5,
d * 6,
d * 7,
d * 8,
d * 9,
d * 10,
d * 15,
// year divisors (# months, approx)
mo,
mo * 2,
mo * 3,
mo * 4,
mo * 6,
// century divisors
y,
y * 2,
y * 5,
y * 10,
y * 25,
y * 50,
y * 100,
]);
const yyyy = "{YYYY}";
const NLyyyy = NL + yyyy;
const md = "{M}/{D}";
const NLmd = NL + md;
const NLmdyy = NLmd + "/{YY}";
const aa = "{aa}";
const hmm = "{h}:{mm}";
const hmmaa = hmm + aa;
const NLhmmaa = NL + hmmaa;
const ss = ":{ss}";
const _ = null;
function genTimeStuffs(ms) {
let s = ms * 1e3,
m = s * 60,
h = m * 60,
d = h * 24,
mo = d * 30,
y = d * 365;
// min of 1e-3 prevents setting a temporal x ticks too small since Date objects cannot advance ticks smaller than 1ms
let subSecIncrs = ms == 1 ? genIncrs(10, 0, 3, allMults).filter(onlyWhole) : genIncrs(10, -3, 0, allMults);
let timeIncrs = subSecIncrs.concat([
// minute divisors (# of secs)
s,
s * 5,
s * 10,
s * 15,
s * 30,
// hour divisors (# of mins)
m,
m * 5,
m * 10,
m * 15,
m * 30,
// day divisors (# of hrs)
h,
h * 2,
h * 3,
h * 4,
h * 6,
h * 8,
h * 12,
// month divisors TODO: need more?
d,
d * 2,
d * 3,
d * 4,
d * 5,
d * 6,
d * 7,
d * 8,
d * 9,
d * 10,
d * 15,
// year divisors (# months, approx)
mo,
mo * 2,
mo * 3,
mo * 4,
mo * 6,
// century divisors
y,
y * 2,
y * 5,
y * 10,
y * 25,
y * 50,
y * 100,
]);
// [0]: minimum num secs in the tick incr
// [1]: default tick format
// [2-7]: rollover tick formats
// [8]: mode: 0: replace [1] -> [2-7], 1: concat [1] + [2-7]
const _timeAxisStamps = [
// tick incr default year month day hour min sec mode
[y, yyyy, _, _, _, _, _, _, 1],
[d * 28, "{MMM}", NLyyyy, _, _, _, _, _, 1],
[d, md, NLyyyy, _, _, _, _, _, 1],
[h, "{h}" + aa, NLmdyy, _, NLmd, _, _, _, 1],
[m, hmmaa, NLmdyy, _, NLmd, _, _, _, 1],
[s, ss, NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
[ms, ss + ".{fff}", NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
];
// the ensures that axis ticks, values & grid are aligned to logical temporal breakpoints and not an arbitrary timestamp
// https://www.timeanddate.com/time/dst/
// https://www.timeanddate.com/time/dst/2019.html
// https://www.epochconverter.com/timezones
function timeAxisSplits(tzDate) {
return (self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) => {
let splits = [];
let isYr = foundIncr >= y;
let isMo = foundIncr >= mo && foundIncr < y;
// get the timezone-adjusted date
let minDate = tzDate(scaleMin);
let minDateTs = minDate * ms;
// get ts of 12am (this lands us at or before the original scaleMin)
let minMin = mkDate(minDate[getFullYear](), isYr ? 0 : minDate[getMonth](), isMo || isYr ? 1 : minDate[getDate]());
let minMinTs = minMin * ms;
if (isMo || isYr) {
let moIncr = isMo ? foundIncr / mo : 0;
let yrIncr = isYr ? foundIncr / y : 0;
// let tzOffset = scaleMin - minDateTs; // needed?
let split = minDateTs == minMinTs ? minDateTs : mkDate(minMin[getFullYear]() + yrIncr, minMin[getMonth]() + moIncr, 1) * ms;
let splitDate = new Date(split / ms);
let baseYear = splitDate[getFullYear]();
let baseMonth = splitDate[getMonth]();
for (let i = 0; split <= scaleMax; i++) {
let next = mkDate(baseYear + yrIncr * i, baseMonth + moIncr * i, 1);
let offs = next - tzDate(next * ms);
split = (+next + offs) * ms;
if (split <= scaleMax)
splits.push(split);
}
}
else {
let incr0 = foundIncr >= d ? d : foundIncr;
let tzOffset = floor(scaleMin) - floor(minDateTs);
let split = minMinTs + tzOffset + incrRoundUp(minDateTs - minMinTs, incr0);
splits.push(split);
let date0 = tzDate(split);
let prevHour = date0[getHours]() + (date0[getMinutes]() / m) + (date0[getSeconds]() / h);
let incrHours = foundIncr / h;
let minSpace = self.axes[axisIdx]._space;
let pctSpace = foundSpace / minSpace;
while (1) {
split = roundDec(split + foundIncr, ms == 1 ? 0 : 3);
if (split > scaleMax)
break;
if (incrHours > 1) {
let expectedHour = floor(roundDec(prevHour + incrHours, 6)) % 24;
let splitDate = tzDate(split);
let actualHour = splitDate.getHours();
let dstShift = actualHour - expectedHour;
if (dstShift > 1)
dstShift = -1;
split -= dstShift * h;
prevHour = (prevHour + incrHours) % 24;
// add a tick only if it's further than 70% of the min allowed label spacing
let prevSplit = splits[splits.length - 1];
let pctIncr = roundDec((split - prevSplit) / foundIncr, 3);
if (pctIncr * pctSpace >= .7)
splits.push(split);
}
else
splits.push(split);
}
}
return splits;
}
}
return [
timeIncrs,
_timeAxisStamps,
timeAxisSplits,
];
}
const [ timeIncrsMs, _timeAxisStampsMs, timeAxisSplitsMs ] = genTimeStuffs(1);
const [ timeIncrsS, _timeAxisStampsS, timeAxisSplitsS ] = genTimeStuffs(1e-3);
// base 2
const binIncrs = genIncrs(2, -53, 53, [1]);
@ -641,37 +770,6 @@ function timeAxisStamps(stampCfg, fmtDate) {
));
}
const NL = "\n";
const yyyy = "{YYYY}";
const NLyyyy = NL + yyyy;
const md = "{M}/{D}";
const NLmd = NL + md;
const NLmdyy = NLmd + "/{YY}";
const aa = "{aa}";
const hmm = "{h}:{mm}";
const hmmaa = hmm + aa;
const NLhmmaa = NL + hmmaa;
const ss = ":{ss}";
const _ = null;
// [0]: minimum num secs in the tick incr
// [1]: default tick format
// [2-7]: rollover tick formats
// [8]: mode: 0: replace [1] -> [2-7], 1: concat [1] + [2-7]
const _timeAxisStamps = [
// tick incr default year month day hour min sec mode
[y, yyyy, _, _, _, _, _, _, 1],
[d * 28, "{MMM}", NLyyyy, _, _, _, _, _, 1],
[d, md, NLyyyy, _, _, _, _, _, 1],
[h, "{h}" + aa, NLmdyy, _, NLmd, _, _, _, 1],
[m, hmmaa, NLmdyy, _, NLmd, _, _, _, 1],
[s, ss, NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
[1e-3, ss + ".{fff}", NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
];
// TODO: will need to accept spaces[] and pull incr into the loop when grid will be non-uniform, eg for log scales.
// currently we ignore this for months since they're *nearly* uniform and the added complexity is not worth it
function timeAxisVals(tzDate, stamps) {
@ -728,93 +826,6 @@ function mkDate(y, m, d) {
return new Date(y, m, d);
}
// the ensures that axis ticks, values & grid are aligned to logical temporal breakpoints and not an arbitrary timestamp
// https://www.timeanddate.com/time/dst/
// https://www.timeanddate.com/time/dst/2019.html
// https://www.epochconverter.com/timezones
function timeAxisSplits(tzDate) {
return (self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) => {
let splits = [];
let isYr = foundIncr >= y;
let isMo = foundIncr >= mo && foundIncr < y;
// get the timezone-adjusted date
let minDate = tzDate(scaleMin);
let minDateTs = minDate / 1e3;
// get ts of 12am (this lands us at or before the original scaleMin)
let minMin = mkDate(minDate[getFullYear](), isYr ? 0 : minDate[getMonth](), isMo || isYr ? 1 : minDate[getDate]());
let minMinTs = minMin / 1e3;
if (isMo || isYr) {
let moIncr = isMo ? foundIncr / mo : 0;
let yrIncr = isYr ? foundIncr / y : 0;
// let tzOffset = scaleMin - minDateTs; // needed?
let split = minDateTs == minMinTs ? minDateTs : mkDate(minMin[getFullYear]() + yrIncr, minMin[getMonth]() + moIncr, 1) / 1e3;
let splitDate = new Date(split * 1e3);
let baseYear = splitDate[getFullYear]();
let baseMonth = splitDate[getMonth]();
for (let i = 0; split <= scaleMax; i++) {
let next = mkDate(baseYear + yrIncr * i, baseMonth + moIncr * i, 1);
let offs = next - tzDate(next / 1e3);
split = (+next + offs) / 1e3;
if (split <= scaleMax)
splits.push(split);
}
}
else {
let incr0 = foundIncr >= d ? d : foundIncr;
let tzOffset = floor(scaleMin) - floor(minDateTs);
let split = minMinTs + tzOffset + incrRoundUp(minDateTs - minMinTs, incr0);
splits.push(split);
let date0 = tzDate(split);
let prevHour = date0[getHours]() + (date0[getMinutes]() / m) + (date0[getSeconds]() / h);
let incrHours = foundIncr / h;
let minSpace = self.axes[axisIdx]._space;
let pctSpace = foundSpace / minSpace;
while (1) {
split = roundDec(split + foundIncr, 3);
if (split > scaleMax)
break;
if (incrHours > 1) {
let expectedHour = floor(roundDec(prevHour + incrHours, 6)) % 24;
let splitDate = tzDate(split);
let actualHour = splitDate.getHours();
let dstShift = actualHour - expectedHour;
if (dstShift > 1)
dstShift = -1;
split -= dstShift * h;
prevHour = (prevHour + incrHours) % 24;
// add a tick only if it's further than 70% of the min allowed label spacing
let prevSplit = splits[splits.length - 1];
let pctIncr = roundDec((split - prevSplit) / foundIncr, 3);
if (pctIncr * pctSpace >= .7)
splits.push(split);
}
else
splits.push(split);
}
}
return splits;
}
}
function timeSeriesStamp(stampCfg, fmtDate) {
return fmtDate(stampCfg);
}
@ -1238,7 +1249,7 @@ function uPlot(opts, data, then) {
opts = p.opts(self, opts) || opts;
});
const ms = opts.ms || 1e-3;
const series = self.series = setDefaults(opts.series || [], xSeriesOpts, ySeriesOpts, false);
const axes = self.axes = setDefaults(opts.axes || [], xAxisOpts, yAxisOpts, true);
@ -1314,11 +1325,11 @@ function uPlot(opts, data, then) {
gutters._y = gutters.y(self);
// self.tz = opts.tz || Intl.DateTimeFormat().resolvedOptions().timeZone;
const _tzDate = (opts.tzDate || (ts => new Date(ts * 1e3)));
const _tzDate = (opts.tzDate || (ts => new Date(ts / ms)));
const _fmtDate = (opts.fmtDate || fmtDate);
const _timeAxisSplits = timeAxisSplits(_tzDate);
const _timeAxisVals = timeAxisVals(_tzDate, timeAxisStamps(_timeAxisStamps, _fmtDate));
const _timeAxisSplits = (ms == 1 ? timeAxisSplitsMs(_tzDate) : timeAxisSplitsS(_tzDate));
const _timeAxisVals = timeAxisVals(_tzDate, timeAxisStamps((ms == 1 ? _timeAxisStampsMs : _timeAxisStampsS), _fmtDate));
const _timeSeriesVal = timeSeriesVal(_tzDate, timeSeriesStamp(_timeSeriesStamp, _fmtDate));
const legend = assign({show: true, live: true}, opts.legend);
@ -1474,9 +1485,13 @@ function uPlot(opts, data, then) {
function convergeSize() {
let converged = false;
let cycleNum = 0;
while (!converged) {
let axesConverged = axesCalc();
let guttersConverged = guttersCalc();
cycleNum++;
let axesConverged = axesCalc(cycleNum);
let guttersConverged = guttersCalc(cycleNum);
converged = axesConverged && guttersConverged;
@ -1684,7 +1699,7 @@ function uPlot(opts, data, then) {
axis.size = fnOrSelf(axis.size);
axis.space = fnOrSelf(axis.space);
axis.rotate = fnOrSelf(axis.rotate);
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? wholeIncrs : (isTime ? timeIncrs : numIncrs)));
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? wholeIncrs : (isTime ? (ms == 1 ? timeIncrsMs : timeIncrsS) : numIncrs)));
axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
let av = axis.values;
@ -1703,7 +1718,7 @@ function uPlot(opts, data, then) {
axis.font = pxRatioFont(axis.font);
axis.labelFont = pxRatioFont(axis.labelFont);
axis._size = axis.size(self, null, i);
axis._size = axis.size(self, null, i, 0);
axis._space =
axis._rotate =
@ -1786,7 +1801,7 @@ function uPlot(opts, data, then) {
if (xScaleDistr == 3)
[_min, _max] = rangeLog(_min, _min, scales[xScaleKey].log, false);
else if (scales[xScaleKey].time)
_max = _min + 86400;
_max = _min + 86400 / ms;
else
[_min, _max] = rangeNum(_min, _max, 0.1, true);
}
@ -2324,7 +2339,7 @@ function uPlot(opts, data, then) {
ctx.translate(-offset, -offset);
}
function axesCalc() {
function axesCalc(cycleNum) {
// log("axesCalc()", arguments);
let converged = true;
@ -2378,7 +2393,7 @@ function uPlot(opts, data, then) {
let oldSize = axis._size;
axis._size = axis.size(self, values, i);
axis._size = ceil(axis.size(self, values, i, cycleNum));
if (oldSize != null && axis._size != oldSize) // ready && ?
converged = false;
@ -2387,13 +2402,13 @@ function uPlot(opts, data, then) {
return converged;
}
function guttersCalc() {
function guttersCalc(cycleNum) {
let converged = true;
let {_x, _y} = gutters;
gutters._x = gutters.x(self);
gutters._y = gutters.y(self);
gutters._x = ceil(gutters.x(self, cycleNum));
gutters._y = ceil(gutters.y(self, cycleNum));
if (gutters._x != _x || gutters._y != _y)
converged = false;

View file

@ -4,7 +4,7 @@
*
* uPlot.js (μPlot)
* A small, fast chart for time series, lines, areas, ohlc & bars
* https://github.com/leeoniya/uPlot (v1.4.4)
* https://github.com/leeoniya/uPlot (v1.4.6)
*/
var uPlot = (function () {
@ -552,8 +552,6 @@ var uPlot = (function () {
var allMults = [1,2,2.5,5];
var wholeMults = allMults.filter(onlyWhole);
// ...0.01, 0.02, 0.025, 0.05, 0.1, 0.2, 0.25, 0.5
var decIncrs = genIncrs(10, -16, 0, allMults);
@ -565,61 +563,196 @@ var uPlot = (function () {
var numIncrs = decIncrs.concat(oneIncrs);
var s = 1,
m = 60,
h = m * m,
d = h * 24,
mo = d * 30,
y = d * 365;
var NL = "\n";
// min of 1e-3 prevents setting a temporal x ticks too small since Date objects cannot advance ticks smaller than 1ms
var timeIncrs = genIncrs(10, -3, 0, wholeMults).concat([
// minute divisors (# of secs)
1,
5,
10,
15,
30,
// hour divisors (# of mins)
m,
m * 5,
m * 10,
m * 15,
m * 30,
// day divisors (# of hrs)
h,
h * 2,
h * 3,
h * 4,
h * 6,
h * 8,
h * 12,
// month divisors TODO: need more?
d,
d * 2,
d * 3,
d * 4,
d * 5,
d * 6,
d * 7,
d * 8,
d * 9,
d * 10,
d * 15,
// year divisors (# months, approx)
mo,
mo * 2,
mo * 3,
mo * 4,
mo * 6,
// century divisors
y,
y * 2,
y * 5,
y * 10,
y * 25,
y * 50,
y * 100 ]);
var yyyy = "{YYYY}";
var NLyyyy = NL + yyyy;
var md = "{M}/{D}";
var NLmd = NL + md;
var NLmdyy = NLmd + "/{YY}";
var aa = "{aa}";
var hmm = "{h}:{mm}";
var hmmaa = hmm + aa;
var NLhmmaa = NL + hmmaa;
var ss = ":{ss}";
var _ = null;
function genTimeStuffs(ms) {
var s = ms * 1e3,
m = s * 60,
h = m * 60,
d = h * 24,
mo = d * 30,
y = d * 365;
// min of 1e-3 prevents setting a temporal x ticks too small since Date objects cannot advance ticks smaller than 1ms
var subSecIncrs = ms == 1 ? genIncrs(10, 0, 3, allMults).filter(onlyWhole) : genIncrs(10, -3, 0, allMults);
var timeIncrs = subSecIncrs.concat([
// minute divisors (# of secs)
s,
s * 5,
s * 10,
s * 15,
s * 30,
// hour divisors (# of mins)
m,
m * 5,
m * 10,
m * 15,
m * 30,
// day divisors (# of hrs)
h,
h * 2,
h * 3,
h * 4,
h * 6,
h * 8,
h * 12,
// month divisors TODO: need more?
d,
d * 2,
d * 3,
d * 4,
d * 5,
d * 6,
d * 7,
d * 8,
d * 9,
d * 10,
d * 15,
// year divisors (# months, approx)
mo,
mo * 2,
mo * 3,
mo * 4,
mo * 6,
// century divisors
y,
y * 2,
y * 5,
y * 10,
y * 25,
y * 50,
y * 100 ]);
// [0]: minimum num secs in the tick incr
// [1]: default tick format
// [2-7]: rollover tick formats
// [8]: mode: 0: replace [1] -> [2-7], 1: concat [1] + [2-7]
var _timeAxisStamps = [
// tick incr default year month day hour min sec mode
[y, yyyy, _, _, _, _, _, _, 1],
[d * 28, "{MMM}", NLyyyy, _, _, _, _, _, 1],
[d, md, NLyyyy, _, _, _, _, _, 1],
[h, "{h}" + aa, NLmdyy, _, NLmd, _, _, _, 1],
[m, hmmaa, NLmdyy, _, NLmd, _, _, _, 1],
[s, ss, NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
[ms, ss + ".{fff}", NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1] ];
// the ensures that axis ticks, values & grid are aligned to logical temporal breakpoints and not an arbitrary timestamp
// https://www.timeanddate.com/time/dst/
// https://www.timeanddate.com/time/dst/2019.html
// https://www.epochconverter.com/timezones
function timeAxisSplits(tzDate) {
return function (self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) {
var splits = [];
var isYr = foundIncr >= y;
var isMo = foundIncr >= mo && foundIncr < y;
// get the timezone-adjusted date
var minDate = tzDate(scaleMin);
var minDateTs = minDate * ms;
// get ts of 12am (this lands us at or before the original scaleMin)
var minMin = mkDate(minDate[getFullYear](), isYr ? 0 : minDate[getMonth](), isMo || isYr ? 1 : minDate[getDate]());
var minMinTs = minMin * ms;
if (isMo || isYr) {
var moIncr = isMo ? foundIncr / mo : 0;
var yrIncr = isYr ? foundIncr / y : 0;
// let tzOffset = scaleMin - minDateTs; // needed?
var split = minDateTs == minMinTs ? minDateTs : mkDate(minMin[getFullYear]() + yrIncr, minMin[getMonth]() + moIncr, 1) * ms;
var splitDate = new Date(split / ms);
var baseYear = splitDate[getFullYear]();
var baseMonth = splitDate[getMonth]();
for (var i = 0; split <= scaleMax; i++) {
var next = mkDate(baseYear + yrIncr * i, baseMonth + moIncr * i, 1);
var offs = next - tzDate(next * ms);
split = (+next + offs) * ms;
if (split <= scaleMax)
{ splits.push(split); }
}
}
else {
var incr0 = foundIncr >= d ? d : foundIncr;
var tzOffset = floor(scaleMin) - floor(minDateTs);
var split$1 = minMinTs + tzOffset + incrRoundUp(minDateTs - minMinTs, incr0);
splits.push(split$1);
var date0 = tzDate(split$1);
var prevHour = date0[getHours]() + (date0[getMinutes]() / m) + (date0[getSeconds]() / h);
var incrHours = foundIncr / h;
var minSpace = self.axes[axisIdx]._space;
var pctSpace = foundSpace / minSpace;
while (1) {
split$1 = roundDec(split$1 + foundIncr, ms == 1 ? 0 : 3);
if (split$1 > scaleMax)
{ break; }
if (incrHours > 1) {
var expectedHour = floor(roundDec(prevHour + incrHours, 6)) % 24;
var splitDate$1 = tzDate(split$1);
var actualHour = splitDate$1.getHours();
var dstShift = actualHour - expectedHour;
if (dstShift > 1)
{ dstShift = -1; }
split$1 -= dstShift * h;
prevHour = (prevHour + incrHours) % 24;
// add a tick only if it's further than 70% of the min allowed label spacing
var prevSplit = splits[splits.length - 1];
var pctIncr = roundDec((split$1 - prevSplit) / foundIncr, 3);
if (pctIncr * pctSpace >= .7)
{ splits.push(split$1); }
}
else
{ splits.push(split$1); }
}
}
return splits;
}
}
return [
timeIncrs,
_timeAxisStamps,
timeAxisSplits ];
}
var ref = genTimeStuffs(1);
var timeIncrsMs = ref[0];
var _timeAxisStampsMs = ref[1];
var timeAxisSplitsMs = ref[2];
var ref$1 = genTimeStuffs(1e-3);
var timeIncrsS = ref$1[0];
var _timeAxisStampsS = ref$1[1];
var timeAxisSplitsS = ref$1[2];
// base 2
var binIncrs = genIncrs(2, -53, 53, [1]);
@ -640,36 +773,6 @@ var uPlot = (function () {
); });
}
var NL = "\n";
var yyyy = "{YYYY}";
var NLyyyy = NL + yyyy;
var md = "{M}/{D}";
var NLmd = NL + md;
var NLmdyy = NLmd + "/{YY}";
var aa = "{aa}";
var hmm = "{h}:{mm}";
var hmmaa = hmm + aa;
var NLhmmaa = NL + hmmaa;
var ss = ":{ss}";
var _ = null;
// [0]: minimum num secs in the tick incr
// [1]: default tick format
// [2-7]: rollover tick formats
// [8]: mode: 0: replace [1] -> [2-7], 1: concat [1] + [2-7]
var _timeAxisStamps = [
// tick incr default year month day hour min sec mode
[y, yyyy, _, _, _, _, _, _, 1],
[d * 28, "{MMM}", NLyyyy, _, _, _, _, _, 1],
[d, md, NLyyyy, _, _, _, _, _, 1],
[h, "{h}" + aa, NLmdyy, _, NLmd, _, _, _, 1],
[m, hmmaa, NLmdyy, _, NLmd, _, _, _, 1],
[s, ss, NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1],
[1e-3, ss + ".{fff}", NLmdyy + " " + hmmaa, _, NLmd + " " + hmmaa, _, NLhmmaa, _, 1] ];
// TODO: will need to accept spaces[] and pull incr into the loop when grid will be non-uniform, eg for log scales.
// currently we ignore this for months since they're *nearly* uniform and the added complexity is not worth it
function timeAxisVals(tzDate, stamps) {
@ -726,93 +829,6 @@ var uPlot = (function () {
return new Date(y, m, d);
}
// the ensures that axis ticks, values & grid are aligned to logical temporal breakpoints and not an arbitrary timestamp
// https://www.timeanddate.com/time/dst/
// https://www.timeanddate.com/time/dst/2019.html
// https://www.epochconverter.com/timezones
function timeAxisSplits(tzDate) {
return function (self, axisIdx, scaleMin, scaleMax, foundIncr, foundSpace) {
var splits = [];
var isYr = foundIncr >= y;
var isMo = foundIncr >= mo && foundIncr < y;
// get the timezone-adjusted date
var minDate = tzDate(scaleMin);
var minDateTs = minDate / 1e3;
// get ts of 12am (this lands us at or before the original scaleMin)
var minMin = mkDate(minDate[getFullYear](), isYr ? 0 : minDate[getMonth](), isMo || isYr ? 1 : minDate[getDate]());
var minMinTs = minMin / 1e3;
if (isMo || isYr) {
var moIncr = isMo ? foundIncr / mo : 0;
var yrIncr = isYr ? foundIncr / y : 0;
// let tzOffset = scaleMin - minDateTs; // needed?
var split = minDateTs == minMinTs ? minDateTs : mkDate(minMin[getFullYear]() + yrIncr, minMin[getMonth]() + moIncr, 1) / 1e3;
var splitDate = new Date(split * 1e3);
var baseYear = splitDate[getFullYear]();
var baseMonth = splitDate[getMonth]();
for (var i = 0; split <= scaleMax; i++) {
var next = mkDate(baseYear + yrIncr * i, baseMonth + moIncr * i, 1);
var offs = next - tzDate(next / 1e3);
split = (+next + offs) / 1e3;
if (split <= scaleMax)
{ splits.push(split); }
}
}
else {
var incr0 = foundIncr >= d ? d : foundIncr;
var tzOffset = floor(scaleMin) - floor(minDateTs);
var split$1 = minMinTs + tzOffset + incrRoundUp(minDateTs - minMinTs, incr0);
splits.push(split$1);
var date0 = tzDate(split$1);
var prevHour = date0[getHours]() + (date0[getMinutes]() / m) + (date0[getSeconds]() / h);
var incrHours = foundIncr / h;
var minSpace = self.axes[axisIdx]._space;
var pctSpace = foundSpace / minSpace;
while (1) {
split$1 = roundDec(split$1 + foundIncr, 3);
if (split$1 > scaleMax)
{ break; }
if (incrHours > 1) {
var expectedHour = floor(roundDec(prevHour + incrHours, 6)) % 24;
var splitDate$1 = tzDate(split$1);
var actualHour = splitDate$1.getHours();
var dstShift = actualHour - expectedHour;
if (dstShift > 1)
{ dstShift = -1; }
split$1 -= dstShift * h;
prevHour = (prevHour + incrHours) % 24;
// add a tick only if it's further than 70% of the min allowed label spacing
var prevSplit = splits[splits.length - 1];
var pctIncr = roundDec((split$1 - prevSplit) / foundIncr, 3);
if (pctIncr * pctSpace >= .7)
{ splits.push(split$1); }
}
else
{ splits.push(split$1); }
}
}
return splits;
}
}
function timeSeriesStamp(stampCfg, fmtDate) {
return fmtDate(stampCfg);
}
@ -1236,7 +1252,7 @@ var uPlot = (function () {
{ opts = p.opts(self, opts) || opts; }
});
var ms = opts.ms || 1e-3;
var series = self.series = setDefaults(opts.series || [], xSeriesOpts, ySeriesOpts, false);
var axes = self.axes = setDefaults(opts.axes || [], xAxisOpts, yAxisOpts, true);
@ -1312,11 +1328,11 @@ var uPlot = (function () {
gutters._y = gutters.y(self);
// self.tz = opts.tz || Intl.DateTimeFormat().resolvedOptions().timeZone;
var _tzDate = (opts.tzDate || (function (ts) { return new Date(ts * 1e3); }));
var _tzDate = (opts.tzDate || (function (ts) { return new Date(ts / ms); }));
var _fmtDate = (opts.fmtDate || fmtDate);
var _timeAxisSplits = timeAxisSplits(_tzDate);
var _timeAxisVals = timeAxisVals(_tzDate, timeAxisStamps(_timeAxisStamps, _fmtDate));
var _timeAxisSplits = (ms == 1 ? timeAxisSplitsMs(_tzDate) : timeAxisSplitsS(_tzDate));
var _timeAxisVals = timeAxisVals(_tzDate, timeAxisStamps((ms == 1 ? _timeAxisStampsMs : _timeAxisStampsS), _fmtDate));
var _timeSeriesVal = timeSeriesVal(_tzDate, timeSeriesStamp(_timeSeriesStamp, _fmtDate));
var legend = assign({show: true, live: true}, opts.legend);
@ -1472,9 +1488,13 @@ var uPlot = (function () {
function convergeSize() {
var converged = false;
var cycleNum = 0;
while (!converged) {
var axesConverged = axesCalc();
var guttersConverged = guttersCalc();
cycleNum++;
var axesConverged = axesCalc(cycleNum);
var guttersConverged = guttersCalc(cycleNum);
converged = axesConverged && guttersConverged;
@ -1686,7 +1706,7 @@ var uPlot = (function () {
axis.size = fnOrSelf(axis.size);
axis.space = fnOrSelf(axis.space);
axis.rotate = fnOrSelf(axis.rotate);
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? wholeIncrs : (isTime ? timeIncrs : numIncrs)));
axis.incrs = fnOrSelf(axis.incrs || ( sc.distr == 2 ? wholeIncrs : (isTime ? (ms == 1 ? timeIncrsMs : timeIncrsS) : numIncrs)));
axis.splits = fnOrSelf(axis.splits || (isTime && sc.distr == 1 ? _timeAxisSplits : sc.distr == 3 ? logAxisSplits : numAxisSplits));
var av = axis.values;
@ -1705,7 +1725,7 @@ var uPlot = (function () {
axis.font = pxRatioFont(axis.font);
axis.labelFont = pxRatioFont(axis.labelFont);
axis._size = axis.size(self, null, i);
axis._size = axis.size(self, null, i, 0);
axis._space =
axis._rotate =
@ -1790,7 +1810,7 @@ var uPlot = (function () {
if (xScaleDistr == 3)
{ (assign = rangeLog(_min, _min, scales[xScaleKey].log, false), _min = assign[0], _max = assign[1]); }
else if (scales[xScaleKey].time)
{ _max = _min + 86400; }
{ _max = _min + 86400 / ms; }
else
{ (assign$1 = rangeNum(_min, _max, 0.1, true), _min = assign$1[0], _max = assign$1[1]); }
}
@ -2331,7 +2351,7 @@ var uPlot = (function () {
ctx.translate(-offset, -offset);
}
function axesCalc() {
function axesCalc(cycleNum) {
// log("axesCalc()", arguments);
var converged = true;
@ -2388,7 +2408,7 @@ var uPlot = (function () {
var oldSize = axis._size;
axis._size = axis.size(self, values, i);
axis._size = ceil(axis.size(self, values, i, cycleNum));
if (oldSize != null && axis._size != oldSize) // ready && ?
{ converged = false; }
@ -2397,14 +2417,14 @@ var uPlot = (function () {
return converged;
}
function guttersCalc() {
function guttersCalc(cycleNum) {
var converged = true;
var _x = gutters._x;
var _y = gutters._y;
gutters._x = gutters.x(self);
gutters._y = gutters.y(self);
gutters._x = ceil(gutters.x(self, cycleNum));
gutters._y = ceil(gutters.y(self, cycleNum));
if (gutters._x != _x || gutters._y != _y)
{ converged = false; }

File diff suppressed because one or more lines are too long