sigma
Version:
A JavaScript library aimed at visualizing graphs of thousands of nodes and edges.
1,152 lines (1,099 loc) • 52.4 kB
JavaScript
'use strict';
var inherits = require('./inherits-04acba6b.cjs.dev.js');
var colors = require('./colors-fe6de9d2.cjs.dev.js');
function _defineProperty(e, r, t) {
return (r = inherits._toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
function ownKeys(e, r) {
var t = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function (r) {
return Object.getOwnPropertyDescriptor(e, r).enumerable;
})), t.push.apply(t, o);
}
return t;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
_defineProperty(e, r, t[r]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
});
}
return e;
}
function _superPropBase(t, o) {
for (; !{}.hasOwnProperty.call(t, o) && null !== (t = inherits._getPrototypeOf(t)););
return t;
}
function _get() {
return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {
var p = _superPropBase(e, t);
if (p) {
var n = Object.getOwnPropertyDescriptor(p, t);
return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
}
}, _get.apply(null, arguments);
}
function _superPropGet(t, o, e, r) {
var p = _get(inherits._getPrototypeOf(1 & r ? t.prototype : t), o, e);
return 2 & r && "function" == typeof p ? function (t) {
return p.apply(e, t);
} : p;
}
function getAttributeItemsCount(attr) {
return attr.normalized ? 1 : attr.size;
}
function getAttributesItemsCount(attrs) {
var res = 0;
attrs.forEach(function (attr) {
return res += getAttributeItemsCount(attr);
});
return res;
}
function loadShader(type, gl, source) {
var glType = type === "VERTEX" ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER;
// Creating the shader
var shader = gl.createShader(glType);
if (shader === null) {
throw new Error("loadShader: error while creating the shader");
}
// Loading source
gl.shaderSource(shader, source);
// Compiling the shader
gl.compileShader(shader);
// Retrieving compilation status
var successfullyCompiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
// Throwing if something went awry
if (!successfullyCompiled) {
var infoLog = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw new Error("loadShader: error while compiling the shader:\n".concat(infoLog, "\n").concat(source));
}
return shader;
}
function loadVertexShader(gl, source) {
return loadShader("VERTEX", gl, source);
}
function loadFragmentShader(gl, source) {
return loadShader("FRAGMENT", gl, source);
}
/**
* Function used to load a program.
*/
function loadProgram(gl, shaders) {
var program = gl.createProgram();
if (program === null) {
throw new Error("loadProgram: error while creating the program.");
}
var i, l;
// Attaching the shaders
for (i = 0, l = shaders.length; i < l; i++) gl.attachShader(program, shaders[i]);
gl.linkProgram(program);
// Checking status
var successfullyLinked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!successfullyLinked) {
gl.deleteProgram(program);
throw new Error("loadProgram: error while linking the program.");
}
return program;
}
function killProgram(_ref) {
var gl = _ref.gl,
buffer = _ref.buffer,
program = _ref.program,
vertexShader = _ref.vertexShader,
fragmentShader = _ref.fragmentShader;
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
gl.deleteProgram(program);
gl.deleteBuffer(buffer);
}
/**
* Function use to print a float for inserting in a GLSL program.
*/
function numberToGLSLFloat(n) {
return n % 1 === 0 ? n.toFixed(1) : n.toString();
}
var PICKING_PREFIX = "#define PICKING_MODE\n";
var SIZE_FACTOR_PER_ATTRIBUTE_TYPE = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, WebGL2RenderingContext.BOOL, 1), WebGL2RenderingContext.BYTE, 1), WebGL2RenderingContext.UNSIGNED_BYTE, 1), WebGL2RenderingContext.SHORT, 2), WebGL2RenderingContext.UNSIGNED_SHORT, 2), WebGL2RenderingContext.INT, 4), WebGL2RenderingContext.UNSIGNED_INT, 4), WebGL2RenderingContext.FLOAT, 4);
var AbstractProgram = /*#__PURE__*/inherits._createClass(function AbstractProgram(_gl, _pickGl, _renderer) {
inherits._classCallCheck(this, AbstractProgram);
});
var Program = /*#__PURE__*/function () {
function Program(gl, pickingBuffer, renderer) {
inherits._classCallCheck(this, Program);
// GLenum
_defineProperty(this, "array", new Float32Array());
_defineProperty(this, "constantArray", new Float32Array());
_defineProperty(this, "capacity", 0);
_defineProperty(this, "verticesCount", 0);
// Reading and caching program definition
var def = this.getDefinition();
this.VERTICES = def.VERTICES;
this.VERTEX_SHADER_SOURCE = def.VERTEX_SHADER_SOURCE;
this.FRAGMENT_SHADER_SOURCE = def.FRAGMENT_SHADER_SOURCE;
this.UNIFORMS = def.UNIFORMS;
this.ATTRIBUTES = def.ATTRIBUTES;
this.METHOD = def.METHOD;
this.CONSTANT_ATTRIBUTES = "CONSTANT_ATTRIBUTES" in def ? def.CONSTANT_ATTRIBUTES : [];
this.CONSTANT_DATA = "CONSTANT_DATA" in def ? def.CONSTANT_DATA : [];
this.isInstanced = "CONSTANT_ATTRIBUTES" in def;
// Computing stride
this.ATTRIBUTES_ITEMS_COUNT = getAttributesItemsCount(this.ATTRIBUTES);
this.STRIDE = this.VERTICES * this.ATTRIBUTES_ITEMS_COUNT;
// Members
this.renderer = renderer;
this.normalProgram = this.getProgramInfo("normal", gl, def.VERTEX_SHADER_SOURCE, def.FRAGMENT_SHADER_SOURCE, null);
this.pickProgram = pickingBuffer ? this.getProgramInfo("pick", gl, PICKING_PREFIX + def.VERTEX_SHADER_SOURCE, PICKING_PREFIX + def.FRAGMENT_SHADER_SOURCE, pickingBuffer) : null;
// For instanced programs:
if (this.isInstanced) {
var constantAttributesItemsCount = getAttributesItemsCount(this.CONSTANT_ATTRIBUTES);
if (this.CONSTANT_DATA.length !== this.VERTICES) throw new Error("Program: error while getting constant data (expected ".concat(this.VERTICES, " items, received ").concat(this.CONSTANT_DATA.length, " instead)"));
this.constantArray = new Float32Array(this.CONSTANT_DATA.length * constantAttributesItemsCount);
for (var i = 0; i < this.CONSTANT_DATA.length; i++) {
var vector = this.CONSTANT_DATA[i];
if (vector.length !== constantAttributesItemsCount) throw new Error("Program: error while getting constant data (one vector has ".concat(vector.length, " items instead of ").concat(constantAttributesItemsCount, ")"));
for (var j = 0; j < vector.length; j++) this.constantArray[i * constantAttributesItemsCount + j] = vector[j];
}
this.STRIDE = this.ATTRIBUTES_ITEMS_COUNT;
}
}
return inherits._createClass(Program, [{
key: "kill",
value: function kill() {
killProgram(this.normalProgram);
if (this.pickProgram) {
killProgram(this.pickProgram);
this.pickProgram = null;
}
}
}, {
key: "getProgramInfo",
value: function getProgramInfo(name, gl, vertexShaderSource, fragmentShaderSource, frameBuffer) {
var def = this.getDefinition();
// WebGL buffers
var buffer = gl.createBuffer();
if (buffer === null) throw new Error("Program: error while creating the WebGL buffer.");
// Shaders and program
var vertexShader = loadVertexShader(gl, vertexShaderSource);
var fragmentShader = loadFragmentShader(gl, fragmentShaderSource);
var program = loadProgram(gl, [vertexShader, fragmentShader]);
// Initializing locations
var uniformLocations = {};
def.UNIFORMS.forEach(function (uniformName) {
var location = gl.getUniformLocation(program, uniformName);
if (location) uniformLocations[uniformName] = location;
});
var attributeLocations = {};
def.ATTRIBUTES.forEach(function (attr) {
attributeLocations[attr.name] = gl.getAttribLocation(program, attr.name);
});
// For instanced programs:
var constantBuffer;
if ("CONSTANT_ATTRIBUTES" in def) {
def.CONSTANT_ATTRIBUTES.forEach(function (attr) {
attributeLocations[attr.name] = gl.getAttribLocation(program, attr.name);
});
constantBuffer = gl.createBuffer();
if (constantBuffer === null) throw new Error("Program: error while creating the WebGL constant buffer.");
}
return {
name: name,
program: program,
gl: gl,
frameBuffer: frameBuffer,
buffer: buffer,
constantBuffer: constantBuffer || {},
uniformLocations: uniformLocations,
attributeLocations: attributeLocations,
isPicking: name === "pick",
vertexShader: vertexShader,
fragmentShader: fragmentShader
};
}
}, {
key: "bindProgram",
value: function bindProgram(program) {
var _this = this;
var offset = 0;
var gl = program.gl,
buffer = program.buffer;
if (!this.isInstanced) {
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
offset = 0;
this.ATTRIBUTES.forEach(function (attr) {
return offset += _this.bindAttribute(attr, program, offset);
});
gl.bufferData(gl.ARRAY_BUFFER, this.array, gl.DYNAMIC_DRAW);
} else {
// Handle constant data (things that remain unchanged for all items):
gl.bindBuffer(gl.ARRAY_BUFFER, program.constantBuffer);
offset = 0;
this.CONSTANT_ATTRIBUTES.forEach(function (attr) {
return offset += _this.bindAttribute(attr, program, offset, false);
});
gl.bufferData(gl.ARRAY_BUFFER, this.constantArray, gl.STATIC_DRAW);
// Handle "instance specific" data (things that vary for each item):
gl.bindBuffer(gl.ARRAY_BUFFER, program.buffer);
offset = 0;
this.ATTRIBUTES.forEach(function (attr) {
return offset += _this.bindAttribute(attr, program, offset, true);
});
gl.bufferData(gl.ARRAY_BUFFER, this.array, gl.DYNAMIC_DRAW);
}
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
}, {
key: "unbindProgram",
value: function unbindProgram(program) {
var _this2 = this;
if (!this.isInstanced) {
this.ATTRIBUTES.forEach(function (attr) {
return _this2.unbindAttribute(attr, program);
});
} else {
this.CONSTANT_ATTRIBUTES.forEach(function (attr) {
return _this2.unbindAttribute(attr, program, false);
});
this.ATTRIBUTES.forEach(function (attr) {
return _this2.unbindAttribute(attr, program, true);
});
}
}
}, {
key: "bindAttribute",
value: function bindAttribute(attr, program, offset, setDivisor) {
var sizeFactor = SIZE_FACTOR_PER_ATTRIBUTE_TYPE[attr.type];
if (typeof sizeFactor !== "number") throw new Error("Program.bind: yet unsupported attribute type \"".concat(attr.type, "\""));
var location = program.attributeLocations[attr.name];
var gl = program.gl;
if (location !== -1) {
gl.enableVertexAttribArray(location);
var stride = !this.isInstanced ? this.ATTRIBUTES_ITEMS_COUNT * Float32Array.BYTES_PER_ELEMENT : (setDivisor ? this.ATTRIBUTES_ITEMS_COUNT : getAttributesItemsCount(this.CONSTANT_ATTRIBUTES)) * Float32Array.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(location, attr.size, attr.type, attr.normalized || false, stride, offset);
if (this.isInstanced && setDivisor) {
if (gl instanceof WebGL2RenderingContext) {
gl.vertexAttribDivisor(location, 1);
} else {
var ext = gl.getExtension("ANGLE_instanced_arrays");
if (ext) ext.vertexAttribDivisorANGLE(location, 1);
}
}
}
return attr.size * sizeFactor;
}
}, {
key: "unbindAttribute",
value: function unbindAttribute(attr, program, unsetDivisor) {
var location = program.attributeLocations[attr.name];
var gl = program.gl;
if (location !== -1) {
gl.disableVertexAttribArray(location);
if (this.isInstanced && unsetDivisor) {
if (gl instanceof WebGL2RenderingContext) {
gl.vertexAttribDivisor(location, 0);
} else {
var ext = gl.getExtension("ANGLE_instanced_arrays");
if (ext) ext.vertexAttribDivisorANGLE(location, 0);
}
}
}
}
}, {
key: "reallocate",
value: function reallocate(capacity) {
// If desired capacity has not changed we do nothing
// NOTE: it's possible here to implement more subtle reallocation schemes
// when the number of rendered items increase or decrease
if (capacity === this.capacity) return;
this.capacity = capacity;
this.verticesCount = this.VERTICES * capacity;
this.array = new Float32Array(!this.isInstanced ? this.verticesCount * this.ATTRIBUTES_ITEMS_COUNT : this.capacity * this.ATTRIBUTES_ITEMS_COUNT);
}
}, {
key: "hasNothingToRender",
value: function hasNothingToRender() {
return this.verticesCount === 0;
}
}, {
key: "renderProgram",
value: function renderProgram(params, programInfo) {
var gl = programInfo.gl,
program = programInfo.program;
// With the current fix for #1397, the alpha blending is enabled for the
// picking layer:
gl.enable(gl.BLEND);
// Original code:
// if (!isPicking) gl.enable(gl.BLEND);
// else gl.disable(gl.BLEND);
gl.useProgram(program);
this.setUniforms(params, programInfo);
this.drawWebGL(this.METHOD, programInfo);
}
}, {
key: "render",
value: function render(params) {
if (this.hasNothingToRender()) return;
if (this.pickProgram) {
this.pickProgram.gl.viewport(0, 0, params.width * params.pixelRatio / params.downSizingRatio, params.height * params.pixelRatio / params.downSizingRatio);
this.bindProgram(this.pickProgram);
this.renderProgram(_objectSpread2(_objectSpread2({}, params), {}, {
pixelRatio: params.pixelRatio / params.downSizingRatio
}), this.pickProgram);
this.unbindProgram(this.pickProgram);
}
this.normalProgram.gl.viewport(0, 0, params.width * params.pixelRatio, params.height * params.pixelRatio);
this.bindProgram(this.normalProgram);
this.renderProgram(params, this.normalProgram);
this.unbindProgram(this.normalProgram);
}
}, {
key: "drawWebGL",
value: function drawWebGL(method, _ref) {
var gl = _ref.gl,
frameBuffer = _ref.frameBuffer;
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
if (!this.isInstanced) {
gl.drawArrays(method, 0, this.verticesCount);
} else {
if (gl instanceof WebGL2RenderingContext) {
gl.drawArraysInstanced(method, 0, this.VERTICES, this.capacity);
} else {
var ext = gl.getExtension("ANGLE_instanced_arrays");
if (ext) ext.drawArraysInstancedANGLE(method, 0, this.VERTICES, this.capacity);
}
}
}
}]);
}();
var AbstractNodeProgram = /*#__PURE__*/function (_AbstractProgram) {
function AbstractNodeProgram() {
inherits._classCallCheck(this, AbstractNodeProgram);
return inherits._callSuper(this, AbstractNodeProgram, arguments);
}
inherits._inherits(AbstractNodeProgram, _AbstractProgram);
return inherits._createClass(AbstractNodeProgram);
}(AbstractProgram);
var NodeProgram = /*#__PURE__*/function (_ref) {
function NodeProgram() {
inherits._classCallCheck(this, NodeProgram);
return inherits._callSuper(this, NodeProgram, arguments);
}
inherits._inherits(NodeProgram, _ref);
return inherits._createClass(NodeProgram, [{
key: "kill",
value: function kill() {
_superPropGet(NodeProgram, "kill", this, 3)([]);
}
}, {
key: "process",
value: function process(nodeIndex, offset, data) {
var i = offset * this.STRIDE;
// NOTE: dealing with hidden items automatically
if (data.hidden) {
for (var l = i + this.STRIDE; i < l; i++) {
this.array[i] = 0;
}
return;
}
return this.processVisibleItem(colors.indexToColor(nodeIndex), i, data);
}
}]);
}(Program);
/**
* Helper function combining two or more programs into a single compound one.
* Note that this is more a quick & easy way to combine program than a really
* performant option. More performant programs can be written entirely.
*
* @param {array} programClasses - Program classes to combine.
* @param {function} drawLabel - An optional node "draw label" function.
* @param {function} drawHover - An optional node "draw hover" function.
* @return {function}
*/
function createNodeCompoundProgram(programClasses, drawLabel, drawHover) {
return /*#__PURE__*/function () {
function NodeCompoundProgram(gl, pickingBuffer, renderer) {
inherits._classCallCheck(this, NodeCompoundProgram);
_defineProperty(this, "drawLabel", drawLabel);
_defineProperty(this, "drawHover", drawHover);
this.programs = programClasses.map(function (Program) {
return new Program(gl, pickingBuffer, renderer);
});
}
return inherits._createClass(NodeCompoundProgram, [{
key: "reallocate",
value: function reallocate(capacity) {
this.programs.forEach(function (program) {
return program.reallocate(capacity);
});
}
}, {
key: "process",
value: function process(nodeIndex, offset, data) {
this.programs.forEach(function (program) {
return program.process(nodeIndex, offset, data);
});
}
}, {
key: "render",
value: function render(params) {
this.programs.forEach(function (program) {
return program.render(params);
});
}
}, {
key: "kill",
value: function kill() {
this.programs.forEach(function (program) {
return program.kill();
});
}
}]);
}();
}
var AbstractEdgeProgram = /*#__PURE__*/function (_AbstractProgram) {
function AbstractEdgeProgram() {
inherits._classCallCheck(this, AbstractEdgeProgram);
return inherits._callSuper(this, AbstractEdgeProgram, arguments);
}
inherits._inherits(AbstractEdgeProgram, _AbstractProgram);
return inherits._createClass(AbstractEdgeProgram);
}(AbstractProgram);
var EdgeProgram = /*#__PURE__*/function (_ref) {
function EdgeProgram() {
var _this;
inherits._classCallCheck(this, EdgeProgram);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = inherits._callSuper(this, EdgeProgram, [].concat(args));
_defineProperty(_this, "drawLabel", undefined);
return _this;
}
inherits._inherits(EdgeProgram, _ref);
return inherits._createClass(EdgeProgram, [{
key: "kill",
value: function kill() {
_superPropGet(EdgeProgram, "kill", this, 3)([]);
}
}, {
key: "process",
value: function process(edgeIndex, offset, sourceData, targetData, data) {
var i = offset * this.STRIDE;
// NOTE: dealing with hidden items automatically
if (data.hidden || sourceData.hidden || targetData.hidden) {
for (var l = i + this.STRIDE; i < l; i++) {
this.array[i] = 0;
}
return;
}
return this.processVisibleItem(colors.indexToColor(edgeIndex), i, sourceData, targetData, data);
}
}]);
}(Program);
/**
* Helper function combining two or more programs into a single compound one.
* Note that this is more a quick & easy way to combine program than a really
* performant option. More performant programs can be written entirely.
*
* @param {array} programClasses - Program classes to combine.
* @param {function} drawLabel - An optional edge "draw label" function.
* @return {function}
*/
function createEdgeCompoundProgram(programClasses, drawLabel) {
return /*#__PURE__*/function () {
function EdgeCompoundProgram(gl, pickingBuffer, renderer) {
inherits._classCallCheck(this, EdgeCompoundProgram);
_defineProperty(this, "drawLabel", drawLabel);
this.programs = programClasses.map(function (Program) {
return new Program(gl, pickingBuffer, renderer);
});
}
return inherits._createClass(EdgeCompoundProgram, [{
key: "reallocate",
value: function reallocate(capacity) {
this.programs.forEach(function (program) {
return program.reallocate(capacity);
});
}
}, {
key: "process",
value: function process(edgeIndex, offset, sourceData, targetData, data) {
this.programs.forEach(function (program) {
return program.process(edgeIndex, offset, sourceData, targetData, data);
});
}
}, {
key: "render",
value: function render(params) {
this.programs.forEach(function (program) {
return program.render(params);
});
}
}, {
key: "kill",
value: function kill() {
this.programs.forEach(function (program) {
return program.kill();
});
}
}]);
}();
}
function drawStraightEdgeLabel(context, edgeData, sourceData, targetData, settings) {
var size = settings.edgeLabelSize,
font = settings.edgeLabelFont,
weight = settings.edgeLabelWeight,
color = settings.edgeLabelColor.attribute ? edgeData[settings.edgeLabelColor.attribute] || settings.edgeLabelColor.color || "#000" : settings.edgeLabelColor.color;
var label = edgeData.label;
if (!label) return;
context.fillStyle = color;
context.font = "".concat(weight, " ").concat(size, "px ").concat(font);
// Computing positions without considering nodes sizes:
var sSize = sourceData.size;
var tSize = targetData.size;
var sx = sourceData.x;
var sy = sourceData.y;
var tx = targetData.x;
var ty = targetData.y;
var cx = (sx + tx) / 2;
var cy = (sy + ty) / 2;
var dx = tx - sx;
var dy = ty - sy;
var d = Math.sqrt(dx * dx + dy * dy);
if (d < sSize + tSize) return;
// Adding nodes sizes:
sx += dx * sSize / d;
sy += dy * sSize / d;
tx -= dx * tSize / d;
ty -= dy * tSize / d;
cx = (sx + tx) / 2;
cy = (sy + ty) / 2;
dx = tx - sx;
dy = ty - sy;
d = Math.sqrt(dx * dx + dy * dy);
// Handling ellipsis
var textLength = context.measureText(label).width;
if (textLength > d) {
var ellipsis = "…";
label = label + ellipsis;
textLength = context.measureText(label).width;
while (textLength > d && label.length > 1) {
label = label.slice(0, -2) + ellipsis;
textLength = context.measureText(label).width;
}
if (label.length < 4) return;
}
var angle;
if (dx > 0) {
if (dy > 0) angle = Math.acos(dx / d);else angle = Math.asin(dy / d);
} else {
if (dy > 0) angle = Math.acos(dx / d) + Math.PI;else angle = Math.asin(dx / d) + Math.PI / 2;
}
context.save();
context.translate(cx, cy);
context.rotate(angle);
context.fillText(label, -textLength / 2, edgeData.size / 2 + size);
context.restore();
}
function drawDiscNodeLabel(context, data, settings) {
if (!data.label) return;
var size = settings.labelSize,
font = settings.labelFont,
weight = settings.labelWeight,
color = settings.labelColor.attribute ? data[settings.labelColor.attribute] || settings.labelColor.color || "#000" : settings.labelColor.color;
context.fillStyle = color;
context.font = "".concat(weight, " ").concat(size, "px ").concat(font);
context.fillText(data.label, data.x + data.size + 3, data.y + size / 3);
}
/**
* Draw an hovered node.
* - if there is no label => display a shadow on the node
* - if the label box is bigger than node size => display a label box that contains the node with a shadow
* - else node with shadow and the label box
*/
function drawDiscNodeHover(context, data, settings) {
var size = settings.labelSize,
font = settings.labelFont,
weight = settings.labelWeight;
context.font = "".concat(weight, " ").concat(size, "px ").concat(font);
// Then we draw the label background
context.fillStyle = "#FFF";
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 8;
context.shadowColor = "#000";
var PADDING = 2;
if (typeof data.label === "string") {
var textWidth = context.measureText(data.label).width,
boxWidth = Math.round(textWidth + 5),
boxHeight = Math.round(size + 2 * PADDING),
radius = Math.max(data.size, size / 2) + PADDING;
var angleRadian = Math.asin(boxHeight / 2 / radius);
var xDeltaCoord = Math.sqrt(Math.abs(Math.pow(radius, 2) - Math.pow(boxHeight / 2, 2)));
context.beginPath();
context.moveTo(data.x + xDeltaCoord, data.y + boxHeight / 2);
context.lineTo(data.x + radius + boxWidth, data.y + boxHeight / 2);
context.lineTo(data.x + radius + boxWidth, data.y - boxHeight / 2);
context.lineTo(data.x + xDeltaCoord, data.y - boxHeight / 2);
context.arc(data.x, data.y, radius, angleRadian, -angleRadian);
context.closePath();
context.fill();
} else {
context.beginPath();
context.arc(data.x, data.y, data.size + PADDING, 0, Math.PI * 2);
context.closePath();
context.fill();
}
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 0;
// And finally we draw the label
drawDiscNodeLabel(context, data, settings);
}
// language=GLSL
var SHADER_SOURCE$6 = /*glsl*/"\nprecision highp float;\n\nvarying vec4 v_color;\nvarying vec2 v_diffVector;\nvarying float v_radius;\n\nuniform float u_correctionRatio;\n\nconst vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0);\n\nvoid main(void) {\n float border = u_correctionRatio * 2.0;\n float dist = length(v_diffVector) - v_radius + border;\n\n // No antialiasing for picking mode:\n #ifdef PICKING_MODE\n if (dist > border)\n gl_FragColor = transparent;\n else\n gl_FragColor = v_color;\n\n #else\n float t = 0.0;\n if (dist > border)\n t = 1.0;\n else if (dist > 0.0)\n t = dist / border;\n\n gl_FragColor = mix(v_color, transparent, t);\n #endif\n}\n";
var FRAGMENT_SHADER_SOURCE$2 = SHADER_SOURCE$6;
// language=GLSL
var SHADER_SOURCE$5 = /*glsl*/"\nattribute vec4 a_id;\nattribute vec4 a_color;\nattribute vec2 a_position;\nattribute float a_size;\nattribute float a_angle;\n\nuniform mat3 u_matrix;\nuniform float u_sizeRatio;\nuniform float u_correctionRatio;\n\nvarying vec4 v_color;\nvarying vec2 v_diffVector;\nvarying float v_radius;\nvarying float v_border;\n\nconst float bias = 255.0 / 254.0;\n\nvoid main() {\n float size = a_size * u_correctionRatio / u_sizeRatio * 4.0;\n vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle));\n vec2 position = a_position + diffVector;\n gl_Position = vec4(\n (u_matrix * vec3(position, 1)).xy,\n 0,\n 1\n );\n\n v_diffVector = diffVector;\n v_radius = size / 2.0;\n\n #ifdef PICKING_MODE\n // For picking mode, we use the ID as the color:\n v_color = a_id;\n #else\n // For normal mode, we use the color:\n v_color = a_color;\n #endif\n\n v_color.a *= bias;\n}\n";
var VERTEX_SHADER_SOURCE$3 = SHADER_SOURCE$5;
var _WebGLRenderingContex$3 = WebGLRenderingContext,
UNSIGNED_BYTE$3 = _WebGLRenderingContex$3.UNSIGNED_BYTE,
FLOAT$3 = _WebGLRenderingContex$3.FLOAT;
var UNIFORMS$3 = ["u_sizeRatio", "u_correctionRatio", "u_matrix"];
var NodeCircleProgram = /*#__PURE__*/function (_NodeProgram) {
function NodeCircleProgram() {
inherits._classCallCheck(this, NodeCircleProgram);
return inherits._callSuper(this, NodeCircleProgram, arguments);
}
inherits._inherits(NodeCircleProgram, _NodeProgram);
return inherits._createClass(NodeCircleProgram, [{
key: "getDefinition",
value: function getDefinition() {
return {
VERTICES: 3,
VERTEX_SHADER_SOURCE: VERTEX_SHADER_SOURCE$3,
FRAGMENT_SHADER_SOURCE: FRAGMENT_SHADER_SOURCE$2,
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS: UNIFORMS$3,
ATTRIBUTES: [{
name: "a_position",
size: 2,
type: FLOAT$3
}, {
name: "a_size",
size: 1,
type: FLOAT$3
}, {
name: "a_color",
size: 4,
type: UNSIGNED_BYTE$3,
normalized: true
}, {
name: "a_id",
size: 4,
type: UNSIGNED_BYTE$3,
normalized: true
}],
CONSTANT_ATTRIBUTES: [{
name: "a_angle",
size: 1,
type: FLOAT$3
}],
CONSTANT_DATA: [[NodeCircleProgram.ANGLE_1], [NodeCircleProgram.ANGLE_2], [NodeCircleProgram.ANGLE_3]]
};
}
}, {
key: "processVisibleItem",
value: function processVisibleItem(nodeIndex, startIndex, data) {
var array = this.array;
var color = colors.floatColor(data.color);
array[startIndex++] = data.x;
array[startIndex++] = data.y;
array[startIndex++] = data.size;
array[startIndex++] = color;
array[startIndex++] = nodeIndex;
}
}, {
key: "setUniforms",
value: function setUniforms(params, _ref) {
var gl = _ref.gl,
uniformLocations = _ref.uniformLocations;
var u_sizeRatio = uniformLocations.u_sizeRatio,
u_correctionRatio = uniformLocations.u_correctionRatio,
u_matrix = uniformLocations.u_matrix;
gl.uniform1f(u_correctionRatio, params.correctionRatio);
gl.uniform1f(u_sizeRatio, params.sizeRatio);
gl.uniformMatrix3fv(u_matrix, false, params.matrix);
}
}]);
}(NodeProgram);
_defineProperty(NodeCircleProgram, "ANGLE_1", 0);
_defineProperty(NodeCircleProgram, "ANGLE_2", 2 * Math.PI / 3);
_defineProperty(NodeCircleProgram, "ANGLE_3", 4 * Math.PI / 3);
// language=GLSL
var SHADER_SOURCE$4 = /*glsl*/"\nprecision mediump float;\n\nvarying vec4 v_color;\n\nvoid main(void) {\n gl_FragColor = v_color;\n}\n";
var FRAGMENT_SHADER_SOURCE$1 = SHADER_SOURCE$4;
// language=GLSL
var SHADER_SOURCE$3 = /*glsl*/"\nattribute vec2 a_position;\nattribute vec2 a_normal;\nattribute float a_radius;\nattribute vec3 a_barycentric;\n\n#ifdef PICKING_MODE\nattribute vec4 a_id;\n#else\nattribute vec4 a_color;\n#endif\n\nuniform mat3 u_matrix;\nuniform float u_sizeRatio;\nuniform float u_correctionRatio;\nuniform float u_minEdgeThickness;\nuniform float u_lengthToThicknessRatio;\nuniform float u_widenessToThicknessRatio;\n\nvarying vec4 v_color;\n\nconst float bias = 255.0 / 254.0;\n\nvoid main() {\n float minThickness = u_minEdgeThickness;\n\n float normalLength = length(a_normal);\n vec2 unitNormal = a_normal / normalLength;\n\n // These first computations are taken from edge.vert.glsl and\n // edge.clamped.vert.glsl. Please read it to get better comments on what's\n // happening:\n float pixelsThickness = max(normalLength / u_sizeRatio, minThickness);\n float webGLThickness = pixelsThickness * u_correctionRatio;\n float webGLNodeRadius = a_radius * 2.0 * u_correctionRatio / u_sizeRatio;\n float webGLArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0;\n float webGLArrowHeadThickness = webGLThickness * u_widenessToThicknessRatio;\n\n float da = a_barycentric.x;\n float db = a_barycentric.y;\n float dc = a_barycentric.z;\n\n vec2 delta = vec2(\n da * (webGLNodeRadius * unitNormal.y)\n + db * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y + webGLArrowHeadThickness * unitNormal.x)\n + dc * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y - webGLArrowHeadThickness * unitNormal.x),\n\n da * (-webGLNodeRadius * unitNormal.x)\n + db * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x + webGLArrowHeadThickness * unitNormal.y)\n + dc * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x - webGLArrowHeadThickness * unitNormal.y)\n );\n\n vec2 position = (u_matrix * vec3(a_position + delta, 1)).xy;\n\n gl_Position = vec4(position, 0, 1);\n\n #ifdef PICKING_MODE\n // For picking mode, we use the ID as the color:\n v_color = a_id;\n #else\n // For normal mode, we use the color:\n v_color = a_color;\n #endif\n\n v_color.a *= bias;\n}\n";
var VERTEX_SHADER_SOURCE$2 = SHADER_SOURCE$3;
var _WebGLRenderingContex$2 = WebGLRenderingContext,
UNSIGNED_BYTE$2 = _WebGLRenderingContex$2.UNSIGNED_BYTE,
FLOAT$2 = _WebGLRenderingContex$2.FLOAT;
var UNIFORMS$2 = ["u_matrix", "u_sizeRatio", "u_correctionRatio", "u_minEdgeThickness", "u_lengthToThicknessRatio", "u_widenessToThicknessRatio"];
var DEFAULT_EDGE_ARROW_HEAD_PROGRAM_OPTIONS = {
extremity: "target",
lengthToThicknessRatio: 2.5,
widenessToThicknessRatio: 2
};
function createEdgeArrowHeadProgram(inputOptions) {
var options = _objectSpread2(_objectSpread2({}, DEFAULT_EDGE_ARROW_HEAD_PROGRAM_OPTIONS), inputOptions || {});
return /*#__PURE__*/function (_EdgeProgram) {
function EdgeArrowHeadProgram() {
inherits._classCallCheck(this, EdgeArrowHeadProgram);
return inherits._callSuper(this, EdgeArrowHeadProgram, arguments);
}
inherits._inherits(EdgeArrowHeadProgram, _EdgeProgram);
return inherits._createClass(EdgeArrowHeadProgram, [{
key: "getDefinition",
value: function getDefinition() {
return {
VERTICES: 3,
VERTEX_SHADER_SOURCE: VERTEX_SHADER_SOURCE$2,
FRAGMENT_SHADER_SOURCE: FRAGMENT_SHADER_SOURCE$1,
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS: UNIFORMS$2,
ATTRIBUTES: [{
name: "a_position",
size: 2,
type: FLOAT$2
}, {
name: "a_normal",
size: 2,
type: FLOAT$2
}, {
name: "a_radius",
size: 1,
type: FLOAT$2
}, {
name: "a_color",
size: 4,
type: UNSIGNED_BYTE$2,
normalized: true
}, {
name: "a_id",
size: 4,
type: UNSIGNED_BYTE$2,
normalized: true
}],
CONSTANT_ATTRIBUTES: [{
name: "a_barycentric",
size: 3,
type: FLOAT$2
}],
CONSTANT_DATA: [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
};
}
}, {
key: "processVisibleItem",
value: function processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) {
if (options.extremity === "source") {
var _ref = [targetData, sourceData];
sourceData = _ref[0];
targetData = _ref[1];
}
var thickness = data.size || 1;
var radius = targetData.size || 1;
var x1 = sourceData.x;
var y1 = sourceData.y;
var x2 = targetData.x;
var y2 = targetData.y;
var color = colors.floatColor(data.color);
// Computing normals
var dx = x2 - x1;
var dy = y2 - y1;
var len = dx * dx + dy * dy;
var n1 = 0;
var n2 = 0;
if (len) {
len = 1 / Math.sqrt(len);
n1 = -dy * len * thickness;
n2 = dx * len * thickness;
}
var array = this.array;
array[startIndex++] = x2;
array[startIndex++] = y2;
array[startIndex++] = -n1;
array[startIndex++] = -n2;
array[startIndex++] = radius;
array[startIndex++] = color;
array[startIndex++] = edgeIndex;
}
}, {
key: "setUniforms",
value: function setUniforms(params, _ref2) {
var gl = _ref2.gl,
uniformLocations = _ref2.uniformLocations;
var u_matrix = uniformLocations.u_matrix,
u_sizeRatio = uniformLocations.u_sizeRatio,
u_correctionRatio = uniformLocations.u_correctionRatio,
u_minEdgeThickness = uniformLocations.u_minEdgeThickness,
u_lengthToThicknessRatio = uniformLocations.u_lengthToThicknessRatio,
u_widenessToThicknessRatio = uniformLocations.u_widenessToThicknessRatio;
gl.uniformMatrix3fv(u_matrix, false, params.matrix);
gl.uniform1f(u_sizeRatio, params.sizeRatio);
gl.uniform1f(u_correctionRatio, params.correctionRatio);
gl.uniform1f(u_minEdgeThickness, params.minEdgeThickness);
gl.uniform1f(u_lengthToThicknessRatio, options.lengthToThicknessRatio);
gl.uniform1f(u_widenessToThicknessRatio, options.widenessToThicknessRatio);
}
}]);
}(EdgeProgram);
}
var EdgeArrowHeadProgram = createEdgeArrowHeadProgram();
var EdgeArrowHeadProgram$1 = EdgeArrowHeadProgram;
// language=GLSL
var SHADER_SOURCE$2 = /*glsl*/"\nprecision mediump float;\n\nvarying vec4 v_color;\nvarying vec2 v_normal;\nvarying float v_thickness;\nvarying float v_feather;\n\nconst vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0);\n\nvoid main(void) {\n // We only handle antialiasing for normal mode:\n #ifdef PICKING_MODE\n gl_FragColor = v_color;\n #else\n float dist = length(v_normal) * v_thickness;\n\n float t = smoothstep(\n v_thickness - v_feather,\n v_thickness,\n dist\n );\n\n gl_FragColor = mix(v_color, transparent, t);\n #endif\n}\n";
var FRAGMENT_SHADER_SOURCE = SHADER_SOURCE$2;
// language=GLSL
var SHADER_SOURCE$1 = /*glsl*/"\nattribute vec4 a_id;\nattribute vec4 a_color;\nattribute vec2 a_normal;\nattribute float a_normalCoef;\nattribute vec2 a_positionStart;\nattribute vec2 a_positionEnd;\nattribute float a_positionCoef;\nattribute float a_radius;\nattribute float a_radiusCoef;\n\nuniform mat3 u_matrix;\nuniform float u_zoomRatio;\nuniform float u_sizeRatio;\nuniform float u_pixelRatio;\nuniform float u_correctionRatio;\nuniform float u_minEdgeThickness;\nuniform float u_lengthToThicknessRatio;\nuniform float u_feather;\n\nvarying vec4 v_color;\nvarying vec2 v_normal;\nvarying float v_thickness;\nvarying float v_feather;\n\nconst float bias = 255.0 / 254.0;\n\nvoid main() {\n float minThickness = u_minEdgeThickness;\n\n float radius = a_radius * a_radiusCoef;\n vec2 normal = a_normal * a_normalCoef;\n vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef;\n\n float normalLength = length(normal);\n vec2 unitNormal = normal / normalLength;\n\n // These first computations are taken from edge.vert.glsl. Please read it to\n // get better comments on what's happening:\n float pixelsThickness = max(normalLength, minThickness * u_sizeRatio);\n float webGLThickness = pixelsThickness * u_correctionRatio / u_sizeRatio;\n\n // Here, we move the point to leave space for the arrow head:\n float direction = sign(radius);\n float webGLNodeRadius = direction * radius * 2.0 * u_correctionRatio / u_sizeRatio;\n float webGLArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0;\n\n vec2 compensationVector = vec2(-direction * unitNormal.y, direction * unitNormal.x) * (webGLNodeRadius + webGLArrowHeadLength);\n\n // Here is the proper position of the vertex\n gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness + compensationVector, 1)).xy, 0, 1);\n\n v_thickness = webGLThickness / u_zoomRatio;\n\n v_normal = unitNormal;\n\n v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0;\n\n #ifdef PICKING_MODE\n // For picking mode, we use the ID as the color:\n v_color = a_id;\n #else\n // For normal mode, we use the color:\n v_color = a_color;\n #endif\n\n v_color.a *= bias;\n}\n";
var VERTEX_SHADER_SOURCE$1 = SHADER_SOURCE$1;
var _WebGLRenderingContex$1 = WebGLRenderingContext,
UNSIGNED_BYTE$1 = _WebGLRenderingContex$1.UNSIGNED_BYTE,
FLOAT$1 = _WebGLRenderingContex$1.FLOAT;
var UNIFORMS$1 = ["u_matrix", "u_zoomRatio", "u_sizeRatio", "u_correctionRatio", "u_pixelRatio", "u_feather", "u_minEdgeThickness", "u_lengthToThicknessRatio"];
var DEFAULT_EDGE_CLAMPED_PROGRAM_OPTIONS = {
lengthToThicknessRatio: DEFAULT_EDGE_ARROW_HEAD_PROGRAM_OPTIONS.lengthToThicknessRatio
};
function createEdgeClampedProgram(inputOptions) {
var options = _objectSpread2(_objectSpread2({}, DEFAULT_EDGE_CLAMPED_PROGRAM_OPTIONS), inputOptions || {});
return /*#__PURE__*/function (_EdgeProgram) {
function EdgeClampedProgram() {
inherits._classCallCheck(this, EdgeClampedProgram);
return inherits._callSuper(this, EdgeClampedProgram, arguments);
}
inherits._inherits(EdgeClampedProgram, _EdgeProgram);
return inherits._createClass(EdgeClampedProgram, [{
key: "getDefinition",
value: function getDefinition() {
return {
VERTICES: 6,
VERTEX_SHADER_SOURCE: VERTEX_SHADER_SOURCE$1,
FRAGMENT_SHADER_SOURCE: FRAGMENT_SHADER_SOURCE,
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS: UNIFORMS$1,
ATTRIBUTES: [{
name: "a_positionStart",
size: 2,
type: FLOAT$1
}, {
name: "a_positionEnd",
size: 2,
type: FLOAT$1
}, {
name: "a_normal",
size: 2,
type: FLOAT$1
}, {
name: "a_color",
size: 4,
type: UNSIGNED_BYTE$1,
normalized: true
}, {
name: "a_id",
size: 4,
type: UNSIGNED_BYTE$1,
normalized: true
}, {
name: "a_radius",
size: 1,
type: FLOAT$1
}],
CONSTANT_ATTRIBUTES: [
// If 0, then position will be a_positionStart
// If 1, then position will be a_positionEnd
{
name: "a_positionCoef",
size: 1,
type: FLOAT$1
}, {
name: "a_normalCoef",
size: 1,
type: FLOAT$1
}, {
name: "a_radiusCoef",
size: 1,
type: FLOAT$1
}],
CONSTANT_DATA: [[0, 1, 0], [0, -1, 0], [1, 1, 1], [1, 1, 1], [0, -1, 0], [1, -1, -1]]
};
}
}, {
key: "processVisibleItem",
value: function processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) {
var thickness = data.size || 1;
var x1 = sourceData.x;
var y1 = sourceData.y;
var x2 = targetData.x;
var y2 = targetData.y;
var color = colors.floatColor(data.color);
// Computing normals
var dx = x2 - x1;
var dy = y2 - y1;
var radius = targetData.size || 1;
var len = dx * dx + dy * dy;
var n1 = 0;
var n2 = 0;
if (len) {
len = 1 / Math.sqrt(len);
n1 = -dy * len * thickness;
n2 = dx * len * thickness;
}
var array = this.array;
array[startIndex++] = x1;
array[startIndex++] = y1;
array[startIndex++] = x2;
array[startIndex++] = y2;
array[startIndex++] = n1;
array[startIndex++] = n2;
array[startIndex++] = color;
array[startIndex++] = edgeIndex;
array[startIndex++] = radius;
}
}, {
key: "setUniforms",
value: function setUniforms(params, _ref) {
var gl = _ref.gl,
uniformLocations = _ref.uniformLocations;
var u_matrix = uniformLocations.u_matrix,
u_zoomRatio = uniformLocations.u_zoomRatio,
u_feather = uniformLocations.u_feather,
u_pixelRatio = uniformLocations.u_pixelRatio,
u_correctionRatio = uniformLocations.u_correctionRatio,
u_sizeRatio = uniformLocations.u_sizeRatio,
u_minEdgeThickness = uniformLocations.u_minEdgeThickness,
u_lengthToThicknessRatio = uniformLocations.u_lengthToThicknessRatio;
gl.uniformMatrix3fv(u_matrix, false, params.matrix);
gl.uniform1f(u_zoomRatio, params.zoomRatio);
gl.uniform1f(u_sizeRatio, params.sizeRatio);
gl.uniform1f(u_correctionRatio, params.correctionRatio);
gl.uniform1f(u_pixelRatio, params.pixelRatio);
gl.uniform1f(u_feather, params.antiAliasingFeather);
gl.uniform1f(u_minEdgeThickness, params.minEdgeThickness);
gl.uniform1f(u_lengthToThicknessRatio, options.lengthToThicknessRatio);
}
}]);
}(EdgeProgram);
}
var EdgeClampedProgram = createEdgeClampedProgram();
var EdgeClampedProgram$1 = EdgeClampedProgram;
function createEdgeArrowProgram(inputOptions) {
return createEdgeCompoundProgram([createEdgeClampedProgram(inputOptions), createEdgeArrowHeadProgram(inputOptions)]);
}
var EdgeArrowProgram = createEdgeArrowProgram();
var EdgeArrowProgram$1 = EdgeArrowProgram;
// language=GLSL
var SHADER_SOURCE = /*glsl*/"\nattribute vec4 a_id;\nattribute vec4 a_color;\nattribute vec2 a_normal;\nattribute float a_normalCoef;\nattribute vec2 a_positionStart;\nattribute vec2 a_positionEnd;\nattribute float a_positionCoef;\n\nuniform mat3 u_matrix;\nuniform float u_sizeRatio;\nuniform float u_zoomRatio;\nuniform float u_pixelRatio;\nuniform float u_correctionRatio;\nuniform float u_minEdgeThickness;\nuniform float u_feather;\n\nvarying vec4 v_color;\nvarying vec2 v_normal;\nvarying float v_thickness;\nvarying float v_feather;\n\nconst float bias = 255.0 / 254.0;\n\nvoid main() {\n float minThickness = u_minEdgeThickness;\n\n vec2 normal = a_normal * a_normalCoef;\n vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef;\n\n float normalLength = length(normal);\n vec2 unitNormal = normal / normalLength;\n\n // We require edges to be at least \"minThickness\" pixels thick *on screen*\n // (so we need to compensate the size ratio):\n float pixelsThickness = max(normalLength, minThickness * u_sizeRatio);\n\n // Then, we need to retrieve the normalized thickness of the edge in the WebGL\n // referential (in a ([0, 1], [0, 1]) space), using our \"magic\" correction\n // ratio:\n float webGLThickness = pixelsThickness * u_correctionRatio / u_sizeRatio;\n\n // Here is the proper position of the vertex\n gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness, 1)).xy, 0, 1);\n\n // For the fragment shader though, we need a thickness that takes the \"magic\"\n // correction ratio into account (as in webGLThickness), but so that the\n // antialiasing effect does not depend on the zoom level. So here's yet\n // another thickness version:\n v_thickness = webGLThickness / u_zoomRatio;\n\n v_normal = unitNormal;\n\n v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0;\n\n #ifdef PICKING_MODE\n // For picking mode, we use the ID as the color:\n v_color = a_id;\n #else\n // For normal mode, we use the color:\n v_color = a_color;\n #endif\n\n v_color.a *= bias;\n}\n";
var VERTEX_SHADER_SOURCE = SHADER_SOURCE;
var _WebGLRenderingContex = WebGLRenderingContext,
UNSIGNED_BYTE = _WebGLRenderingContex.UNSIGNED_BYTE,
FLOAT = _WebGLRenderingContex.FLOAT;
var UNIFORMS = ["u_matrix", "u_zoomRatio", "u_sizeRatio", "u_correctionRatio", "u_pixelRatio", "u_feather", "u_minEdgeThickness"];
var EdgeRectangleProgram = /*#__PURE__*/function (_EdgeProgram) {
function EdgeRectangleProgram() {
inherits._classCallCheck(this, EdgeRectangleProgram);
return inherits._callSuper(this, EdgeRectangleProgram, arguments);
}
inherits._inherits(EdgeRectangleProgram, _EdgeProgram);
return inherits._createClass(EdgeRectangleProgram, [{
key: "getDefinition",
value: function getDefinition() {
return {
VERTICES: 6,
VERTEX_SHADER_SOURCE: VERTEX_SHADER_SOURCE,
FRAGMENT_SHADER_SOURCE: FRAGMENT_SHADER_SOURCE,
METHOD: WebGLRenderingContext.TRIANGLES,
UNIFORMS: UNIFORMS,
ATTRIBUTES: [{
name: "a_positionStart",
size: 2,
type: FLOAT
}, {
name: "a_positionEnd",
size: 2,
type: FLOAT
}, {
name: "a_normal",
size: 2,
type: FLOAT
}, {
name: "a_color",
size: 4,
type: UNSIGNED_BYTE,
normalized: true
}, {
name: "a_id",
size: 4,
type: UNSIGNED_BYTE,
normalized: true
}],
CONSTANT_ATTRIBUTES: [
// If 0, then position will be a_positionStart
// If 2, then position will be a_positionEnd
{
name: "a_positionCoef",
size: 1,
type: FLOAT
}, {
name: "a_normalCoef",
size: 1,
type: FLOAT
}],
CONSTANT_DATA: [[0, 1], [0, -1], [1, 1], [1, 1], [0, -1], [1, -1]]
};
}
}, {
key: "processVisibleItem",
value: function processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) {
var thickness = data.size || 1;
var x1 = sourceData.x;
var y1 = sourceData.y;
var x2 = targetData.x;
var y2 = targetData.y;
var color = colors.floatColor(data.color);
// Computing normals
var dx = x2 - x1;
var dy = y2 - y1;
var len = dx * dx + dy * dy;
var n1 = 0;
var n2 = 0;
if (len) {
len = 1 / Math.sqrt(len);
n1 = -dy * len * thickness;
n2 = dx * len * thickness;
}
var array = this.array;
array[startIndex++] = x1;
array[startIndex++] = y1;
array[startIndex++] = x2;
array[startIndex++] = y2;
array[startIndex++] = n1;
array[startIndex++] = n2;
array[startIndex++] = color;
array[startIndex++] = edgeIndex;
}
}, {
key: "setUniforms",
value: function setUniforms(params, _ref) {
var gl = _ref.gl,
uniformLocations = _ref.uniformLocations;
var u_matrix = unifor