-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(graph): add last year color viz
- Loading branch information
Showing
9 changed files
with
288 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
precision mediump float; | ||
|
||
varying vec4 v_color; | ||
varying float v_thickness; | ||
varying vec2 v_cpA; | ||
varying vec2 v_cpB; | ||
varying vec2 v_cpC; | ||
|
||
float det(vec2 a, vec2 b) { | ||
return a.x * b.y - b.x * a.y; | ||
} | ||
|
||
vec2 get_distance_vector(vec2 b0, vec2 b1, vec2 b2) { | ||
float a = det(b0, b2), b = 2.0 * det(b1, b0), d = 2.0 * det(b2, b1); | ||
float f = b * d - a * a; | ||
vec2 d21 = b2 - b1, d10 = b1 - b0, d20 = b2 - b0; | ||
vec2 gf = 2.0 * (b * d21 + d * d10 + a * d20); | ||
gf = vec2(gf.y, -gf.x); | ||
vec2 pp = -f * gf / dot(gf, gf); | ||
vec2 d0p = b0 - pp; | ||
float ap = det(d0p, d20), bp = 2.0 * det(d10, d0p); | ||
float t = clamp((ap + bp) / (2.0 * a + b + d), 0.0, 1.0); | ||
return mix(mix(b0, b1, t), mix(b1, b2, t), t); | ||
} | ||
|
||
float distToQuadraticBezierCurve(vec2 p, vec2 b0, vec2 b1, vec2 b2) { | ||
return length(get_distance_vector(b0 - p, b1 - p, b2 - p)); | ||
} | ||
|
||
const float epsilon = 0.7; | ||
const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0); | ||
|
||
void main(void) { | ||
float dist = distToQuadraticBezierCurve(gl_FragCoord.xy, v_cpA, v_cpB, v_cpC); | ||
|
||
if (dist < v_thickness + epsilon) { | ||
float inCurve = 1.0 - smoothstep(v_thickness - epsilon, v_thickness + epsilon, dist); | ||
gl_FragColor = inCurve * vec4(v_color.rgb * v_color.a, v_color.a); | ||
} else { | ||
gl_FragColor = transparent; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* eslint-disable */ | ||
import { floatColor, canUse32BitsIndices } from 'sigma/utils'; | ||
import { AbstractEdgeProgram } from 'sigma/rendering/webgl/programs/common/edge'; | ||
|
||
import vertexShaderSource from './edge.curve.vert.glsl?raw'; | ||
import fragmentShaderSource from './edge.curve.frag.glsl?raw'; | ||
|
||
const POINTS = 2, | ||
ATTRIBUTES = 3; | ||
|
||
export default class EdgeFastProgram extends AbstractEdgeProgram { | ||
positionLocation; | ||
colorLocation; | ||
matrixLocation; | ||
|
||
constructor(gl) { | ||
super(gl, vertexShaderSource, fragmentShaderSource, POINTS, ATTRIBUTES); | ||
|
||
// Locations: | ||
this.positionLocation = gl.getAttribLocation(this.program, "a_position"); | ||
this.colorLocation = gl.getAttribLocation(this.program, "a_color"); | ||
|
||
// Uniform locations: | ||
const matrixLocation = gl.getUniformLocation(this.program, "u_matrix"); | ||
if (matrixLocation === null) throw new Error("EdgeFastProgram: error while getting matrixLocation"); | ||
this.matrixLocation = matrixLocation; | ||
|
||
this.bind(); | ||
} | ||
|
||
bind() { | ||
const gl = this.gl; | ||
|
||
// Bindings | ||
gl.enableVertexAttribArray(this.positionLocation); | ||
gl.enableVertexAttribArray(this.colorLocation); | ||
|
||
gl.vertexAttribPointer( | ||
this.positionLocation, | ||
2, | ||
gl.FLOAT, | ||
false, | ||
this.attributes * Float32Array.BYTES_PER_ELEMENT, | ||
0, | ||
); | ||
gl.vertexAttribPointer( | ||
this.colorLocation, | ||
4, | ||
gl.UNSIGNED_BYTE, | ||
true, | ||
this.attributes * Float32Array.BYTES_PER_ELEMENT, | ||
8, | ||
); | ||
} | ||
|
||
computeIndices() { | ||
//nothing to do | ||
} | ||
|
||
process(sourceData, targetData, data, hidden, offset) { | ||
const array = this.array; | ||
|
||
let i = 0; | ||
if (hidden) { | ||
for (let l = i + POINTS * ATTRIBUTES; i < l; i++) array[i] = 0; | ||
return; | ||
} | ||
|
||
const x1 = sourceData.x, | ||
y1 = sourceData.y, | ||
x2 = targetData.x, | ||
y2 = targetData.y, | ||
color = floatColor(data.color); | ||
|
||
i = POINTS * ATTRIBUTES * offset; | ||
|
||
// First point | ||
array[i++] = x1; | ||
array[i++] = y1; | ||
array[i++] = color; | ||
|
||
// Second point | ||
array[i++] = x2; | ||
array[i++] = y2; | ||
array[i] = color; | ||
} | ||
|
||
render(params) { | ||
if (this.hasNothingToRender()) return; | ||
|
||
const gl = this.gl; | ||
const program = this.program; | ||
|
||
gl.useProgram(program); | ||
|
||
gl.uniformMatrix3fv(this.matrixLocation, false, params.matrix); | ||
|
||
gl.drawArrays(gl.LINES, 0, this.array.length / ATTRIBUTES); | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
attribute vec4 a_color; | ||
attribute float a_direction; | ||
attribute float a_thickness; | ||
attribute vec2 a_source; | ||
attribute vec2 a_target; | ||
attribute float a_current; | ||
|
||
uniform mat3 u_matrix; | ||
uniform float u_sizeRatio; | ||
uniform float u_pixelRatio; | ||
uniform vec2 u_dimensions; | ||
|
||
varying vec4 v_color; | ||
varying float v_thickness; | ||
varying vec2 v_cpA; | ||
varying vec2 v_cpB; | ||
varying vec2 v_cpC; | ||
|
||
const float bias = 255.0 / 254.0; | ||
const float epsilon = 0.7; | ||
const float minThickness = 0.3; | ||
|
||
const float defaultCurveness = 0.25; | ||
|
||
vec2 clipspaceToViewport(vec2 pos, vec2 dimensions) { | ||
return vec2( | ||
(pos.x + 1.0) * dimensions.x / 2.0, | ||
(pos.y + 1.0) * dimensions.y / 2.0 | ||
); | ||
} | ||
|
||
vec2 viewportToClipspace(vec2 pos, vec2 dimensions) { | ||
return vec2( | ||
pos.x / dimensions.x * 2.0 - 1.0, | ||
pos.y / dimensions.y * 2.0 - 1.0 | ||
); | ||
} | ||
|
||
void main() { | ||
|
||
const float curveness = defaultCurveness; | ||
|
||
// Selecting the correct position | ||
// Branchless "position = a_source if a_current == 1.0 else a_target" | ||
vec2 position = a_source * max(0.0, a_current) + a_target * max(0.0, 1.0 - a_current); | ||
position = (u_matrix * vec3(position, 1)).xy; | ||
|
||
vec2 source = (u_matrix * vec3(a_source, 1)).xy; | ||
vec2 target = (u_matrix * vec3(a_target, 1)).xy; | ||
|
||
vec2 viewportPosition = clipspaceToViewport(position, u_dimensions); | ||
vec2 viewportSource = clipspaceToViewport(source, u_dimensions); | ||
vec2 viewportTarget = clipspaceToViewport(target, u_dimensions); | ||
|
||
vec2 delta = viewportTarget.xy - viewportSource.xy; | ||
float len = length(delta); | ||
vec2 normal = vec2(-delta.y, delta.x) * a_direction; | ||
vec2 unitNormal = normal / len; | ||
float boundingBoxThickness = len * curveness; | ||
float curveThickness = max(minThickness, a_thickness / 2.0 / u_sizeRatio * u_pixelRatio); | ||
|
||
v_thickness = curveThickness; | ||
|
||
v_cpA = viewportSource; | ||
v_cpB = 0.5 * (viewportSource + viewportTarget) + unitNormal * a_direction * boundingBoxThickness; | ||
v_cpC = viewportTarget; | ||
|
||
vec2 viewportOffsetPosition = ( | ||
viewportPosition + | ||
unitNormal * (boundingBoxThickness / 2.0 + curveThickness + epsilon) * | ||
max(0.0, a_direction) // NOTE: cutting the bounding box in half to avoid overdraw | ||
); | ||
|
||
position = viewportToClipspace(viewportOffsetPosition, u_dimensions); | ||
gl_Position = vec4(position, 0, 1); | ||
|
||
v_color = a_color; | ||
v_color.a *= bias; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.