@cosmograph/cosmos
Advanced tools
Comparing version 2.0.0-beta.14 to 2.0.0-beta.15
@@ -71,47 +71,48 @@ import { GraphConfig, GraphConfigInterface } from './config'; | ||
* | ||
* @param {number[]} pointPositions - An array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn], | ||
* @param {Float32Array} pointPositions - A Float32Array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn], | ||
* where `n` is the index of the point. | ||
* Example: `[1, 2, 3, 4, 5, 6]` sets the first point to (1, 2), the second point to (3, 4), and so on. | ||
* Example: `new Float32Array([1, 2, 3, 4, 5, 6])` sets the first point to (1, 2), the second point to (3, 4), and so on. | ||
*/ | ||
setPointPositions(pointPositions: number[]): void; | ||
setPointPositions(pointPositions: Float32Array): void; | ||
/** | ||
* Sets the colors for the graph points. | ||
* | ||
* @param {number[]} pointColors - An array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* @param {Float32Array} pointColors - A Float32Array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* where each color is represented in RGBA format. | ||
* Example: `[255, 0, 0, 1, 0, 255, 0, 1]` sets the first point to red and the second point to green. | ||
* Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first point to red and the second point to green. | ||
*/ | ||
setPointColors(pointColors: number[]): void; | ||
setPointColors(pointColors: Float32Array): void; | ||
/** | ||
* Sets the sizes for the graph points. | ||
* | ||
* @param {number[]} pointSizes - An array representing the sizes of points in the format [size1, size2, ..., sizen], | ||
* @param {Float32Array} pointSizes - A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen], | ||
* where `n` is the index of the point. | ||
* Example: `[10, 20, 30]` sets the first point to size 10, the second point to size 20, and the third point to size 30. | ||
* Example: `new Float32Array([10, 20, 30])` sets the first point to size 10, the second point to size 20, and the third point to size 30. | ||
*/ | ||
setPointSizes(pointSizes: number[]): void; | ||
setPointSizes(pointSizes: Float32Array): void; | ||
/** | ||
* Sets the links for the graph. | ||
* | ||
* @param {number[]} links - An array representing the links between points in the format [source1, target1, source2, target2, ..., sourcen, targetn], | ||
* @param {Float32Array} links - A Float32Array representing the links between points | ||
* in the format [source1, target1, source2, target2, ..., sourcen, targetn], | ||
* where `source` and `target` are the indices of the points being linked. | ||
* Example: `[0, 1, 1, 2]` creates a link from point 0 to point 1 and another link from point 1 to point 2. | ||
* Example: `new Float32Array([0, 1, 1, 2])` creates a link from point 0 to point 1 and another link from point 1 to point 2. | ||
*/ | ||
setLinks(links: number[]): void; | ||
setLinks(links: Float32Array): void; | ||
/** | ||
* Sets the colors for the graph links. | ||
* | ||
* @param {number[]} linkColors - An array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* @param {Float32Array} linkColors - A Float32Array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* where each color is in RGBA format. | ||
* Example: `[255, 0, 0, 1, 0, 255, 0, 1]` sets the first link to red and the second link to green. | ||
* Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first link to red and the second link to green. | ||
*/ | ||
setLinkColors(linkColors: number[]): void; | ||
setLinkColors(linkColors: Float32Array): void; | ||
/** | ||
* Sets the widths for the graph links. | ||
* | ||
* @param {number[]} linkWidths - An array representing the widths of links in the format [width1, width2, ..., widthn], | ||
* @param {Float32Array} linkWidths - A Float32Array representing the widths of links in the format [width1, width2, ..., widthn], | ||
* where `n` is the index of the link. | ||
* Example: `[1, 2, 3]` sets the first link to width 1, the second link to width 2, and the third link to width 3. | ||
* Example: `new Float32Array([1, 2, 3])` sets the first link to width 1, the second link to width 2, and the third link to width 3. | ||
*/ | ||
setLinkWidths(linkWidths: number[]): void; | ||
setLinkWidths(linkWidths: Float32Array): void; | ||
/** | ||
@@ -128,7 +129,7 @@ * Sets the arrows for the graph links. | ||
* | ||
* @param {number[]} linkStrength - An array representing the strength of each link in the format [strength1, strength2, ..., strengthn], | ||
* @param {Float32Array} linkStrength - A Float32Array representing the strength of each link in the format [strength1, strength2, ..., strengthn], | ||
* where `n` is the index of the link. | ||
* Example: `[1, 2, 3]` sets the first link to strength 1, the second link to strength 2, and the third link to strength 3. | ||
* Example: `new Float32Array([1, 2, 3])` sets the first link to strength 1, the second link to strength 2, and the third link to strength 3. | ||
*/ | ||
setLinkStrength(linkStrength: number[]): void; | ||
setLinkStrength(linkStrength: Float32Array): void; | ||
/** | ||
@@ -158,3 +159,3 @@ * Sets the point clusters for the graph. | ||
/** | ||
* Sets the force coefficients for clustering points in the graph. | ||
* Sets the force strength coefficients for clustering points in the graph. | ||
* | ||
@@ -164,7 +165,7 @@ * This method allows you to customize the forces acting on individual points during the clustering process. | ||
* | ||
* @param {number[]} forceCoefficients - Array of force coefficients for each point in the format [coeff1, coeff2, ..., coeffn], | ||
* @param {Float32Array} clusterStrength - A Float32Array of force strength coefficients for each point in the format [coeff1, coeff2, ..., coeffn], | ||
* where `n` is the index of the point. | ||
* Example: `[1, 0.4, 0.3]` sets the force coefficient for point 0 to 1, point 1 to 0.4, and point 2 to 0.3. | ||
* Example: `new Float32Array([1, 0.4, 0.3])` sets the force coefficient for point 0 to 1, point 1 to 0.4, and point 2 to 0.3. | ||
*/ | ||
setClusterForceCoefficients(forceCoefficients: number[]): void; | ||
setClusterStrength(clusterStrength: Float32Array): void; | ||
/** | ||
@@ -209,2 +210,7 @@ * Renders the graph. | ||
/** | ||
* Get current X and Y coordinates of the clusters. | ||
* @returns Array of point cluster. | ||
*/ | ||
getClusterPositions(): number[]; | ||
/** | ||
* Center and zoom in/out the view to fit all points in the scene. | ||
@@ -211,0 +217,0 @@ * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default). |
@@ -0,7 +1,8 @@ | ||
import { default as regl } from 'regl'; | ||
import { CoreModule } from '../core-module'; | ||
export declare class Clusters extends CoreModule { | ||
centermassFbo: regl.Framebuffer2D | undefined; | ||
private clusterFbo; | ||
private clusterPositionsFbo; | ||
private clusterForceCoefficientFbo; | ||
private centermassFbo; | ||
private clearCentermassCommand; | ||
@@ -8,0 +9,0 @@ private calculateCentermassCommand; |
import { GraphConfig } from '../../config'; | ||
export declare class GraphData { | ||
inputPointPositions: number[] | undefined; | ||
inputPointColors: number[] | undefined; | ||
inputPointSizes: number[] | undefined; | ||
inputLinkColors: number[] | undefined; | ||
inputLinkWidths: number[] | undefined; | ||
inputLinkStrength: number[] | undefined; | ||
inputPointPositions: Float32Array | undefined; | ||
inputPointColors: Float32Array | undefined; | ||
inputPointSizes: Float32Array | undefined; | ||
inputLinkColors: Float32Array | undefined; | ||
inputLinkWidths: Float32Array | undefined; | ||
inputLinkStrength: Float32Array | undefined; | ||
inputPointClusters: (number | undefined)[] | undefined; | ||
inputClusterPositions: (number | undefined)[] | undefined; | ||
inputPointClusterForces: number[] | undefined; | ||
pointPositions: number[] | undefined; | ||
pointColors: number[] | undefined; | ||
pointSizes: number[] | undefined; | ||
inputLinks: number[] | undefined; | ||
links: number[] | undefined; | ||
linkColors: number[] | undefined; | ||
linkWidths: number[] | undefined; | ||
inputClusterStrength: Float32Array | undefined; | ||
pointPositions: Float32Array | undefined; | ||
pointColors: Float32Array | undefined; | ||
pointSizes: Float32Array | undefined; | ||
inputLinks: Float32Array | undefined; | ||
links: Float32Array | undefined; | ||
linkColors: Float32Array | undefined; | ||
linkWidths: Float32Array | undefined; | ||
linkArrowsBoolean: boolean[] | undefined; | ||
linkArrows: number[] | undefined; | ||
linkStrength: (number | undefined)[] | undefined; | ||
linkStrength: Float32Array | undefined; | ||
pointClusters: (number | undefined)[] | undefined; | ||
clusterPositions: (number | undefined)[] | undefined; | ||
pointClusterForces: number[] | undefined; | ||
clusterStrength: Float32Array | undefined; | ||
/** | ||
@@ -33,2 +33,4 @@ * Each inner array of `sourceIndexToTargetIndices` and `targetIndexToSourceIndices` contains pairs where: | ||
degree: number[] | undefined; | ||
inDegree: number[] | undefined; | ||
outDegree: number[] | undefined; | ||
private _config; | ||
@@ -35,0 +37,0 @@ constructor(config: GraphConfig); |
import { GraphConfigInterface } from '../config'; | ||
export type CosmosStoryProps = GraphConfigInterface & { | ||
pointPositions: number[]; | ||
links: number[]; | ||
pointColors: number[]; | ||
pointPositions: Float32Array; | ||
pointColors: Float32Array; | ||
pointSizes?: Float32Array; | ||
links?: Float32Array; | ||
linkColors?: Float32Array; | ||
linkWidths?: Float32Array; | ||
pointClusters?: number[]; | ||
clusterPositions?: number[]; | ||
clusterForces?: number[]; | ||
clusterStrength?: Float32Array; | ||
showClusterLabels?: boolean; | ||
}; | ||
export declare const createCosmos: (props: CosmosStoryProps) => HTMLCanvasElement; | ||
export declare const createCosmos: (props: CosmosStoryProps) => HTMLDivElement; |
export type MeshData = { | ||
pointPositions: number[]; | ||
links: number[]; | ||
pointPositions: Float32Array; | ||
pointColors: Float32Array; | ||
pointSizes: Float32Array; | ||
links: Float32Array; | ||
linkColors: Float32Array; | ||
linkWidths: Float32Array; | ||
clusters: number[]; | ||
clusterPositions: number[]; | ||
clusterForces: number[]; | ||
pointColors: number[]; | ||
clusterStrength: Float32Array; | ||
}; | ||
export declare function generateMeshData(n: number, m: number, nClusters: number, wholeness: number, radialness?: number[]): MeshData; |
@@ -7,2 +7,2 @@ import { Meta, StoryObj } from '@storybook/html'; | ||
export declare const FullMesh: Story; | ||
export declare const MeshWithHoles: () => HTMLCanvasElement; | ||
export declare const MeshWithHoles: () => HTMLDivElement; |
{ | ||
"name": "@cosmograph/cosmos", | ||
"version": "2.0.0-beta.14", | ||
"version": "2.0.0-beta.15", | ||
"description": "GPU-based force graph layout and rendering", | ||
@@ -5,0 +5,0 @@ "jsdelivr": "dist/index.min.js", |
@@ -266,7 +266,7 @@ import { select, Selection } from 'd3-selection' | ||
* | ||
* @param {number[]} pointPositions - An array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn], | ||
* @param {Float32Array} pointPositions - A Float32Array representing the positions of points in the format [x1, y1, x2, y2, ..., xn, yn], | ||
* where `n` is the index of the point. | ||
* Example: `[1, 2, 3, 4, 5, 6]` sets the first point to (1, 2), the second point to (3, 4), and so on. | ||
* Example: `new Float32Array([1, 2, 3, 4, 5, 6])` sets the first point to (1, 2), the second point to (3, 4), and so on. | ||
*/ | ||
public setPointPositions (pointPositions: number[]): void { | ||
public setPointPositions (pointPositions: Float32Array): void { | ||
this.graph.inputPointPositions = pointPositions | ||
@@ -279,7 +279,7 @@ this._hasPointPositionsChanged = true | ||
* | ||
* @param {number[]} pointColors - An array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* @param {Float32Array} pointColors - A Float32Array representing the colors of points in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* where each color is represented in RGBA format. | ||
* Example: `[255, 0, 0, 1, 0, 255, 0, 1]` sets the first point to red and the second point to green. | ||
* Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first point to red and the second point to green. | ||
*/ | ||
public setPointColors (pointColors: number[]): void { | ||
public setPointColors (pointColors: Float32Array): void { | ||
this.graph.inputPointColors = pointColors | ||
@@ -292,7 +292,7 @@ this._hasPointColorsChanged = true | ||
* | ||
* @param {number[]} pointSizes - An array representing the sizes of points in the format [size1, size2, ..., sizen], | ||
* @param {Float32Array} pointSizes - A Float32Array representing the sizes of points in the format [size1, size2, ..., sizen], | ||
* where `n` is the index of the point. | ||
* Example: `[10, 20, 30]` sets the first point to size 10, the second point to size 20, and the third point to size 30. | ||
* Example: `new Float32Array([10, 20, 30])` sets the first point to size 10, the second point to size 20, and the third point to size 30. | ||
*/ | ||
public setPointSizes (pointSizes: number[]): void { | ||
public setPointSizes (pointSizes: Float32Array): void { | ||
this.graph.inputPointSizes = pointSizes | ||
@@ -305,7 +305,8 @@ this._hasPointSizesChanged = true | ||
* | ||
* @param {number[]} links - An array representing the links between points in the format [source1, target1, source2, target2, ..., sourcen, targetn], | ||
* @param {Float32Array} links - A Float32Array representing the links between points | ||
* in the format [source1, target1, source2, target2, ..., sourcen, targetn], | ||
* where `source` and `target` are the indices of the points being linked. | ||
* Example: `[0, 1, 1, 2]` creates a link from point 0 to point 1 and another link from point 1 to point 2. | ||
* Example: `new Float32Array([0, 1, 1, 2])` creates a link from point 0 to point 1 and another link from point 1 to point 2. | ||
*/ | ||
public setLinks (links: number[]): void { | ||
public setLinks (links: Float32Array): void { | ||
this.graph.inputLinks = links | ||
@@ -318,7 +319,7 @@ this._hasLinksChanged = true | ||
* | ||
* @param {number[]} linkColors - An array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* @param {Float32Array} linkColors - A Float32Array representing the colors of links in the format [r1, g1, b1, a1, r2, g2, b2, a2, ..., rn, gn, bn, an], | ||
* where each color is in RGBA format. | ||
* Example: `[255, 0, 0, 1, 0, 255, 0, 1]` sets the first link to red and the second link to green. | ||
* Example: `new Float32Array([255, 0, 0, 1, 0, 255, 0, 1])` sets the first link to red and the second link to green. | ||
*/ | ||
public setLinkColors (linkColors: number[]): void { | ||
public setLinkColors (linkColors: Float32Array): void { | ||
this.graph.inputLinkColors = linkColors | ||
@@ -331,7 +332,7 @@ this._hasLinkColorsChanged = true | ||
* | ||
* @param {number[]} linkWidths - An array representing the widths of links in the format [width1, width2, ..., widthn], | ||
* @param {Float32Array} linkWidths - A Float32Array representing the widths of links in the format [width1, width2, ..., widthn], | ||
* where `n` is the index of the link. | ||
* Example: `[1, 2, 3]` sets the first link to width 1, the second link to width 2, and the third link to width 3. | ||
* Example: `new Float32Array([1, 2, 3])` sets the first link to width 1, the second link to width 2, and the third link to width 3. | ||
*/ | ||
public setLinkWidths (linkWidths: number[]): void { | ||
public setLinkWidths (linkWidths: Float32Array): void { | ||
this.graph.inputLinkWidths = linkWidths | ||
@@ -356,7 +357,7 @@ this._hasLinkWidthsChanged = true | ||
* | ||
* @param {number[]} linkStrength - An array representing the strength of each link in the format [strength1, strength2, ..., strengthn], | ||
* @param {Float32Array} linkStrength - A Float32Array representing the strength of each link in the format [strength1, strength2, ..., strengthn], | ||
* where `n` is the index of the link. | ||
* Example: `[1, 2, 3]` sets the first link to strength 1, the second link to strength 2, and the third link to strength 3. | ||
* Example: `new Float32Array([1, 2, 3])` sets the first link to strength 1, the second link to strength 2, and the third link to strength 3. | ||
*/ | ||
public setLinkStrength (linkStrength: number[]): void { | ||
public setLinkStrength (linkStrength: Float32Array): void { | ||
this.graph.inputLinkStrength = linkStrength | ||
@@ -397,3 +398,3 @@ } | ||
/** | ||
* Sets the force coefficients for clustering points in the graph. | ||
* Sets the force strength coefficients for clustering points in the graph. | ||
* | ||
@@ -403,8 +404,8 @@ * This method allows you to customize the forces acting on individual points during the clustering process. | ||
* | ||
* @param {number[]} forceCoefficients - Array of force coefficients for each point in the format [coeff1, coeff2, ..., coeffn], | ||
* @param {Float32Array} clusterStrength - A Float32Array of force strength coefficients for each point in the format [coeff1, coeff2, ..., coeffn], | ||
* where `n` is the index of the point. | ||
* Example: `[1, 0.4, 0.3]` sets the force coefficient for point 0 to 1, point 1 to 0.4, and point 2 to 0.3. | ||
* Example: `new Float32Array([1, 0.4, 0.3])` sets the force coefficient for point 0 to 1, point 1 to 0.4, and point 2 to 0.3. | ||
*/ | ||
public setClusterForceCoefficients (forceCoefficients: number[]): void { | ||
this.graph.inputPointClusterForces = forceCoefficients | ||
public setClusterStrength (clusterStrength: Float32Array): void { | ||
this.graph.inputClusterStrength = clusterStrength | ||
this._hasPointClusterForceChanged = true | ||
@@ -545,2 +546,23 @@ } | ||
/** | ||
* Get current X and Y coordinates of the clusters. | ||
* @returns Array of point cluster. | ||
*/ | ||
public getClusterPositions (): number[] { | ||
if (this.graph.pointClusters === undefined || this.clusters === undefined) return [] | ||
const positions: number[] = [] | ||
const clusterPositionsPixels = readPixels(this.reglInstance, this.clusters.centermassFbo as regl.Framebuffer2D) | ||
positions.length = clusterPositionsPixels.length / 2 | ||
for (let i = 0; i < positions.length / 2; i += 1) { | ||
const sumX = clusterPositionsPixels[i * 4 + 0] | ||
const sumY = clusterPositionsPixels[i * 4 + 1] | ||
const sumN = clusterPositionsPixels[i * 4 + 2] | ||
if (sumX !== undefined && sumY !== undefined && sumN !== undefined) { | ||
positions[i * 2] = sumX / sumN | ||
positions[i * 2 + 1] = sumY / sumN | ||
} | ||
} | ||
return positions | ||
} | ||
/** | ||
* Center and zoom in/out the view to fit all points in the scene. | ||
@@ -547,0 +569,0 @@ * @param duration Duration of the center and zoom in/out animation in milliseconds (`250` by default). |
@@ -11,6 +11,7 @@ import regl from 'regl' | ||
export class Clusters extends CoreModule { | ||
public centermassFbo: regl.Framebuffer2D | undefined | ||
private clusterFbo: regl.Framebuffer2D | undefined | ||
private clusterPositionsFbo: regl.Framebuffer2D | undefined | ||
private clusterForceCoefficientFbo: regl.Framebuffer2D | undefined | ||
private centermassFbo: regl.Framebuffer2D | undefined | ||
private clearCentermassCommand: regl.DrawCommand | undefined | ||
@@ -64,3 +65,3 @@ private calculateCentermassCommand: regl.DrawCommand | undefined | ||
if (data.pointClusterForces) clusterForceCoefficient[i * 4 + 0] = data.pointClusterForces[i] ?? 1 | ||
if (data.clusterStrength) clusterForceCoefficient[i * 4 + 0] = data.clusterStrength[i] ?? 1 | ||
} | ||
@@ -67,0 +68,0 @@ this.clusterTexture({ |
import { getRgbaColor, isNumber } from '@/graph/helper' | ||
import { GraphConfig } from '@/graph/config' | ||
export class GraphData { | ||
public inputPointPositions: number[] | undefined | ||
public inputPointColors: number[] | undefined | ||
public inputPointSizes: number[] | undefined | ||
public inputLinkColors: number[] | undefined | ||
public inputLinkWidths: number[] | undefined | ||
public inputLinkStrength: number[] | undefined | ||
public inputPointPositions: Float32Array | undefined | ||
public inputPointColors: Float32Array | undefined | ||
public inputPointSizes: Float32Array | undefined | ||
public inputLinkColors: Float32Array | undefined | ||
public inputLinkWidths: Float32Array | undefined | ||
public inputLinkStrength: Float32Array | undefined | ||
public inputPointClusters: (number | undefined)[] | undefined | ||
public inputClusterPositions: (number | undefined)[] | undefined | ||
public inputPointClusterForces: number[] | undefined | ||
public inputClusterStrength: Float32Array | undefined | ||
public pointPositions: number[] | undefined | ||
public pointColors: number[] | undefined | ||
public pointSizes: number[] | undefined | ||
public pointPositions: Float32Array | undefined | ||
public pointColors: Float32Array | undefined | ||
public pointSizes: Float32Array | undefined | ||
public inputLinks: number[] | undefined | ||
public links: number[] | undefined | ||
public linkColors: number[] | undefined | ||
public linkWidths: number[] | undefined | ||
public inputLinks: Float32Array | undefined | ||
public links: Float32Array | undefined | ||
public linkColors: Float32Array | undefined | ||
public linkWidths: Float32Array | undefined | ||
public linkArrowsBoolean: boolean[] | undefined | ||
public linkArrows: number[] | undefined | ||
public linkStrength: (number | undefined)[] | undefined | ||
public linkStrength: Float32Array | undefined | ||
public pointClusters: (number | undefined)[] | undefined | ||
public clusterPositions: (number | undefined)[] | undefined | ||
public pointClusterForces: number[] | undefined | ||
public clusterStrength: Float32Array | undefined | ||
@@ -39,2 +39,4 @@ /** | ||
public degree: number[] | undefined | ||
public inDegree: number[] | undefined | ||
public outDegree: number[] | undefined | ||
@@ -71,3 +73,3 @@ private _config: GraphConfig | ||
if (this.inputPointColors === undefined || this.inputPointColors.length / 4 !== this.pointsNumber) { | ||
this.pointColors = new Array(this.pointsNumber * 4) | ||
this.pointColors = new Float32Array(this.pointsNumber * 4) | ||
for (let i = 0; i < this.pointColors.length / 4; i++) { | ||
@@ -101,3 +103,3 @@ this.pointColors[i * 4] = defaultRgba[0] | ||
if (this.inputPointSizes === undefined || this.inputPointSizes.length !== this.pointsNumber) { | ||
this.pointSizes = new Array(this.pointsNumber).fill(this._config.defaultPointSize) | ||
this.pointSizes = new Float32Array(this.pointsNumber).fill(this._config.defaultPointSize) | ||
} else { | ||
@@ -129,3 +131,3 @@ this.pointSizes = this.inputPointSizes | ||
if (this.inputLinkColors === undefined || this.inputLinkColors.length / 4 !== this.linksNumber) { | ||
this.linkColors = new Array(this.linksNumber * 4) | ||
this.linkColors = new Float32Array(this.linksNumber * 4) | ||
@@ -160,3 +162,3 @@ for (let i = 0; i < this.linkColors.length / 4; i++) { | ||
if (this.inputLinkWidths === undefined || this.inputLinkWidths.length !== this.linksNumber) { | ||
this.linkWidths = new Array(this.linksNumber).fill(this._config.defaultLinkWidth) | ||
this.linkWidths = new Float32Array(this.linksNumber).fill(this._config.defaultLinkWidth) | ||
} else { | ||
@@ -217,6 +219,6 @@ this.linkWidths = this.inputLinkWidths | ||
} | ||
if (this.inputPointClusterForces === undefined || this.inputPointClusterForces.length !== this.pointsNumber) { | ||
this.pointClusterForces = undefined | ||
if (this.inputClusterStrength === undefined || this.inputClusterStrength.length !== this.pointsNumber) { | ||
this.clusterStrength = undefined | ||
} else { | ||
this.pointClusterForces = this.inputPointClusterForces | ||
this.clusterStrength = this.inputClusterStrength | ||
} | ||
@@ -271,9 +273,17 @@ } | ||
this.degree = undefined | ||
this.inDegree = undefined | ||
this.outDegree = undefined | ||
return | ||
} | ||
this.degree = new Array(this.pointsNumber).fill(0) | ||
this.inDegree = new Array(this.pointsNumber).fill(0) | ||
this.outDegree = new Array(this.pointsNumber).fill(0) | ||
for (let i = 0; i < this.pointsNumber; i++) { | ||
this.degree[i] = (this.sourceIndexToTargetIndices?.[i]?.length ?? 0) + (this.targetIndexToSourceIndices?.[i]?.length ?? 0) | ||
this.inDegree[i] = this.targetIndexToSourceIndices?.[i]?.length ?? 0 | ||
this.outDegree[i] = this.sourceIndexToTargetIndices?.[i]?.length ?? 0 | ||
this.degree[i] = (this.inDegree[i] ?? 0) + (this.outDegree[i] ?? 0) | ||
} | ||
} | ||
} |
@@ -135,3 +135,3 @@ import regl from 'regl' | ||
if (!this.colorBuffer) this.colorBuffer = reglInstance.buffer(0) | ||
this.colorBuffer(data.linkColors ?? []) | ||
this.colorBuffer(data.linkColors ?? new Float32Array()) | ||
} | ||
@@ -142,3 +142,3 @@ | ||
if (!this.widthBuffer) this.widthBuffer = reglInstance.buffer(0) | ||
this.widthBuffer(data.linkWidths ?? []) | ||
this.widthBuffer(data.linkWidths ?? new Float32Array()) | ||
} | ||
@@ -149,3 +149,3 @@ | ||
if (!this.arrowBuffer) this.arrowBuffer = reglInstance.buffer(0) | ||
this.arrowBuffer(data.linkArrows ?? []) | ||
this.arrowBuffer(data.linkArrows ?? new Float32Array()) | ||
} | ||
@@ -152,0 +152,0 @@ |
@@ -406,3 +406,3 @@ import regl from 'regl' | ||
if (!this.colorBuffer) this.colorBuffer = reglInstance.buffer(0) | ||
this.colorBuffer(data.pointColors as number[]) | ||
this.colorBuffer(data.pointColors as Float32Array) | ||
} | ||
@@ -409,0 +409,0 @@ |
@@ -33,2 +33,3 @@ import type { Meta, StoryObj } from '@storybook/html' | ||
links: wormData.links, | ||
linkColors: wormData.linkColors, | ||
}, | ||
@@ -42,6 +43,11 @@ } | ||
pointColors: radialData.pointColors, | ||
pointSizes: radialData.pointSizes, | ||
pointClusters: radialData.clusters, | ||
links: radialData.links, | ||
linkColors: radialData.linkColors, | ||
linkWidths: radialData.linkWidths, | ||
clusterPositions: radialData.clusterPositions, | ||
links: radialData.links, | ||
clusterForces: radialData.clusterForces, | ||
clusterStrength: radialData.clusterStrength, | ||
}, | ||
@@ -59,3 +65,5 @@ } | ||
pointClusters: withoutLinksData.clusters, | ||
showClusterLabels: true, | ||
}, | ||
} |
@@ -5,14 +5,23 @@ import { GraphConfigInterface } from '@/graph/config' | ||
export type CosmosStoryProps = GraphConfigInterface & { | ||
pointPositions: number[]; | ||
links: number[]; | ||
pointColors: number[]; | ||
pointPositions: Float32Array; | ||
pointColors: Float32Array; | ||
pointSizes?: Float32Array; | ||
links?: Float32Array; | ||
linkColors?: Float32Array; | ||
linkWidths?: Float32Array; | ||
// linkStrength?: Float32Array; | ||
pointClusters?: number[]; | ||
clusterPositions?: number[]; | ||
clusterForces?: number[]; | ||
clusterStrength?: Float32Array; | ||
showClusterLabels?: boolean; | ||
} | ||
export const createCosmos = (props: CosmosStoryProps): HTMLCanvasElement => { | ||
export const createCosmos = (props: CosmosStoryProps): HTMLDivElement => { | ||
const div = document.createElement('div') | ||
const canvas = document.createElement('canvas') | ||
canvas.style.height = '100vh' | ||
canvas.style.width = '100%' | ||
div.appendChild(canvas) | ||
@@ -49,14 +58,70 @@ const config: GraphConfigInterface = { | ||
graph.setPointColors(props.pointColors) | ||
if (props.pointSizes) graph.setPointSizes(props.pointSizes) | ||
if (props.links) graph.setLinks(props.links) | ||
if (props.linkColors) graph.setLinkColors(props.linkColors) | ||
if (props.linkWidths) graph.setLinkWidths(props.linkWidths) | ||
// if (props.linkStrength) graph.setLinkStrength(props.linkStrength) | ||
if (props.pointClusters) graph.setPointClusters(props.pointClusters) | ||
if (props.clusterPositions) graph.setClusterPositions(props.clusterPositions) | ||
if (props.clusterForces) graph.setClusterForceCoefficients(props.clusterForces) | ||
if (props.clusterStrength) graph.setClusterStrength(props.clusterStrength) | ||
graph.zoom(0.9) | ||
graph.render() | ||
if (props.showClusterLabels) { | ||
const clusterLabelDivs: HTMLDivElement[] = [] | ||
function updateClusterLabels (graph: Graph): void { | ||
const clusterPositions = graph.getClusterPositions() | ||
const nClusters = clusterPositions.length / 2 | ||
if (nClusters === 0) return | ||
if (clusterLabelDivs.length === 0) { | ||
for (let i = 0; i < nClusters; i++) { | ||
const clusterLabelDiv = document.createElement('div') | ||
const contentLabel = document.createElement('p') | ||
clusterLabelDiv.appendChild(contentLabel) | ||
clusterLabelDiv.style.position = 'absolute' | ||
clusterLabelDiv.style.pointerEvents = 'none' | ||
contentLabel.style.fontFamily = [ | ||
'"Nunito Sans"', | ||
'-apple-system', | ||
'".SFNSText-Regular"', | ||
'"San Francisco"', | ||
'BlinkMacSystemFont', | ||
'"Segoe UI"', | ||
'"Helvetica Neue"', | ||
'Helvetica', | ||
'Arial', | ||
'sans-serif', | ||
].join(', ') | ||
contentLabel.style.fontWeight = 'bold' | ||
contentLabel.style.color = 'white' | ||
contentLabel.style.transform = 'translate(-50%, -100%)' | ||
contentLabel.innerText = `Cluster ${i + 1}` | ||
div.appendChild(clusterLabelDiv) | ||
clusterLabelDivs[i] = clusterLabelDiv | ||
} | ||
} | ||
for (let i = 0; i < nClusters; i++) { | ||
const clusterPosition = clusterPositions.slice(i * 2, i * 2 + 2) | ||
const x = clusterPosition[0] | ||
const y = clusterPosition[1] | ||
const clusterLabelDiv = clusterLabelDivs[i] as HTMLDivElement | ||
const screenXY = graph.spaceToScreenPosition([x ?? 0, y ?? 0]) | ||
clusterLabelDiv.style.top = `${screenXY[1]}px` | ||
clusterLabelDiv.style.left = `${screenXY[0]}px` | ||
} | ||
} | ||
graph.setConfig({ | ||
onZoom: updateClusterLabels.bind(this, graph), | ||
onSimulationTick: updateClusterLabels.bind(this, graph), | ||
}) | ||
} | ||
}) | ||
return canvas | ||
return div | ||
} |
@@ -16,8 +16,14 @@ import { scaleLinear, scaleSequential } from 'd3-scale' | ||
export type MeshData = { | ||
pointPositions: number[]; | ||
links: number[]; | ||
pointPositions: Float32Array; | ||
pointColors: Float32Array; | ||
pointSizes: Float32Array; | ||
links: Float32Array; | ||
linkColors: Float32Array; | ||
linkWidths: Float32Array; | ||
// linkStrength: Float32Array; | ||
clusters: number[]; | ||
clusterPositions: number[]; | ||
clusterForces: number[]; | ||
pointColors: number[]; | ||
clusterStrength: Float32Array; | ||
} | ||
@@ -37,8 +43,9 @@ | ||
const pointPositions = new Array(n * m * 2) | ||
const pointPositions = new Float32Array(n * m * 2) | ||
const links: number[] = [] | ||
const clusters = new Array(n * m) | ||
const clusterPositions = new Array(nClusters * 2) | ||
const clusterForces = new Array(n * m) | ||
const pointColors = new Array(n * m * 4) | ||
const clusterStrength = new Float32Array(n * m) | ||
const pointColors = new Float32Array(n * m * 4) | ||
const pointSizes = new Float32Array(n * m) | ||
@@ -60,3 +67,3 @@ const spaceSize = 4096 | ||
clusters[pointIndex] = pointIndex % nClusters | ||
clusterForces[pointIndex] = (nClusters - (pointIndex % nClusters)) / nClusters | ||
clusterStrength[pointIndex] = (nClusters - (pointIndex % nClusters)) / nClusters | ||
const pointColor = pointColorScale(pointIndex % nClusters) | ||
@@ -69,2 +76,4 @@ const rgba = getRgbaColor(pointColor) | ||
pointSizes[pointIndex] = getRandom(1, 5) | ||
const nextPointIndex = pointIndex + 1 | ||
@@ -87,3 +96,31 @@ const bottomPointIndex = pointIndex + n | ||
return { pointPositions, links, clusters, clusterForces, clusterPositions, pointColors } | ||
const linkColors = new Float32Array(links.length / 2 * 4) | ||
const linkWidths = new Float32Array(links.length / 2) | ||
// const linkStrength = new Float32Array(links.length / 2) | ||
for (let i = 0; i < links.length / 2; i++) { | ||
const sourcePointIndex = links[i * 2] as number | ||
const rgba = getRgbaColor(pointColorScale(sourcePointIndex % nClusters)) | ||
linkColors[i * 4 + 0] = rgba[0] | ||
linkColors[i * 4 + 1] = rgba[1] | ||
linkColors[i * 4 + 2] = rgba[2] | ||
linkColors[i * 4 + 3] = 0.9 | ||
linkWidths[i] = getRandom(0.1, 0.5) | ||
// linkStrength[i] = (n * m - sourcePointIndex) / (n * m) | ||
} | ||
return { | ||
pointPositions, | ||
pointColors, | ||
pointSizes, | ||
links: new Float32Array(links), | ||
linkColors, | ||
linkWidths, | ||
// linkStrength, | ||
clusters, | ||
clusterStrength, | ||
clusterPositions, | ||
} | ||
} |
@@ -33,3 +33,3 @@ import type { Meta, StoryObj } from '@storybook/html' | ||
export const MeshWithHoles = (): HTMLCanvasElement => { | ||
export const MeshWithHoles = (): HTMLDivElement => { | ||
const { pointPositions, links, pointColors } = generateMeshData(40, 80, 15, 0.8) | ||
@@ -36,0 +36,0 @@ |
import { resolve } from 'path' | ||
import { defineConfig } from 'vite' | ||
import { defineConfig, LibraryFormats, UserConfig } from 'vite' | ||
import glsl from 'vite-plugin-glsl' | ||
@@ -7,40 +7,48 @@ import dts from 'vite-plugin-dts' | ||
// eslint-disable-next-line import/no-default-export | ||
export default defineConfig({ | ||
build: { | ||
lib: { | ||
entry: resolve(__dirname, 'src/index.ts'), | ||
name: 'Cosmos', | ||
formats: ['es', 'umd'], | ||
fileName: (format) => format === 'umd' ? 'index.min.js' : 'index.js', | ||
}, | ||
sourcemap: true, | ||
minify: true, | ||
rollupOptions: { | ||
external: ['d3-array', 'd3-color', 'd3-drag', 'd3-ease', 'd3-scale', 'd3-selection', 'd3-transition', 'd3-zoom', 'regl'], | ||
output: { | ||
globals: { | ||
'd3-selection': 'd3', | ||
'd3-ease': 'd3', | ||
regl: 'createREGL', | ||
'd3-color': 'd3', | ||
'd3-scale': 'd3', | ||
'd3-array': 'd3', | ||
'gl-matrix': 'glMatrix', | ||
random: 'random', | ||
'd3-zoom': 'd3', | ||
'd3-drag': 'd3', | ||
'd3-transition': 'd3', | ||
export default defineConfig(() => { | ||
const config: UserConfig = { | ||
build: { | ||
lib: { | ||
entry: resolve(__dirname, 'src/index.ts'), | ||
name: 'Cosmos', | ||
formats: ['es', 'umd'] as LibraryFormats[], | ||
fileName: (format): string => format === 'umd' ? 'index.min.js' : 'index.js', | ||
}, | ||
sourcemap: true, | ||
minify: true, | ||
rollupOptions: { | ||
external: ['d3-array', 'd3-color', 'd3-drag', 'd3-ease', 'd3-scale', 'd3-selection', 'd3-transition', 'd3-zoom', 'regl'], | ||
output: { | ||
globals: { | ||
'd3-selection': 'd3', | ||
'd3-ease': 'd3', | ||
regl: 'createREGL', | ||
'd3-color': 'd3', | ||
'd3-scale': 'd3', | ||
'd3-array': 'd3', | ||
'gl-matrix': 'glMatrix', | ||
random: 'random', | ||
'd3-zoom': 'd3', | ||
'd3-drag': 'd3', | ||
'd3-transition': 'd3', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
plugins: [ | ||
glsl(), | ||
dts(), | ||
], | ||
resolve: { | ||
alias: { | ||
'@/graph': resolve(__dirname, 'src/'), | ||
plugins: [ | ||
glsl(), | ||
dts(), | ||
], | ||
resolve: { | ||
alias: { | ||
'@/graph': resolve(__dirname, 'src/'), | ||
}, | ||
}, | ||
}, | ||
} | ||
if (config?.build?.lib && config.build.rollupOptions && config.build.lib.formats && config.build.lib.formats.includes('umd')) { | ||
delete config.build.rollupOptions.external | ||
} | ||
return config | ||
}) |
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 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 not supported yet
Sorry, the diff of this file is not supported yet
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
3392519
20555
1