@ggterm/core 0.2.7 → 0.2.10
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/cli-plot.js +387 -6
- package/dist/cli.js +378 -5
- package/dist/geoms/index.d.ts +1 -0
- package/dist/geoms/index.d.ts.map +1 -1
- package/dist/geoms/ridgeline.d.ts +52 -0
- package/dist/geoms/ridgeline.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +382 -5
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/render-geoms.d.ts +6 -0
- package/dist/pipeline/render-geoms.d.ts.map +1 -1
- package/dist/pipeline/scales.d.ts.map +1 -1
- package/dist/stats/density.d.ts +5 -0
- package/dist/stats/density.d.ts.map +1 -1
- package/dist/stats/density2d.d.ts +36 -0
- package/dist/stats/density2d.d.ts.map +1 -0
- package/dist/stats/index.d.ts +3 -1
- package/dist/stats/index.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -652,7 +652,7 @@ function isCategoricalField(data, field) {
|
|
|
652
652
|
for (const row of data) {
|
|
653
653
|
const value = row[field];
|
|
654
654
|
if (value !== null && value !== undefined) {
|
|
655
|
-
if (typeof value === "string"
|
|
655
|
+
if (typeof value === "string") {
|
|
656
656
|
return true;
|
|
657
657
|
}
|
|
658
658
|
}
|
|
@@ -1049,6 +1049,44 @@ function getPointColor(row, aes, colorScale) {
|
|
|
1049
1049
|
}
|
|
1050
1050
|
return DEFAULT_POINT_COLOR;
|
|
1051
1051
|
}
|
|
1052
|
+
function parseColorToRgba(color, fallback = { r: 128, g: 128, b: 128, a: 1 }) {
|
|
1053
|
+
if (!color)
|
|
1054
|
+
return fallback;
|
|
1055
|
+
if (typeof color === "object" && color !== null && "r" in color) {
|
|
1056
|
+
return color;
|
|
1057
|
+
}
|
|
1058
|
+
if (typeof color === "string") {
|
|
1059
|
+
if (color.startsWith("#")) {
|
|
1060
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
|
|
1061
|
+
if (result) {
|
|
1062
|
+
return {
|
|
1063
|
+
r: parseInt(result[1], 16),
|
|
1064
|
+
g: parseInt(result[2], 16),
|
|
1065
|
+
b: parseInt(result[3], 16),
|
|
1066
|
+
a: 1
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
const namedColors = {
|
|
1071
|
+
red: { r: 255, g: 0, b: 0, a: 1 },
|
|
1072
|
+
blue: { r: 0, g: 0, b: 255, a: 1 },
|
|
1073
|
+
green: { r: 0, g: 128, b: 0, a: 1 },
|
|
1074
|
+
black: { r: 0, g: 0, b: 0, a: 1 },
|
|
1075
|
+
white: { r: 255, g: 255, b: 255, a: 1 },
|
|
1076
|
+
gray: { r: 128, g: 128, b: 128, a: 1 },
|
|
1077
|
+
grey: { r: 128, g: 128, b: 128, a: 1 },
|
|
1078
|
+
yellow: { r: 255, g: 255, b: 0, a: 1 },
|
|
1079
|
+
orange: { r: 255, g: 165, b: 0, a: 1 },
|
|
1080
|
+
purple: { r: 128, g: 0, b: 128, a: 1 },
|
|
1081
|
+
cyan: { r: 0, g: 255, b: 255, a: 1 },
|
|
1082
|
+
magenta: { r: 255, g: 0, b: 255, a: 1 }
|
|
1083
|
+
};
|
|
1084
|
+
const named = namedColors[color.toLowerCase()];
|
|
1085
|
+
if (named)
|
|
1086
|
+
return named;
|
|
1087
|
+
}
|
|
1088
|
+
return fallback;
|
|
1089
|
+
}
|
|
1052
1090
|
function renderGeomPoint(data, geom, aes, scales, canvas) {
|
|
1053
1091
|
const defaultShape = getPointShape(geom.params.shape);
|
|
1054
1092
|
const positionType = getPositionType(geom.position);
|
|
@@ -1447,7 +1485,7 @@ function renderGeomHLine(_data, geom, _aes, scales, canvas) {
|
|
|
1447
1485
|
if (yintercept === undefined)
|
|
1448
1486
|
return;
|
|
1449
1487
|
const cy = Math.round(scales.y.map(yintercept));
|
|
1450
|
-
const color = geom.params.color
|
|
1488
|
+
const color = parseColorToRgba(geom.params.color);
|
|
1451
1489
|
const startX = Math.round(scales.x.range[0]);
|
|
1452
1490
|
const endX = Math.round(scales.x.range[1]);
|
|
1453
1491
|
canvas.drawHLine(startX, cy, endX - startX + 1, "─", color);
|
|
@@ -1457,7 +1495,7 @@ function renderGeomVLine(_data, geom, _aes, scales, canvas) {
|
|
|
1457
1495
|
if (xintercept === undefined)
|
|
1458
1496
|
return;
|
|
1459
1497
|
const cx = Math.round(scales.x.map(xintercept));
|
|
1460
|
-
const color = geom.params.color
|
|
1498
|
+
const color = parseColorToRgba(geom.params.color);
|
|
1461
1499
|
const startY = Math.round(Math.min(scales.y.range[0], scales.y.range[1]));
|
|
1462
1500
|
const endY = Math.round(Math.max(scales.y.range[0], scales.y.range[1]));
|
|
1463
1501
|
canvas.drawVLine(cx, startY, endY - startY + 1, "│", color);
|
|
@@ -1768,6 +1806,120 @@ function renderGeomViolin(data, geom, _aes, scales, canvas) {
|
|
|
1768
1806
|
}
|
|
1769
1807
|
}
|
|
1770
1808
|
}
|
|
1809
|
+
function renderGeomRidgeline(data, geom, aes, scales, canvas) {
|
|
1810
|
+
const scaleFactor = geom.params.scale ?? 0.9;
|
|
1811
|
+
const alpha = geom.params.alpha ?? 0.8;
|
|
1812
|
+
const showOutline = geom.params.outline ?? true;
|
|
1813
|
+
const fixedFill = geom.params.fill;
|
|
1814
|
+
const fixedColor = geom.params.color;
|
|
1815
|
+
const plotLeft = Math.round(scales.x.range[0]);
|
|
1816
|
+
const plotRight = Math.round(scales.x.range[1]);
|
|
1817
|
+
const plotTop = Math.round(Math.min(scales.y.range[0], scales.y.range[1]));
|
|
1818
|
+
const plotBottom = Math.round(Math.max(scales.y.range[0], scales.y.range[1]));
|
|
1819
|
+
const groups = new Map;
|
|
1820
|
+
const groupKeys = [];
|
|
1821
|
+
for (const row of data) {
|
|
1822
|
+
const key = String(row.y ?? "default");
|
|
1823
|
+
if (!groups.has(key)) {
|
|
1824
|
+
groups.set(key, { data: [], index: Number(row.yIndex) ?? groupKeys.length });
|
|
1825
|
+
groupKeys.push(key);
|
|
1826
|
+
}
|
|
1827
|
+
groups.get(key).data.push(row);
|
|
1828
|
+
}
|
|
1829
|
+
const numGroups = groupKeys.length;
|
|
1830
|
+
if (numGroups === 0)
|
|
1831
|
+
return;
|
|
1832
|
+
const plotHeight = Math.abs(plotBottom - plotTop);
|
|
1833
|
+
const ridgeBaseHeight = plotHeight / numGroups;
|
|
1834
|
+
const defaultColors = [
|
|
1835
|
+
{ r: 79, g: 169, b: 238, a: 1 },
|
|
1836
|
+
{ r: 238, g: 136, b: 102, a: 1 },
|
|
1837
|
+
{ r: 102, g: 204, b: 153, a: 1 },
|
|
1838
|
+
{ r: 204, g: 102, b: 204, a: 1 },
|
|
1839
|
+
{ r: 255, g: 200, b: 87, a: 1 },
|
|
1840
|
+
{ r: 138, g: 201, b: 222, a: 1 },
|
|
1841
|
+
{ r: 255, g: 153, b: 153, a: 1 },
|
|
1842
|
+
{ r: 170, g: 170, b: 170, a: 1 }
|
|
1843
|
+
];
|
|
1844
|
+
let parsedFillColor = null;
|
|
1845
|
+
if (fixedFill) {
|
|
1846
|
+
parsedFillColor = parseColorToRgba(fixedFill);
|
|
1847
|
+
}
|
|
1848
|
+
const sortedKeys = [...groupKeys].sort((a, b) => {
|
|
1849
|
+
const idxA = groups.get(a)?.index ?? 0;
|
|
1850
|
+
const idxB = groups.get(b)?.index ?? 0;
|
|
1851
|
+
return idxB - idxA;
|
|
1852
|
+
});
|
|
1853
|
+
for (const groupKey of sortedKeys) {
|
|
1854
|
+
const group = groups.get(groupKey);
|
|
1855
|
+
if (!group)
|
|
1856
|
+
continue;
|
|
1857
|
+
const groupIndex = group.index;
|
|
1858
|
+
const groupData = group.data;
|
|
1859
|
+
const sorted = [...groupData].sort((a, b) => {
|
|
1860
|
+
const ax = Number(a.x) || 0;
|
|
1861
|
+
const bx = Number(b.x) || 0;
|
|
1862
|
+
return ax - bx;
|
|
1863
|
+
});
|
|
1864
|
+
if (sorted.length < 2)
|
|
1865
|
+
continue;
|
|
1866
|
+
const baseline = plotTop + (groupIndex + 0.5) * ridgeBaseHeight;
|
|
1867
|
+
let fillColor;
|
|
1868
|
+
if (parsedFillColor) {
|
|
1869
|
+
fillColor = parsedFillColor;
|
|
1870
|
+
} else if ((aes.fill || aes.color) && scales.color) {
|
|
1871
|
+
const mappedColor = scales.color.map(groupKey);
|
|
1872
|
+
if (typeof mappedColor === "object" && "r" in mappedColor) {
|
|
1873
|
+
fillColor = mappedColor;
|
|
1874
|
+
} else {
|
|
1875
|
+
fillColor = defaultColors[groupIndex % defaultColors.length];
|
|
1876
|
+
}
|
|
1877
|
+
} else {
|
|
1878
|
+
fillColor = defaultColors[groupIndex % defaultColors.length];
|
|
1879
|
+
}
|
|
1880
|
+
const alphaFillColor = {
|
|
1881
|
+
r: Math.round(fillColor.r * alpha + 255 * (1 - alpha) * 0.1),
|
|
1882
|
+
g: Math.round(fillColor.g * alpha + 255 * (1 - alpha) * 0.1),
|
|
1883
|
+
b: Math.round(fillColor.b * alpha + 255 * (1 - alpha) * 0.1),
|
|
1884
|
+
a: 1
|
|
1885
|
+
};
|
|
1886
|
+
const maxRidgeHeight = ridgeBaseHeight * scaleFactor * 1.5;
|
|
1887
|
+
const outlinePoints = [];
|
|
1888
|
+
for (const row of sorted) {
|
|
1889
|
+
const xVal = Number(row.x);
|
|
1890
|
+
const scaled = Number(row.scaled) || 0;
|
|
1891
|
+
const px = Math.round(scales.x.map(xVal));
|
|
1892
|
+
const ridgeHeight = scaled * maxRidgeHeight;
|
|
1893
|
+
const py = Math.round(baseline - ridgeHeight);
|
|
1894
|
+
if (px < plotLeft || px > plotRight)
|
|
1895
|
+
continue;
|
|
1896
|
+
const fillTop = Math.max(plotTop, py);
|
|
1897
|
+
const fillBottom = Math.min(plotBottom, Math.round(baseline));
|
|
1898
|
+
for (let y = fillTop;y <= fillBottom; y++) {
|
|
1899
|
+
canvas.drawChar(px, y, "█", alphaFillColor);
|
|
1900
|
+
}
|
|
1901
|
+
if (showOutline) {
|
|
1902
|
+
outlinePoints.push({ x: px, y: Math.max(plotTop, py) });
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
if (showOutline && outlinePoints.length > 1) {
|
|
1906
|
+
const outlineColor = fixedColor ? parseColorToRgba(fixedColor) : { r: Math.min(255, fillColor.r + 40), g: Math.min(255, fillColor.g + 40), b: Math.min(255, fillColor.b + 40), a: 1 };
|
|
1907
|
+
for (let i = 0;i < outlinePoints.length - 1; i++) {
|
|
1908
|
+
const p1 = outlinePoints[i];
|
|
1909
|
+
const p2 = outlinePoints[i + 1];
|
|
1910
|
+
if (Math.abs(p2.x - p1.x) <= 1) {
|
|
1911
|
+
if (p1.y >= plotTop && p1.y <= plotBottom) {
|
|
1912
|
+
canvas.drawChar(p1.x, p1.y, "▄", outlineColor);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
const last = outlinePoints[outlinePoints.length - 1];
|
|
1917
|
+
if (last.y >= plotTop && last.y <= plotBottom) {
|
|
1918
|
+
canvas.drawChar(last.x, last.y, "▄", outlineColor);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1771
1923
|
function renderGeomTile(data, geom, aes, scales, canvas) {
|
|
1772
1924
|
const alpha = geom.params.alpha ?? 1;
|
|
1773
1925
|
const plotLeft = Math.round(scales.x.range[0]);
|
|
@@ -2016,7 +2168,7 @@ function renderGeomAbline(_data, geom, _aes, scales, canvas) {
|
|
|
2016
2168
|
const intercept = geom.params.intercept ?? 0;
|
|
2017
2169
|
const linetype = geom.params.linetype ?? "solid";
|
|
2018
2170
|
const lineChar = linetype === "dotted" ? "·" : linetype === "dashed" ? "╌" : "─";
|
|
2019
|
-
const color = geom.params.color
|
|
2171
|
+
const color = parseColorToRgba(geom.params.color);
|
|
2020
2172
|
const plotLeft = Math.round(scales.x.range[0]);
|
|
2021
2173
|
const plotRight = Math.round(scales.x.range[1]);
|
|
2022
2174
|
const plotTop = Math.round(Math.min(scales.y.range[0], scales.y.range[1]));
|
|
@@ -2206,6 +2358,10 @@ function renderGeom(data, geom, aes, scales, canvas, coordType) {
|
|
|
2206
2358
|
case "violin":
|
|
2207
2359
|
renderGeomViolin(data, geom, aes, scales, canvas);
|
|
2208
2360
|
break;
|
|
2361
|
+
case "ridgeline":
|
|
2362
|
+
case "joy":
|
|
2363
|
+
renderGeomRidgeline(data, geom, aes, scales, canvas);
|
|
2364
|
+
break;
|
|
2209
2365
|
case "tile":
|
|
2210
2366
|
case "raster":
|
|
2211
2367
|
case "bin2d":
|
|
@@ -3314,6 +3470,52 @@ function stat_ydensity(params = {}) {
|
|
|
3314
3470
|
}
|
|
3315
3471
|
};
|
|
3316
3472
|
}
|
|
3473
|
+
function stat_xdensity(params = {}) {
|
|
3474
|
+
return {
|
|
3475
|
+
type: "xdensity",
|
|
3476
|
+
compute(data, aes) {
|
|
3477
|
+
const groups = new Map;
|
|
3478
|
+
const groupOrder = [];
|
|
3479
|
+
for (const row of data) {
|
|
3480
|
+
const groupKey = String(row[aes.y] ?? "default");
|
|
3481
|
+
const xVal = row[aes.x];
|
|
3482
|
+
if (xVal === null || xVal === undefined)
|
|
3483
|
+
continue;
|
|
3484
|
+
const numX = Number(xVal);
|
|
3485
|
+
if (isNaN(numX))
|
|
3486
|
+
continue;
|
|
3487
|
+
if (!groups.has(groupKey)) {
|
|
3488
|
+
groups.set(groupKey, []);
|
|
3489
|
+
groupOrder.push(groupKey);
|
|
3490
|
+
}
|
|
3491
|
+
groups.get(groupKey).push(numX);
|
|
3492
|
+
}
|
|
3493
|
+
const result = [];
|
|
3494
|
+
let groupIndex = 0;
|
|
3495
|
+
for (const groupKey of groupOrder) {
|
|
3496
|
+
const xValues = groups.get(groupKey);
|
|
3497
|
+
if (xValues.length < 2) {
|
|
3498
|
+
groupIndex++;
|
|
3499
|
+
continue;
|
|
3500
|
+
}
|
|
3501
|
+
const tempData = xValues.map((v) => ({ x: v }));
|
|
3502
|
+
const densityResult = computeDensity(tempData, "x", params);
|
|
3503
|
+
for (const d of densityResult) {
|
|
3504
|
+
result.push({
|
|
3505
|
+
x: d.x,
|
|
3506
|
+
y: groupKey,
|
|
3507
|
+
yIndex: groupIndex,
|
|
3508
|
+
density: d.density,
|
|
3509
|
+
scaled: d.scaled,
|
|
3510
|
+
height: d.scaled
|
|
3511
|
+
});
|
|
3512
|
+
}
|
|
3513
|
+
groupIndex++;
|
|
3514
|
+
}
|
|
3515
|
+
return result;
|
|
3516
|
+
}
|
|
3517
|
+
};
|
|
3518
|
+
}
|
|
3317
3519
|
|
|
3318
3520
|
// src/stats/smooth.ts
|
|
3319
3521
|
function linearRegression(xs, ys) {
|
|
@@ -3791,6 +3993,124 @@ function stat_qq_line(params = {}) {
|
|
|
3791
3993
|
};
|
|
3792
3994
|
}
|
|
3793
3995
|
|
|
3996
|
+
// src/stats/density2d.ts
|
|
3997
|
+
function gaussian2d(dx, dy, hx, hy) {
|
|
3998
|
+
const ux = dx / hx;
|
|
3999
|
+
const uy = dy / hy;
|
|
4000
|
+
return Math.exp(-0.5 * (ux * ux + uy * uy)) / (2 * Math.PI * hx * hy);
|
|
4001
|
+
}
|
|
4002
|
+
function scottBandwidth2d(values) {
|
|
4003
|
+
const n = values.length;
|
|
4004
|
+
if (n < 2)
|
|
4005
|
+
return 1;
|
|
4006
|
+
const mean = values.reduce((a, b) => a + b, 0) / n;
|
|
4007
|
+
const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / (n - 1);
|
|
4008
|
+
const std = Math.sqrt(variance);
|
|
4009
|
+
return std * Math.pow(n, -1 / 6);
|
|
4010
|
+
}
|
|
4011
|
+
function computeDensity2d(data, xField, yField, params = {}) {
|
|
4012
|
+
const points = [];
|
|
4013
|
+
const xValues = [];
|
|
4014
|
+
const yValues = [];
|
|
4015
|
+
for (const row of data) {
|
|
4016
|
+
const xVal = row[xField];
|
|
4017
|
+
const yVal = row[yField];
|
|
4018
|
+
if (xVal === null || xVal === undefined || yVal === null || yVal === undefined)
|
|
4019
|
+
continue;
|
|
4020
|
+
const x = Number(xVal);
|
|
4021
|
+
const y = Number(yVal);
|
|
4022
|
+
if (isNaN(x) || isNaN(y))
|
|
4023
|
+
continue;
|
|
4024
|
+
points.push({ x, y });
|
|
4025
|
+
xValues.push(x);
|
|
4026
|
+
yValues.push(y);
|
|
4027
|
+
}
|
|
4028
|
+
if (points.length < 3) {
|
|
4029
|
+
return [];
|
|
4030
|
+
}
|
|
4031
|
+
const n = params.n ?? 50;
|
|
4032
|
+
const nx = params.nx ?? n;
|
|
4033
|
+
const ny = params.ny ?? n;
|
|
4034
|
+
const adjust = params.adjust ?? 1;
|
|
4035
|
+
let hx, hy;
|
|
4036
|
+
if (Array.isArray(params.h)) {
|
|
4037
|
+
hx = params.h[0] * adjust;
|
|
4038
|
+
hy = params.h[1] * adjust;
|
|
4039
|
+
} else if (params.h !== undefined) {
|
|
4040
|
+
hx = params.h * adjust;
|
|
4041
|
+
hy = params.h * adjust;
|
|
4042
|
+
} else {
|
|
4043
|
+
hx = scottBandwidth2d(xValues) * adjust;
|
|
4044
|
+
hy = scottBandwidth2d(yValues) * adjust;
|
|
4045
|
+
}
|
|
4046
|
+
if (hx <= 0)
|
|
4047
|
+
hx = 1;
|
|
4048
|
+
if (hy <= 0)
|
|
4049
|
+
hy = 1;
|
|
4050
|
+
const xMin = Math.min(...xValues);
|
|
4051
|
+
const xMax = Math.max(...xValues);
|
|
4052
|
+
const yMin = Math.min(...yValues);
|
|
4053
|
+
const yMax = Math.max(...yValues);
|
|
4054
|
+
const xPad = 3 * hx;
|
|
4055
|
+
const yPad = 3 * hy;
|
|
4056
|
+
const gridXMin = xMin - xPad;
|
|
4057
|
+
const gridXMax = xMax + xPad;
|
|
4058
|
+
const gridYMin = yMin - yPad;
|
|
4059
|
+
const gridYMax = yMax + yPad;
|
|
4060
|
+
const xStep = (gridXMax - gridXMin) / (nx - 1);
|
|
4061
|
+
const yStep = (gridYMax - gridYMin) / (ny - 1);
|
|
4062
|
+
const results = [];
|
|
4063
|
+
const nPoints = points.length;
|
|
4064
|
+
for (let i = 0;i < nx; i++) {
|
|
4065
|
+
const gx = gridXMin + i * xStep;
|
|
4066
|
+
for (let j = 0;j < ny; j++) {
|
|
4067
|
+
const gy = gridYMin + j * yStep;
|
|
4068
|
+
let density = 0;
|
|
4069
|
+
for (const pt of points) {
|
|
4070
|
+
density += gaussian2d(gx - pt.x, gy - pt.y, hx, hy);
|
|
4071
|
+
}
|
|
4072
|
+
density /= nPoints;
|
|
4073
|
+
results.push({
|
|
4074
|
+
x: gx,
|
|
4075
|
+
y: gy,
|
|
4076
|
+
z: density,
|
|
4077
|
+
density,
|
|
4078
|
+
level: density
|
|
4079
|
+
});
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4082
|
+
return results;
|
|
4083
|
+
}
|
|
4084
|
+
function stat_density_2d(params = {}) {
|
|
4085
|
+
return {
|
|
4086
|
+
type: "density_2d",
|
|
4087
|
+
compute(data, aes) {
|
|
4088
|
+
if (aes.color) {
|
|
4089
|
+
const groups = new Map;
|
|
4090
|
+
for (const row of data) {
|
|
4091
|
+
const group = String(row[aes.color] ?? "default");
|
|
4092
|
+
if (!groups.has(group)) {
|
|
4093
|
+
groups.set(group, []);
|
|
4094
|
+
}
|
|
4095
|
+
groups.get(group).push(row);
|
|
4096
|
+
}
|
|
4097
|
+
const result = [];
|
|
4098
|
+
for (const [group, groupData] of groups) {
|
|
4099
|
+
const density = computeDensity2d(groupData, aes.x, aes.y, params);
|
|
4100
|
+
for (const d of density) {
|
|
4101
|
+
result.push({
|
|
4102
|
+
...d,
|
|
4103
|
+
[aes.color]: group
|
|
4104
|
+
});
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
return result;
|
|
4108
|
+
}
|
|
4109
|
+
return computeDensity2d(data, aes.x, aes.y, params);
|
|
4110
|
+
}
|
|
4111
|
+
};
|
|
4112
|
+
}
|
|
4113
|
+
|
|
3794
4114
|
// src/facets/index.ts
|
|
3795
4115
|
function as_labeller(labels) {
|
|
3796
4116
|
return (value) => labels[value] ?? value;
|
|
@@ -4068,6 +4388,14 @@ function applyStatTransform(data, geom, aes) {
|
|
|
4068
4388
|
adjust: geom.params.adjust
|
|
4069
4389
|
});
|
|
4070
4390
|
return ydensityStat.compute(data, aes);
|
|
4391
|
+
} else if (geom.stat === "xdensity") {
|
|
4392
|
+
const xdensityStat = stat_xdensity({
|
|
4393
|
+
bw: geom.params.bw,
|
|
4394
|
+
kernel: geom.params.kernel,
|
|
4395
|
+
n: geom.params.n,
|
|
4396
|
+
adjust: geom.params.adjust
|
|
4397
|
+
});
|
|
4398
|
+
return xdensityStat.compute(data, aes);
|
|
4071
4399
|
} else if (geom.stat === "smooth") {
|
|
4072
4400
|
const smoothStat = stat_smooth({
|
|
4073
4401
|
method: geom.params.method,
|
|
@@ -4109,6 +4437,15 @@ function applyStatTransform(data, geom, aes) {
|
|
|
4109
4437
|
drop: geom.params.drop
|
|
4110
4438
|
});
|
|
4111
4439
|
return bin2dStat.compute(data, aes);
|
|
4440
|
+
} else if (geom.stat === "density_2d") {
|
|
4441
|
+
const density2dStat = stat_density_2d({
|
|
4442
|
+
h: geom.params.bandwidth,
|
|
4443
|
+
n: geom.params.n,
|
|
4444
|
+
nx: geom.params.nx,
|
|
4445
|
+
ny: geom.params.ny,
|
|
4446
|
+
adjust: geom.params.adjust
|
|
4447
|
+
});
|
|
4448
|
+
return density2dStat.compute(data, aes);
|
|
4112
4449
|
}
|
|
4113
4450
|
return data;
|
|
4114
4451
|
}
|
|
@@ -4177,6 +4514,14 @@ function renderToCanvas(spec, options) {
|
|
|
4177
4514
|
scaleData = applyStatTransform(spec.data, geom, spec.aes);
|
|
4178
4515
|
scaleAes = { ...spec.aes, x: "x", y: "y", fill: "fill" };
|
|
4179
4516
|
break;
|
|
4517
|
+
} else if (geom.stat === "density_2d") {
|
|
4518
|
+
scaleData = applyStatTransform(spec.data, geom, spec.aes);
|
|
4519
|
+
scaleAes = { ...spec.aes, x: "x", y: "y" };
|
|
4520
|
+
break;
|
|
4521
|
+
} else if (geom.stat === "xdensity") {
|
|
4522
|
+
scaleData = applyStatTransform(spec.data, geom, spec.aes);
|
|
4523
|
+
scaleAes = { ...spec.aes, x: "x", y: "y" };
|
|
4524
|
+
break;
|
|
4180
4525
|
}
|
|
4181
4526
|
}
|
|
4182
4527
|
scaleData = applyCoordTransform(scaleData, scaleAes, spec.coord);
|
|
@@ -4213,6 +4558,10 @@ function renderToCanvas(spec, options) {
|
|
|
4213
4558
|
geomAes = { ...spec.aes, x: "x", y: "y", xend: "xend", yend: "yend" };
|
|
4214
4559
|
} else if (geom.stat === "bin2d") {
|
|
4215
4560
|
geomAes = { ...spec.aes, x: "x", y: "y", fill: "fill" };
|
|
4561
|
+
} else if (geom.stat === "density_2d") {
|
|
4562
|
+
geomAes = { ...spec.aes, x: "x", y: "y" };
|
|
4563
|
+
} else if (geom.stat === "xdensity") {
|
|
4564
|
+
geomAes = { ...spec.aes, x: "x", y: "y" };
|
|
4216
4565
|
}
|
|
4217
4566
|
geomData = applyCoordTransform(geomData, geomAes, spec.coord);
|
|
4218
4567
|
}
|
|
@@ -5130,8 +5479,32 @@ function geom_qq_line(options = {}) {
|
|
|
5130
5479
|
};
|
|
5131
5480
|
}
|
|
5132
5481
|
|
|
5482
|
+
// src/geoms/ridgeline.ts
|
|
5483
|
+
function geom_ridgeline(options = {}) {
|
|
5484
|
+
return {
|
|
5485
|
+
type: "ridgeline",
|
|
5486
|
+
stat: "xdensity",
|
|
5487
|
+
position: "identity",
|
|
5488
|
+
params: {
|
|
5489
|
+
scale: options.scale ?? 0.9,
|
|
5490
|
+
alpha: options.alpha ?? 0.8,
|
|
5491
|
+
fill: options.fill,
|
|
5492
|
+
color: options.color,
|
|
5493
|
+
adjust: options.adjust ?? 1,
|
|
5494
|
+
n: options.n ?? 128,
|
|
5495
|
+
outline: options.outline ?? true
|
|
5496
|
+
}
|
|
5497
|
+
};
|
|
5498
|
+
}
|
|
5499
|
+
var geom_joy;
|
|
5500
|
+
var init_ridgeline = __esm(() => {
|
|
5501
|
+
geom_joy = geom_ridgeline;
|
|
5502
|
+
});
|
|
5503
|
+
|
|
5133
5504
|
// src/geoms/index.ts
|
|
5134
|
-
var init_geoms = () => {
|
|
5505
|
+
var init_geoms = __esm(() => {
|
|
5506
|
+
init_ridgeline();
|
|
5507
|
+
});
|
|
5135
5508
|
|
|
5136
5509
|
// src/scales/continuous.ts
|
|
5137
5510
|
function createContinuousScale(aesthetic, options = {}) {
|
package/dist/geoms/index.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ export { geom_contour, geom_contour_filled, geom_density_2d, type ContourOptions
|
|
|
20
20
|
export { geom_errorbar, geom_errorbarh, geom_crossbar, geom_linerange, geom_pointrange, type ErrorbarOptions, } from './errorbar';
|
|
21
21
|
export { geom_rect, geom_abline, type RectOptions, type AblineOptions } from './rect';
|
|
22
22
|
export { geom_qq, geom_qq_line, type QQOptions, type QQLineOptions } from './qq';
|
|
23
|
+
export { geom_ridgeline, geom_joy, type RidgelineOptions } from './ridgeline';
|
|
23
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/geoms/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AACxG,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACzE,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAGjD,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACnG,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAA;AACrF,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/geoms/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AACxG,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACzE,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAA;AAGjD,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACnG,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,KAAK,eAAe,GACrB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAA;AACrF,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* geom_ridgeline - Ridgeline plot geometry (joy plots)
|
|
3
|
+
*
|
|
4
|
+
* Creates stacked density plots for comparing distributions across groups.
|
|
5
|
+
* Each group gets a ridge that can overlap with neighbors for a compact view.
|
|
6
|
+
*/
|
|
7
|
+
import type { Geom } from '../types';
|
|
8
|
+
export interface RidgelineOptions {
|
|
9
|
+
/** Height scale for ridges (default: 0.9, higher = more overlap) */
|
|
10
|
+
scale?: number;
|
|
11
|
+
/** Alpha transparency (default: 0.8) */
|
|
12
|
+
alpha?: number;
|
|
13
|
+
/** Fill color */
|
|
14
|
+
fill?: string;
|
|
15
|
+
/** Border/outline color */
|
|
16
|
+
color?: string;
|
|
17
|
+
/** Bandwidth adjustment factor for density (default: 1) */
|
|
18
|
+
adjust?: number;
|
|
19
|
+
/** Number of points for density estimation (default: 128) */
|
|
20
|
+
n?: number;
|
|
21
|
+
/** Whether to show ridge outlines (default: true) */
|
|
22
|
+
outline?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Render ridgeline plot (joy plot)
|
|
26
|
+
*
|
|
27
|
+
* Ridgeline plots show the distribution of a numeric variable (x)
|
|
28
|
+
* for several groups (y). Each group is displayed as a density curve,
|
|
29
|
+
* stacked vertically with optional overlap.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* import { gg, geom_ridgeline } from '@ggterm/core'
|
|
34
|
+
*
|
|
35
|
+
* // Basic ridgeline plot
|
|
36
|
+
* gg(data)
|
|
37
|
+
* .aes({ x: 'value', y: 'month' })
|
|
38
|
+
* .geom(geom_ridgeline())
|
|
39
|
+
*
|
|
40
|
+
* // With custom scale (more overlap)
|
|
41
|
+
* gg(data)
|
|
42
|
+
* .aes({ x: 'temperature', y: 'city', fill: 'city' })
|
|
43
|
+
* .geom(geom_ridgeline({ scale: 1.5, alpha: 0.7 }))
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function geom_ridgeline(options?: RidgelineOptions): Geom;
|
|
47
|
+
/**
|
|
48
|
+
* Alias for geom_ridgeline
|
|
49
|
+
* Named after the Joy Division album cover that popularized this visualization
|
|
50
|
+
*/
|
|
51
|
+
export declare const geom_joy: typeof geom_ridgeline;
|
|
52
|
+
//# sourceMappingURL=ridgeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ridgeline.d.ts","sourceRoot":"","sources":["../../src/geoms/ridgeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAEpC,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iBAAiB;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,gBAAqB,GAAG,IAAI,CAenE;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,uBAAiB,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export type { AestheticMapping, Canvas, CanvasCell, ComputedPoint, Coord, DataRe
|
|
|
9
9
|
export { TerminalCanvas, createCanvas, DEFAULT_FG, DEFAULT_BG } from './canvas';
|
|
10
10
|
export { renderToCanvas, renderToString, calculateLayout, buildScaleContext, inferContinuousDomain, inferDiscreteDomain, } from './pipeline';
|
|
11
11
|
export type { PlotLayout, ResolvedScale, ScaleContext } from './pipeline';
|
|
12
|
-
export { geom_point, geom_line, geom_path, geom_hline, geom_vline, geom_bar, geom_col, geom_text, geom_label, geom_area, geom_ribbon, geom_histogram, geom_boxplot, geom_segment, geom_curve, geom_smooth, geom_step, geom_rug, geom_violin, geom_tile, geom_raster, geom_bin2d, geom_contour, geom_contour_filled, geom_density_2d, geom_errorbar, geom_errorbarh, geom_crossbar, geom_linerange, geom_pointrange, geom_rect, geom_abline, geom_qq, geom_qq_line, geom_freqpoly, } from './geoms';
|
|
13
|
-
export type { PathOptions, RugOptions, SmoothOptions, StepOptions, ViolinOptions, TileOptions, Bin2dOptions, ContourOptions, ErrorbarOptions, RectOptions, AblineOptions, QQOptions, QQLineOptions, FreqpolyOptions, } from './geoms';
|
|
12
|
+
export { geom_point, geom_line, geom_path, geom_hline, geom_vline, geom_bar, geom_col, geom_text, geom_label, geom_area, geom_ribbon, geom_histogram, geom_boxplot, geom_segment, geom_curve, geom_smooth, geom_step, geom_rug, geom_violin, geom_tile, geom_raster, geom_bin2d, geom_contour, geom_contour_filled, geom_density_2d, geom_errorbar, geom_errorbarh, geom_crossbar, geom_linerange, geom_pointrange, geom_rect, geom_abline, geom_qq, geom_qq_line, geom_freqpoly, geom_ridgeline, geom_joy, } from './geoms';
|
|
13
|
+
export type { PathOptions, RugOptions, SmoothOptions, StepOptions, ViolinOptions, TileOptions, Bin2dOptions, ContourOptions, ErrorbarOptions, RectOptions, AblineOptions, QQOptions, QQLineOptions, FreqpolyOptions, RidgelineOptions, } from './geoms';
|
|
14
14
|
export { position_identity, position_dodge, position_stack, position_fill, position_jitter, applyPositionAdjustment, isStackPosition, isDodgePosition, getPositionType, } from './positions';
|
|
15
15
|
export type { Position, AdjustedPoint, DodgeOptions, JitterOptions, StackOptions, FillOptions, } from './positions';
|
|
16
16
|
export { stat_bin, stat_bin2d, stat_boxplot, stat_density, stat_smooth, stat_summary, stat_qq, stat_qq_line, computeBins, computeBins2d, computeBoxplotStats, computeDensity, computeSmooth, computeSummary, computeQQ, computeQQLine, } from './stats';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAGtC,YAAY,EACV,gBAAgB,EAChB,MAAM,EACN,UAAU,EACV,aAAa,EACb,KAAK,EACL,UAAU,EACV,UAAU,EACV,MAAM,EACN,KAAK,EACL,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,aAAa,EACb,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,KAAK,GACN,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG/E,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGzE,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,EACT,QAAQ,EAER,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,SAAS,EACT,WAAW,EAEX,OAAO,EACP,YAAY,EAEZ,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|