Merge pull request #31556 from marcwjj/master

Add typings for venn.js library
This commit is contained in:
Nathan Shively-Sanders
2018-12-20 16:29:03 -08:00
committed by GitHub
4 changed files with 207 additions and 0 deletions

106
types/venn/index.d.ts vendored Normal file
View File

@@ -0,0 +1,106 @@
// Type definitions for venn 0.2.16
// Project: https://github.com/benfred/venn.js/
// Definitions by: Jiajing Wang <https://github.com/marcwjj>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
import * as d3 from 'd3';
/** Typing for Point object. */
export interface Point {
x: number;
y: number;
}
/** Typing for Circle object. */
export interface Circle {
x: number;
y: number;
radius: number;
}
/** Typing for Overlap object. */
export interface Overlap {
sets: string[];
size: number;
weight?: number;
}
/** Typing for Area object. */
export interface Area {
sets: string[];
size: number;
}
/** Typing for layout function parameter. */
export interface LayoutParameter {
lossFunction?: (sets: {[key: string]: Circle}, overlaps: Overlap[]) => number;
restarts?: number;
}
/** Typing for the VennDiagram instance. */
export interface VennDiagram {
(selection: d3.Selection<d3.BaseType, {}, d3.BaseType, {}|undefined>): {};
width: (w: number) => VennDiagram;
height: (h: number) => VennDiagram;
duration: (d: number) => VennDiagram;
layoutFunction:
(f: (areas: Area[], parameters: LayoutParameter) => void) => VennDiagram;
lossFunction:
(f: (sets: {[key: string]: Circle},
overlaps: Overlap[]) => number) => VennDiagram;
orientationOrder:
(f: (a: {setid: string}, b: {setid: string}) => number) => VennDiagram;
}
/**
* Typing for venn.intersectionArea that returns the intersection area of a
* bunch of circles (where each circle is an object having an x,y and radius
* property).
*/
export function intersectionArea(
circles: Array<{}>, stats?: {}): number;
/**
* Typing for venn.distance that returns euclidean distance between two points.
*/
export function distance(p1: Point, p2: Point): number;
/**
* Typing for venn.circleOverlap that returns the overlap area of two circles
* of radius r1 and r2 - that have their centers separated by distance d.
* Simpler faster circle intersection for only two circles.
*/
export function circleOverlap(
r1: number, r2: number, d: number): number;
/**
* Typing for venn.circleFromPath that returns a circle object from an svg path.
*/
export function circleFromPath(path: string): Circle;
/**
* Typing for venn.sortAreas that sorts all areas in the venn diagram, so that
* a particular area is on top (relativeTo) - and all other areas are so that
* the smallest areas are on top.
*/
export function sortAreas(
div: d3.Selection<d3.BaseType, {}, d3.BaseType, {}|undefined>,
relativeTo: Area): void;
/**
* Typing for venn.bestInitialLayout that takes the best working variant of
* either constrained MDS or greedy.
*/
export function bestInitialLayout(
areas: Area[], params: LayoutParameter): Circle[];
/**
* Typing for venn.venn, which given a list of set objects, and their
* corresponding overlaps, updates the (x, y, radius) attribute on each set such
* that their positions roughly correspond to the desired overlaps.
*/
export function venn(areas: Area[], parameters: {}): Circle[];
/** Typing for the constructor. */
export function VennDiagram(): VennDiagram;

24
types/venn/tsconfig.json Normal file
View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"venn-tests.ts"
]
}

6
types/venn/tslint.json Normal file
View File

@@ -0,0 +1,6 @@
{
"extends": "dtslint/dt.json",
"rules": {
"dt-header": false
}
}

71
types/venn/venn-tests.ts Normal file
View File

@@ -0,0 +1,71 @@
/**
* Created by marcwjj on 12/19/2018.
*/
import venn = require('venn');
const vennDiagram = venn.VennDiagram()
.width(100)
.height(200)
.duration(300);
vennDiagram.orientationOrder(
(a: {setid: string}, b: {setid: string}) =>
a['setid'].localeCompare(b['setid']));
function lossFunction(
sets: {[key: string]: venn.Circle},
overlaps: venn.Overlap[]): number {
let output = 0;
for (const area of overlaps) {
let overlapSize;
if (area.sets.length === 1) {
continue;
} else {
if (area.sets.length === 2) {
const left = sets[area.sets[0]];
const right = sets[area.sets[1]];
overlapSize = venn.circleOverlap(
left.radius, right.radius, venn.distance(left, right));
} else {
overlapSize =
venn.intersectionArea(area.sets.map((i: string) => sets[i]));
}
}
if (overlapSize < 100 && area.size > 0) {
return Number.MAX_VALUE;
}
// Penalizes rendering overlapping circles when there is no actual overlap.
if (area.size === 0 && overlapSize > 0) {
output += (overlapSize - area.size) * (overlapSize - area.size) * 100000;
}
const weight = area.weight !== undefined ? area.weight : 1;
output += weight * (overlapSize - area.size) * (overlapSize - area.size);
}
return output;
}
vennDiagram.layoutFunction(
(areas: venn.Area[], parameters: venn.LayoutParameter) => {
return venn.venn(
areas, {
initialLayout: (areas: venn.Area[]) => {
const circles: {[key: string]: venn.Circle} = {};
let circleCount = 0;
areas.filter((area) => area.sets.length === 1)
.forEach((area) => {
circles[area.sets[0]] = {
x: 0,
y: 0,
radius: Math.sqrt(area.size / Math.PI),
};
circleCount += 1;
});
return venn.bestInitialLayout(areas, {lossFunction});
},
...parameters,
});
});
vennDiagram.lossFunction(lossFunction);