Comparing version 1.0.0-alpha.12.0 to 1.0.0-alpha.13.0
{ | ||
"name": "binguru", | ||
"version": "1.0.0-alpha.12.0", | ||
"version": "1.0.0-alpha.13.0", | ||
"description": "BinGuru is a Javascript package with an API to several established data binning / data classification methods, often used for visualizing data on choropleth maps. It also includes an implementation of a new, consensus binning method, 'Resiliency'.", | ||
@@ -22,8 +22,8 @@ "main": "dist/index.mjs", | ||
"data", | ||
"classification;", | ||
"choropleth;", | ||
"maps;", | ||
"GIS;", | ||
"cartography;", | ||
"visualization;" | ||
"classification", | ||
"choropleth", | ||
"maps", | ||
"GIS", | ||
"cartography", | ||
"visualization" | ||
], | ||
@@ -30,0 +30,0 @@ "author": "Arpit Narechania, Alex Endert, Clio Andris", |
@@ -25,27 +25,19 @@ # BinGuru | ||
### API | ||
Coming soon. | ||
### API and Demo | ||
Check out this <a target="_blank" href="https://observablehq.com/@arpitnarechania/binguru-demo">Observable Notebook</a>. | ||
### Demos | ||
Coming soon. | ||
### Build and Publish | ||
- Install dependencies: `npm install` | ||
- Build the package: `npm run build` | ||
- Set version: `npm version prerelease --preid=<version>` | ||
- Dry run: `npm publish --dry-run` | ||
- Publish to the registry: `npm publish` | ||
### Test | ||
Coming soon. | ||
### Credits | ||
BinGuru was created by | ||
<a target="_blank" href="http://narechania.com">Arpit Narechania</a>, <a href="https://va.gatech.edu/endert/">Alex Endert</a>, and <a href="https://friendlycities.gatech.edu/">Clio Andris</a> of the <a target="_blank" href="http://vis.gatech.edu/">Georgia Tech Visualization Lab.</a> | ||
<a target="_blank" href="http://narechania.com">Arpit Narechania</a>, <a href="https://va.gatech.edu/endert/">Alex Endert</a>, and <a href="https://friendlycities.gatech.edu/">Clio Andris</a> of the <a target="_blank" href="https://vis.gatech.edu/">Georgia Tech Visualization Lab.</a> We thank the members of the <a target="_blank" href="http://vis.gatech.edu/">Georgia Tech Visualization Lab</a> for their support and constructive feedback.</p> | ||
We thank the members of the <a target="_blank" href="http://vis.gatech.edu/">Georgia Tech Visualization Lab</a> for their support and constructive feedback.</p> | ||
### Citations | ||
@@ -52,0 +44,0 @@ ```bibTeX |
100
src/index.ts
@@ -13,2 +13,3 @@ /*********************************************************** | ||
export const EQUAL_INTERVAL = "equalInterval"; | ||
@@ -365,3 +366,3 @@ export const PERCENTILE = "percentile"; | ||
*/ | ||
standardDeviation() { | ||
standardDeviation(meanAsBinBoundary=false, sdfactor=1) { | ||
let context = this; | ||
@@ -371,19 +372,17 @@ let binBreaks: number[] = []; | ||
// If there are even binCount | ||
let minStart = 0; | ||
let increment = 0; | ||
if (binCount % 2 == 0) { | ||
minStart = context.mean - (context.sd * (binCount / 2 - 1)); | ||
increment = context.sd; // 1 standard deviation | ||
} else { | ||
// minStart = mean - (sd * ((binCount - 1) / 2) / 2); | ||
// increment = sd / 2; // 0.5 standard deviation | ||
binCount++; | ||
minStart = context.mean - (context.sd * (binCount / 2 - 1)); | ||
increment = context.sd; // 1 standard deviation | ||
if(meanAsBinBoundary){ | ||
let minStart = context.mean - (context.sd * sdfactor * (Math.ceil(binCount / 2) - 1)); | ||
let increment = context.sd * sdfactor; | ||
for (let i = 0; i < (binCount - 1); i++) { | ||
let value = minStart + increment * i; | ||
binBreaks.push(value); | ||
} | ||
}else{ | ||
let minStart = context.mean - (context.sd * sdfactor * (Math.ceil(binCount / 2) - 1)) - context.sd * sdfactor / 2; | ||
let increment = context.sd * sdfactor; | ||
for (let i = 0; i < (binCount - 1); i++) { | ||
let value = minStart + increment * i; | ||
binBreaks.push(value); | ||
} | ||
} | ||
for (let i = 0; i < (binCount - 1); i++) { | ||
let value = minStart + increment * i; | ||
binBreaks.push(value); | ||
} | ||
@@ -413,8 +412,5 @@ // Compute Bin Sizes | ||
*/ | ||
manualInterval() { | ||
manualInterval(binBreaks = [1, 2, 3]) { | ||
let context = this; | ||
// let binBreaks = [context.mean - (context.mean - context.min) / 2, context.mean + (context.max - context.mean) / 2]; | ||
let binBreaks = [70, 80, 90]; | ||
// Compute Bin Sizes | ||
@@ -518,8 +514,14 @@ let binSizes = context.computeBinSizes(binBreaks); | ||
*/ | ||
definedInterval() { | ||
definedInterval(binExtent:number|any=null) { | ||
let context = this; | ||
let binBreaks: number[] = []; | ||
let binCount = 1; // binCount is hard-coded here. | ||
while (context.min + (context.binExtent * binCount) < context.max) { | ||
binBreaks.push(context.min + context.binExtent * binCount); | ||
// Use the default `this.binExtent` from the class variable (set in the constructor) unless local variable `binExtent` is supplied. | ||
if(binExtent == null){ | ||
binExtent = this.binExtent; | ||
} | ||
while (context.min + (binExtent * binCount) < context.max) { | ||
binBreaks.push(context.min + binExtent * binCount); | ||
binCount++; | ||
@@ -591,3 +593,3 @@ } | ||
*/ | ||
logarithmicInterval(logBase: number | string = 'auto') { | ||
logarithmicInterval() { | ||
let context = this; | ||
@@ -597,23 +599,17 @@ let binBreaks: number[] = []; | ||
// Calculate the logarithmic base | ||
if (logBase == "auto") { | ||
// Calculate the logarithmic base from the data extent and desired bin count | ||
logBase = Math.pow((context.max / context.min), (1 / context.binCount)); | ||
// Generate the bin boundaries using the logarithmic scale | ||
for (let i = 0; i < context.binCount; i++) { | ||
if (i != 0) binBreaks.push(binBreak); | ||
binBreak *= logBase; | ||
} | ||
} else { | ||
// Calculate the logarithmic interval size | ||
const logIntervalSize = (Math.log10(context.max) - Math.log10(context.min)) / context.binCount; | ||
for (let i = 0; i < context.binCount; i++) { | ||
if (i != 0) binBreaks.push(binBreak); | ||
binBreak *= Math.pow(10, logIntervalSize); | ||
} | ||
// Calculate the logarithmic interval size | ||
let max = context.max; | ||
let min = context.min; | ||
const epsilon = 1e-10; | ||
if(max == 0){ | ||
max = epsilon; | ||
} | ||
if(min == 0){ | ||
min = epsilon; | ||
} | ||
const logIntervalSize = (Math.log10(context.max) - Math.log10(context.min)) / context.binCount; | ||
for (let i = 0; i < context.binCount; i++) { | ||
if (i != 0) binBreaks.push(binBreak); | ||
binBreak *= Math.pow(10, logIntervalSize); | ||
} | ||
@@ -948,3 +944,2 @@ // Compute Bin Sizes | ||
* Resiliency | ||
* // TODO: When you switch to Population Density, the problem is that when all top Priority bins are chosen, there is NO bin in the 3rd or 4th bin; only 1 (3k+ points), 2 (1 point), and 5 (5 points) exist. How do we ensure that at least one point belongs to ALL bins to match the total number of bins requirement (and stay consistent that way). What could we do though? Should we move the boundary points of the neighbouring bins (e.g., end of 2 and beginning of 5) into these missing bins (3rd and 4th)? Maybe. OR when filling the binBreaks, take into consideration the corresponding priorityBin ID (i.e., 1, 2, or 5) and then choose the 3rd and 4th binBreaks by splitting the 2nd and 5th binBreaks. | ||
* @returns { binCount: number, binBreaks: number[], binSizes: object, dataRange: number[], dataBinAssignments: object } | ||
@@ -1273,5 +1268,9 @@ */ | ||
binMin = dataMin; | ||
} else if (binMin <= dataMin){ | ||
binMin = parseFloat((dataMin * 0.9).toFixed(context.precision)); // Heuristic just to go just beyond the dataMin | ||
} | ||
if (binMax < dataMax) { | ||
binMax = dataMax; | ||
}else if(binMax >= dataMax){ | ||
binMax = parseFloat((dataMax * 1.1).toFixed(context.precision)); // Heuristic just to go just beyond the dataMax | ||
} | ||
@@ -1348,3 +1347,3 @@ | ||
"encoding": { | ||
"x": { "field": "binMin", "type": "quantitative", "axis": { "title": null, "values": binBreaks, "format": ".2f", "labelFontSize": 16 }, "scale": { "domain": [binMin, binMax] } }, | ||
"x": { "field": "binMin", "type": "quantitative", "axis": { "title": null, "values": binBreaks, "format": `.${context.precision}f`, "labelFontSize": 16 }, "scale": { "domain": [binMin, binMax] } }, | ||
"y": { | ||
@@ -1361,3 +1360,3 @@ "field": "binningMethod", "type": "ordinal", "axis": { | ||
"field": "binMax", "scale": { "domain": [binMin, binMax] }, "axis": { | ||
"format": ".2f", | ||
"format": `.${context.precision}f`, | ||
"labelFontSize": 16 | ||
@@ -1409,5 +1408,5 @@ } | ||
"encoding": { | ||
"x": { "field": "binMin", "type": "quantitative", "axis": { "title": null, "values": binBreaks, "format": ".2f" }, "scale": { "domain": [binMin, binMax] } }, | ||
"x": { "field": "binMin", "type": "quantitative", "axis": { "title": null, "values": binBreaks, "format": `.${context.precision}f` }, "scale": { "domain": [binMin, binMax] } }, | ||
"y": { "field": "binningMethod", "type": "ordinal", "axis": { "title": null, "labelFontSize": 16, "labelLimit": 250, "labelPadding": 10 } }, | ||
"x2": { "field": "binMax", "scale": { "domain": [binMin, binMax] }, "axis": { "format": ".2f" } }, | ||
"x2": { "field": "binMax", "scale": { "domain": [binMin, binMax] }, "axis": { "format": `.${context.precision}f` } }, | ||
"size": { "value": 2 }, | ||
@@ -1437,2 +1436,3 @@ "strokeDash": { "value": [8, 8] } | ||
// For now, hard-coding the Unclassed binning method to the viridis color scale (as the linear gradient implementation requires discrete 'stop' points and there is no API that returns the list of colors for a Vega-Lite supported color scheme code). | ||
if (binningMethodName == UNCLASSED) { | ||
@@ -1439,0 +1439,0 @@ delete vlSpec["layer"][0]["encoding"]["color"]; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
301664
6511
58