@funnest/charts-viz 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +36 -9
- package/dist/path.d.ts +3 -3
- package/dist/scale.d.ts +14 -0
- package/dist/ticks.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Pure TypeScript with no DOM access, so the same scales, ticks and SVG path strings
|
|
5
5
|
* drive the web components (@funnest/charts-react) and React Native (react-native-svg).
|
|
6
6
|
*/
|
|
7
|
-
export { linearScale, bandScale, clamp, type LinearScale, type BandScale } from './scale';
|
|
8
|
-
export { niceStep, niceDomain, ticks, sampleIndices } from './ticks';
|
|
7
|
+
export { linearScale, logScale, bandScale, clamp, type LinearScale, type LogScale, type ValueScale, type BandScale } from './scale';
|
|
8
|
+
export { niceStep, niceDomain, ticks, logTicks, sampleIndices } from './ticks';
|
|
9
9
|
export { linePath, areaPath, barPath, segments, type XY, type Curve } from './path';
|
|
10
10
|
export { extent, maxLength, stack, stackedExtent, percentages, nearestIndex, seriesChange, type SeriesData, type StackedSeries, type PercentageSegment, } from './data';
|
|
11
11
|
export { DEFAULT_PALETTE, seriesColor } from './palette';
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,15 @@ function linearScale(domain, range) {
|
|
|
8
8
|
Object.assign(scale, { kind: "linear", domain: [d0, d1], range: [r0, r1] });
|
|
9
9
|
return scale;
|
|
10
10
|
}
|
|
11
|
+
function logScale(domain, range) {
|
|
12
|
+
const d0 = Math.max(Number.MIN_VALUE, domain[0]);
|
|
13
|
+
const d1 = Math.max(d0, domain[1]);
|
|
14
|
+
const inner = linearScale([Math.log10(d0), Math.log10(d1)], range);
|
|
15
|
+
const scale = ((v) => inner(Math.log10(Math.max(v, d0))));
|
|
16
|
+
scale.invert = (p) => 10 ** inner.invert(p);
|
|
17
|
+
Object.assign(scale, { kind: "log", domain: [d0, d1], range: [range[0], range[1]] });
|
|
18
|
+
return scale;
|
|
19
|
+
}
|
|
11
20
|
function bandScale(count, range, padding = 0.2) {
|
|
12
21
|
const [r0, r1] = range;
|
|
13
22
|
const n = Math.max(1, count);
|
|
@@ -61,6 +70,22 @@ function sampleIndices(count, max) {
|
|
|
61
70
|
for (let i = 0; i < count; i += every) out.push(i);
|
|
62
71
|
return out;
|
|
63
72
|
}
|
|
73
|
+
function logTicks(min, max, count = 5) {
|
|
74
|
+
if (!(min > 0) || !(max > min)) return ticks(min, max, count);
|
|
75
|
+
const lo = Math.floor(Math.log10(min));
|
|
76
|
+
const hi = Math.ceil(Math.log10(max));
|
|
77
|
+
if (hi - lo <= 1) return ticks(min, max, count);
|
|
78
|
+
const pick = (mults) => {
|
|
79
|
+
const out = [];
|
|
80
|
+
for (let e = lo; e <= hi; e++) for (const m of mults) {
|
|
81
|
+
const v = round(m * 10 ** e);
|
|
82
|
+
if (v >= min * (1 - 1e-9) && v <= max * (1 + 1e-9)) out.push(v);
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
};
|
|
86
|
+
const dense = pick([1, 2, 5]);
|
|
87
|
+
return dense.length <= count * 2 ? dense : pick([1]);
|
|
88
|
+
}
|
|
64
89
|
|
|
65
90
|
// src/path.ts
|
|
66
91
|
var f = (n) => (Math.round(n * 100) / 100).toString();
|
|
@@ -118,17 +143,17 @@ function segments(values) {
|
|
|
118
143
|
});
|
|
119
144
|
return out;
|
|
120
145
|
}
|
|
121
|
-
function barPath(x, width, baseY, valueY, radius = 0) {
|
|
146
|
+
function barPath(x, width, baseY, valueY, radius = 0, roundBase = false) {
|
|
122
147
|
const top = Math.min(baseY, valueY);
|
|
123
|
-
const
|
|
124
|
-
const
|
|
148
|
+
const bottom = Math.max(baseY, valueY);
|
|
149
|
+
const h = bottom - top;
|
|
125
150
|
const x1 = x + width;
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
return `M${f(x)},${f(
|
|
151
|
+
const r = Math.max(0, Math.min(radius, width / 2, roundBase ? h / 2 : h));
|
|
152
|
+
if (r === 0) return `M${f(x)},${f(top)}H${f(x1)}V${f(bottom)}H${f(x)}Z`;
|
|
153
|
+
const up = valueY <= baseY;
|
|
154
|
+
const rTop = up || roundBase ? r : 0;
|
|
155
|
+
const rBottom = !up || roundBase ? r : 0;
|
|
156
|
+
return `M${f(x)},${f(top + rTop)}` + (rTop ? `Q${f(x)},${f(top)} ${f(x + rTop)},${f(top)}` : "") + `H${f(x1 - rTop)}` + (rTop ? `Q${f(x1)},${f(top)} ${f(x1)},${f(top + rTop)}` : "") + `V${f(bottom - rBottom)}` + (rBottom ? `Q${f(x1)},${f(bottom)} ${f(x1 - rBottom)},${f(bottom)}` : "") + `H${f(x + rBottom)}` + (rBottom ? `Q${f(x)},${f(bottom)} ${f(x)},${f(bottom - rBottom)}` : "") + "Z";
|
|
132
157
|
}
|
|
133
158
|
function monotoneSegments(p) {
|
|
134
159
|
const n = p.length;
|
|
@@ -260,6 +285,8 @@ export {
|
|
|
260
285
|
extent,
|
|
261
286
|
linePath,
|
|
262
287
|
linearScale,
|
|
288
|
+
logScale,
|
|
289
|
+
logTicks,
|
|
263
290
|
maxLength,
|
|
264
291
|
nearestIndex,
|
|
265
292
|
niceDomain,
|
package/dist/path.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function segments<T>(values: readonly (T | null | undefined)[]):
|
|
|
20
20
|
values: T[];
|
|
21
21
|
}[];
|
|
22
22
|
/**
|
|
23
|
-
* Bar from `baseY` to `valueY` (pixels)
|
|
24
|
-
*
|
|
23
|
+
* Bar from `baseY` to `valueY` (pixels). `radius` rounds the end away from the baseline
|
|
24
|
+
* (negative bars round at the bottom); `roundBase` rounds the baseline end too.
|
|
25
25
|
*/
|
|
26
|
-
export declare function barPath(x: number, width: number, baseY: number, valueY: number, radius?: number): string;
|
|
26
|
+
export declare function barPath(x: number, width: number, baseY: number, valueY: number, radius?: number, roundBase?: boolean): string;
|
package/dist/scale.d.ts
CHANGED
|
@@ -7,6 +7,20 @@ export interface LinearScale {
|
|
|
7
7
|
invert(pixel: number): number;
|
|
8
8
|
}
|
|
9
9
|
export declare function linearScale(domain: readonly [number, number], range: readonly [number, number]): LinearScale;
|
|
10
|
+
/**
|
|
11
|
+
* A log10 scale for values spanning orders of magnitude (long-term price charts).
|
|
12
|
+
* Domain values must be positive; non-positive inputs clamp to the domain minimum.
|
|
13
|
+
*/
|
|
14
|
+
export interface LogScale {
|
|
15
|
+
readonly kind: 'log';
|
|
16
|
+
readonly domain: readonly [number, number];
|
|
17
|
+
readonly range: readonly [number, number];
|
|
18
|
+
(value: number): number;
|
|
19
|
+
invert(pixel: number): number;
|
|
20
|
+
}
|
|
21
|
+
export declare function logScale(domain: readonly [number, number], range: readonly [number, number]): LogScale;
|
|
22
|
+
/** Either value scale; both map a value to a pixel and back. */
|
|
23
|
+
export type ValueScale = LinearScale | LogScale;
|
|
10
24
|
/** A categorical scale: `count` equal bands across the range, each with inner padding. */
|
|
11
25
|
export interface BandScale {
|
|
12
26
|
readonly kind: 'band';
|
package/dist/ticks.d.ts
CHANGED
|
@@ -9,3 +9,8 @@ export declare function ticks(min: number, max: number, count?: number): number[
|
|
|
9
9
|
* always keeping the first one.
|
|
10
10
|
*/
|
|
11
11
|
export declare function sampleIndices(count: number, max: number): number[];
|
|
12
|
+
/**
|
|
13
|
+
* Ticks for a log scale: 1, 2, 5 × 10ⁿ inside [min, max] (min > 0). Falls back to powers
|
|
14
|
+
* of ten alone when that would be too many, and to linear ticks for a narrow range.
|
|
15
|
+
*/
|
|
16
|
+
export declare function logTicks(min: number, max: number, count?: number): number[];
|
package/package.json
CHANGED