Skip to content

Commit 0575cab

Browse files
committed
fix partial magnitudes in uPlot.rangeLog(). close #1052.
1 parent 9dbbdc7 commit 0575cab

File tree

7 files changed

+144
-53
lines changed

7 files changed

+144
-53
lines changed

demos/log-scales2.html

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,73 @@
420420

421421
let u = new uPlot(opts, data, document.body);
422422
}
423+
424+
const fmtTick = new Intl.NumberFormat(undefined, {
425+
notation: "compact",
426+
compactDisplay: "short",
427+
}).format;
428+
429+
{
430+
function makeChart(data) {
431+
const opts = {
432+
title: "Partial mags (base 10)",
433+
width: 600,
434+
height: 300,
435+
axes: [
436+
{},
437+
{
438+
scale: 'y0',
439+
side: 3,
440+
values: (u, splits) => splits.map(fmtTick),
441+
},
442+
{
443+
scale: 'y1',
444+
side: 1,
445+
values: (u, splits) => splits.map(fmtTick),
446+
},
447+
],
448+
scales: {
449+
y0: {
450+
distr: 3,
451+
range: (u, dataMin, dataMax) => uPlot.rangeLog(dataMin, dataMax, 10, false),
452+
},
453+
y1: {
454+
distr: 3,
455+
range: (u, dataMin, dataMax) => uPlot.rangeLog(dataMin, dataMax, 10, false),
456+
},
457+
},
458+
series: [
459+
{},
460+
{
461+
label: 'A',
462+
scale: 'y0',
463+
stroke: '#f7931a',
464+
},
465+
{
466+
label: 'B',
467+
scale: 'y1',
468+
stroke: '#000',
469+
},
470+
]
471+
};
472+
473+
let u = new uPlot(opts, data, document.body);
474+
475+
return u;
476+
}
477+
478+
makeChart([
479+
[1704326400, 1704412800, 1704499200],
480+
[1000001, 1000000, 990000],
481+
[99000, 100000, 100000.001]
482+
]);
483+
484+
makeChart([
485+
[1704326400, 1704412800, 1704499200],
486+
[1000001, 1000000, 990000].map(v => v / 10_000_000),
487+
[99000, 100000, 100000.001].map(v => v / 1_000_000),
488+
]);
489+
}
423490
</script>
424491
</body>
425492
</html>

dist/uPlot.cjs.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ function getMinMax(data, _i0, _i1, sorted = 0, log = false) {
102102
}
103103

104104
function rangeLog(min, max, base, fullMags) {
105+
if (base == 2)
106+
fullMags = true;
107+
105108
let minSign = sign(min);
106109
let maxSign = sign(max);
107110

@@ -121,8 +124,11 @@ function rangeLog(min, max, base, fullMags) {
121124
let growMinAbs = minSign == 1 ? floor : ceil;
122125
let growMaxAbs = maxSign == 1 ? ceil : floor;
123126

124-
let minExp = growMinAbs(logFn(abs(min)));
125-
let maxExp = growMaxAbs(logFn(abs(max)));
127+
let minLogAbs = logFn(abs(min));
128+
let maxLogAbs = logFn(abs(max));
129+
130+
let minExp = growMinAbs(minLogAbs);
131+
let maxExp = growMaxAbs(maxLogAbs);
126132

127133
let minIncr = pow(base, minExp);
128134
let maxIncr = pow(base, maxExp);
@@ -135,13 +141,13 @@ function rangeLog(min, max, base, fullMags) {
135141
maxIncr = roundDec(maxIncr, -maxExp);
136142
}
137143

138-
if (fullMags || base == 2) {
144+
if (fullMags) {
139145
min = minIncr * minSign;
140146
max = maxIncr * maxSign;
141147
}
142148
else {
143-
min = incrRoundDn(min, minIncr);
144-
max = incrRoundUp(max, maxIncr);
149+
min = incrRoundDn(min, pow(base, floor(minLogAbs)), false);
150+
max = incrRoundUp(max, pow(base, floor(maxLogAbs)), false);
145151
}
146152

147153
return [min, max];
@@ -355,16 +361,16 @@ const fixFloat = val => {
355361
return roundDec(val, len);
356362
};
357363

358-
function incrRound(num, incr) {
359-
return fixFloat(roundDec(fixFloat(num/incr))*incr);
364+
function incrRound(num, incr, _fixFloat = true) {
365+
return _fixFloat ? fixFloat(roundDec(fixFloat(num/incr))*incr) : roundDec(num/incr)*incr;
360366
}
361367

362-
function incrRoundUp(num, incr) {
363-
return fixFloat(ceil(fixFloat(num/incr))*incr);
368+
function incrRoundUp(num, incr, _fixFloat = true) {
369+
return _fixFloat ? fixFloat(ceil(fixFloat(num/incr))*incr) : ceil(num/incr)*incr;
364370
}
365371

366-
function incrRoundDn(num, incr) {
367-
return fixFloat(floor(fixFloat(num/incr))*incr);
372+
function incrRoundDn(num, incr, _fixFloat = true) {
373+
return _fixFloat ? fixFloat(floor(fixFloat(num/incr))*incr) : floor(num/incr)*incr;
368374
}
369375

370376
// https://stackoverflow.com/a/48764436
@@ -2865,13 +2871,13 @@ function snapNumY(self, dataMin, dataMax) {
28652871
}
28662872

28672873
function snapLogY(self, dataMin, dataMax, scale) {
2868-
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, false);
2874+
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, true);
28692875
}
28702876

28712877
const snapLogX = snapLogY;
28722878

28732879
function snapAsinhY(self, dataMin, dataMax, scale) {
2874-
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, false);
2880+
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, true);
28752881
}
28762882

28772883
const snapAsinhX = snapAsinhY;

dist/uPlot.esm.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ function getMinMax(data, _i0, _i1, sorted = 0, log = false) {
100100
}
101101

102102
function rangeLog(min, max, base, fullMags) {
103+
if (base == 2)
104+
fullMags = true;
105+
103106
let minSign = sign(min);
104107
let maxSign = sign(max);
105108

@@ -119,8 +122,11 @@ function rangeLog(min, max, base, fullMags) {
119122
let growMinAbs = minSign == 1 ? floor : ceil;
120123
let growMaxAbs = maxSign == 1 ? ceil : floor;
121124

122-
let minExp = growMinAbs(logFn(abs(min)));
123-
let maxExp = growMaxAbs(logFn(abs(max)));
125+
let minLogAbs = logFn(abs(min));
126+
let maxLogAbs = logFn(abs(max));
127+
128+
let minExp = growMinAbs(minLogAbs);
129+
let maxExp = growMaxAbs(maxLogAbs);
124130

125131
let minIncr = pow(base, minExp);
126132
let maxIncr = pow(base, maxExp);
@@ -133,13 +139,13 @@ function rangeLog(min, max, base, fullMags) {
133139
maxIncr = roundDec(maxIncr, -maxExp);
134140
}
135141

136-
if (fullMags || base == 2) {
142+
if (fullMags) {
137143
min = minIncr * minSign;
138144
max = maxIncr * maxSign;
139145
}
140146
else {
141-
min = incrRoundDn(min, minIncr);
142-
max = incrRoundUp(max, maxIncr);
147+
min = incrRoundDn(min, pow(base, floor(minLogAbs)), false);
148+
max = incrRoundUp(max, pow(base, floor(maxLogAbs)), false);
143149
}
144150

145151
return [min, max];
@@ -353,16 +359,16 @@ const fixFloat = val => {
353359
return roundDec(val, len);
354360
};
355361

356-
function incrRound(num, incr) {
357-
return fixFloat(roundDec(fixFloat(num/incr))*incr);
362+
function incrRound(num, incr, _fixFloat = true) {
363+
return _fixFloat ? fixFloat(roundDec(fixFloat(num/incr))*incr) : roundDec(num/incr)*incr;
358364
}
359365

360-
function incrRoundUp(num, incr) {
361-
return fixFloat(ceil(fixFloat(num/incr))*incr);
366+
function incrRoundUp(num, incr, _fixFloat = true) {
367+
return _fixFloat ? fixFloat(ceil(fixFloat(num/incr))*incr) : ceil(num/incr)*incr;
362368
}
363369

364-
function incrRoundDn(num, incr) {
365-
return fixFloat(floor(fixFloat(num/incr))*incr);
370+
function incrRoundDn(num, incr, _fixFloat = true) {
371+
return _fixFloat ? fixFloat(floor(fixFloat(num/incr))*incr) : floor(num/incr)*incr;
366372
}
367373

368374
// https://stackoverflow.com/a/48764436
@@ -2863,13 +2869,13 @@ function snapNumY(self, dataMin, dataMax) {
28632869
}
28642870

28652871
function snapLogY(self, dataMin, dataMax, scale) {
2866-
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, false);
2872+
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, true);
28672873
}
28682874

28692875
const snapLogX = snapLogY;
28702876

28712877
function snapAsinhY(self, dataMin, dataMax, scale) {
2872-
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, false);
2878+
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, true);
28732879
}
28742880

28752881
const snapAsinhX = snapAsinhY;

dist/uPlot.iife.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ var uPlot = (function () {
103103
}
104104

105105
function rangeLog(min, max, base, fullMags) {
106+
if (base == 2)
107+
fullMags = true;
108+
106109
let minSign = sign(min);
107110
let maxSign = sign(max);
108111

@@ -122,8 +125,11 @@ var uPlot = (function () {
122125
let growMinAbs = minSign == 1 ? floor : ceil;
123126
let growMaxAbs = maxSign == 1 ? ceil : floor;
124127

125-
let minExp = growMinAbs(logFn(abs(min)));
126-
let maxExp = growMaxAbs(logFn(abs(max)));
128+
let minLogAbs = logFn(abs(min));
129+
let maxLogAbs = logFn(abs(max));
130+
131+
let minExp = growMinAbs(minLogAbs);
132+
let maxExp = growMaxAbs(maxLogAbs);
127133

128134
let minIncr = pow(base, minExp);
129135
let maxIncr = pow(base, maxExp);
@@ -136,13 +142,13 @@ var uPlot = (function () {
136142
maxIncr = roundDec(maxIncr, -maxExp);
137143
}
138144

139-
if (fullMags || base == 2) {
145+
if (fullMags) {
140146
min = minIncr * minSign;
141147
max = maxIncr * maxSign;
142148
}
143149
else {
144-
min = incrRoundDn(min, minIncr);
145-
max = incrRoundUp(max, maxIncr);
150+
min = incrRoundDn(min, pow(base, floor(minLogAbs)), false);
151+
max = incrRoundUp(max, pow(base, floor(maxLogAbs)), false);
146152
}
147153

148154
return [min, max];
@@ -356,16 +362,16 @@ var uPlot = (function () {
356362
return roundDec(val, len);
357363
};
358364

359-
function incrRound(num, incr) {
360-
return fixFloat(roundDec(fixFloat(num/incr))*incr);
365+
function incrRound(num, incr, _fixFloat = true) {
366+
return _fixFloat ? fixFloat(roundDec(fixFloat(num/incr))*incr) : roundDec(num/incr)*incr;
361367
}
362368

363-
function incrRoundUp(num, incr) {
364-
return fixFloat(ceil(fixFloat(num/incr))*incr);
369+
function incrRoundUp(num, incr, _fixFloat = true) {
370+
return _fixFloat ? fixFloat(ceil(fixFloat(num/incr))*incr) : ceil(num/incr)*incr;
365371
}
366372

367-
function incrRoundDn(num, incr) {
368-
return fixFloat(floor(fixFloat(num/incr))*incr);
373+
function incrRoundDn(num, incr, _fixFloat = true) {
374+
return _fixFloat ? fixFloat(floor(fixFloat(num/incr))*incr) : floor(num/incr)*incr;
369375
}
370376

371377
// https://stackoverflow.com/a/48764436
@@ -2866,13 +2872,13 @@ var uPlot = (function () {
28662872
}
28672873

28682874
function snapLogY(self, dataMin, dataMax, scale) {
2869-
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, false);
2875+
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, true);
28702876
}
28712877

28722878
const snapLogX = snapLogY;
28732879

28742880
function snapAsinhY(self, dataMin, dataMax, scale) {
2875-
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, false);
2881+
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, true);
28762882
}
28772883

28782884
const snapAsinhX = snapAsinhY;

dist/uPlot.iife.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uPlot.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,13 @@ function snapNumY(self, dataMin, dataMax) {
242242
}
243243

244244
function snapLogY(self, dataMin, dataMax, scale) {
245-
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, false);
245+
return dataMin == null ? nullNullTuple : rangeLog(dataMin, dataMax, self.scales[scale].log, true);
246246
}
247247

248248
const snapLogX = snapLogY;
249249

250250
function snapAsinhY(self, dataMin, dataMax, scale) {
251-
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, false);
251+
return dataMin == null ? nullNullTuple : rangeAsinh(dataMin, dataMax, self.scales[scale].log, true);
252252
}
253253

254254
const snapAsinhX = snapAsinhY;

src/utils.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ export function getMinMax(data, _i0, _i1, sorted = 0, log = false) {
8989
}
9090

9191
export function rangeLog(min, max, base, fullMags) {
92+
if (base == 2)
93+
fullMags = true;
94+
9295
let minSign = sign(min);
9396
let maxSign = sign(max);
9497

@@ -108,8 +111,11 @@ export function rangeLog(min, max, base, fullMags) {
108111
let growMinAbs = minSign == 1 ? floor : ceil;
109112
let growMaxAbs = maxSign == 1 ? ceil : floor;
110113

111-
let minExp = growMinAbs(logFn(abs(min)));
112-
let maxExp = growMaxAbs(logFn(abs(max)));
114+
let minLogAbs = logFn(abs(min))
115+
let maxLogAbs = logFn(abs(max));
116+
117+
let minExp = growMinAbs(minLogAbs);
118+
let maxExp = growMaxAbs(maxLogAbs);
113119

114120
let minIncr = pow(base, minExp);
115121
let maxIncr = pow(base, maxExp);
@@ -122,13 +128,13 @@ export function rangeLog(min, max, base, fullMags) {
122128
maxIncr = roundDec(maxIncr, -maxExp);
123129
}
124130

125-
if (fullMags || base == 2) {
131+
if (fullMags) {
126132
min = minIncr * minSign;
127133
max = maxIncr * maxSign;
128134
}
129135
else {
130-
min = incrRoundDn(min, minIncr);
131-
max = incrRoundUp(max, maxIncr);
136+
min = incrRoundDn(min, pow(base, floor(minLogAbs)), false);
137+
max = incrRoundUp(max, pow(base, floor(maxLogAbs)), false);
132138
}
133139

134140
return [min, max];
@@ -343,16 +349,16 @@ const fixFloat = val => {
343349
return roundDec(val, len);
344350
}
345351

346-
export function incrRound(num, incr) {
347-
return fixFloat(roundDec(fixFloat(num/incr))*incr);
352+
export function incrRound(num, incr, _fixFloat = true) {
353+
return _fixFloat ? fixFloat(roundDec(fixFloat(num/incr))*incr) : roundDec(num/incr)*incr;
348354
}
349355

350-
export function incrRoundUp(num, incr) {
351-
return fixFloat(ceil(fixFloat(num/incr))*incr);
356+
export function incrRoundUp(num, incr, _fixFloat = true) {
357+
return _fixFloat ? fixFloat(ceil(fixFloat(num/incr))*incr) : ceil(num/incr)*incr;
352358
}
353359

354-
export function incrRoundDn(num, incr) {
355-
return fixFloat(floor(fixFloat(num/incr))*incr);
360+
export function incrRoundDn(num, incr, _fixFloat = true) {
361+
return _fixFloat ? fixFloat(floor(fixFloat(num/incr))*incr) : floor(num/incr)*incr;
356362
}
357363

358364
// https://stackoverflow.com/a/48764436

0 commit comments

Comments
 (0)