@d3fc/d3fc-webgl

A collection of utilities to enable drawing to WebGL canvases

Usage no npm install needed!

<script type="module">
  import d3fcD3fcWebgl from 'https://cdn.skypack.dev/@d3fc/d3fc-webgl';
</script>

README

d3fc-webgl

A collection of very low-level components for rendering with WebGL. See other packages (e.g. d3fc-series) for higher-level components which make use of these low-level components.

Main D3FC package

Installing

npm install @d3fc/d3fc-webgl

API Reference

This package contains the components needed to render a standard or custom series types with WebGL.

Series

If this is your first time using WebGL, this collection of very low-level components is not the best place to start. See other packages (e.g. d3fc-series) for higher-level components which make use of these low-level components.

The series share a common API with a typical configuration requiring x and y WebGL scales together with a number of attribute buffers.

Some of the series make use of next/previous attributes. These are needed in situations where the current element requires information about adjacent elements in order to be drawn correctly. For example when drawing a line we need to know information about adjacent data points so that we can draw the connection between them correctly.

Currently only the line and point series are able to render different orientations (horizontal and vertical), all other charts render as a vertical chart.

Common Properties

A few properties are shared across all of the series.

# series.xScale(scale) # series.yScale(scale)

If scale is specified, sets the scale and returns this series. If scale is not specified, returns the current scale.

N.B. scales are Webgl scales not D3 scales. These can be created manually or generated from D3 scales using the webglScaleMapper.

# series.decorate(decorateFunc)

If decorateFunc is specified, sets decorate to the given function and returns this series. If decorateFunc is not specified, returns the current decorate function.

The function is called immediately prior to the underlying WebGL calls. It is passed a single argument which is an instance of webglProgramBuilder. This allows users of the components to modify the shaders, as well as change or pass in additional attribute/uniform values.

# series.context(WebGLRenderingContext)

If WebGLRenderingContext is specified, sets the rendering context and returns this series. If WebGLRenderingContext is not specified, returns the current rendering context.

This property is rebound from webglProgramBuilder.context.

# series.definedAttribute(attribute)

If attribute is specified, sets the defined attribute and returns this series. If attribute is not specified, returns the current defined attribute.

The attribute values should either be 1 (to indicate the data point is defined) or 0 (to indicate the data point is not defined).

Area

# fc.webglSeriesArea()

Used to construct a new WebGL Area series.

# webglSeriesArea.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesArea.crossNextValueAttribute(attribute)

If attribute is specified, sets the cross next value attribute and returns this series. If attribute is not specified, returns the current cross next value attribute.

# webglSeriesArea.mainValueAttribute(attribute)

If attribute is specified, sets the main value attribute and returns this series. If attribute is not specified, returns the current main value attribute.

# webglSeriesArea.mainNextValueAttribute(attribute)

If attribute is specified, sets the main next value attribute and returns this series. If attribute is not specified, returns the current main next value attribute.

# webglSeriesArea.baseValueAttribute(attribute)

If attribute is specified, sets the base value attribute and returns this series. If attribute is not specified, returns the current base value attribute.

# webglSeriesArea.baseNextValueAttribute(attribute)

If attribute is specified, sets the base next value attribute and returns this series. If attribute is not specified, returns the current base next value attribute.

# webglSeriesArea.definedNextAttribute(attribute)

If attribute is specified, sets the defined next attribute and returns this series. If attribute is not specified, returns the current defined next attribute.

The attribute values should either be 1 (to indicate the data point is defined) or 0 (to indicate the data point is not defined).

Bar

# fc.webglSeriesBar()

Used to construct a new WebGL Bar series.

# webglSeriesBar.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesBar.mainValueAttribute(attribute)

If attribute is specified, sets the main value attribute and returns this series. If attribute is not specified, returns the current main value attribute.

# webglSeriesBar.baseValueAttribute(attribute)

If attribute is specified, sets the base value attribute and returns this series. If attribute is not specified, returns the current base value attribute.

# webglSeriesBar.bandwidthAttribute(attribute)

If attribute is specified, sets the bandwidth attribute and returns this series. If attribute is not specified, returns the current bandwidth attribute.

The attribute values should be provided in pixels.

BoxPlot

# fc.webglSeriesBoxPlot()

Used to construct a new WebGL BoxPlot series

# webglSeriesBoxPlot.lineWidth(width)

If width is specified, sets the width to the given value and returns this series. If width is not specified, returns the current width value.

The value should be provided in pixels.

# webglSeriesBoxPlot.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesBoxPlot.highValueAttribute(attribute)

If attribute is specified, sets the high value attribute and returns this series. If attribute is not specified, returns the current high value attribute.

# webglSeriesBoxPlot.upperQuartileValueAttribute(attribute)

If attribute is specified, sets the upper quartile value attribute and returns this series. If attribute is not specified, returns the current upper quartile value attribute.

# webglSeriesBoxPlot.medianValueAttribute(attribute)

If attribute is specified, sets the median value attribute and returns this series. If attribute is not specified, returns the current median value attribute.

# webglSeriesBoxPlot.lowerQuartileValueAttribute(attribute)

If attribute is specified, sets the lower quartile value attribute and returns this series. If attribute is not specified, returns the current lower quartile value attribute.

# webglSeriesBoxPlot.lowValueAttribute(attribute)

If attribute is specified, sets the low value attribute and returns this series. If attribute is not specified, returns the current low value attribute.

# webglSeriesBoxPlot.bandwidthAttribute(attribute)

If attribute is specified, sets the bandwidth attribute and returns this series. If attribute is not specified, returns the current bandwidth attribute.

The attribute values should be provided in pixels.

# webglSeriesBoxPlot.capAttribute(attribute)

If attribute is specified, sets the cap attribute and returns this series. If attribute is not specified, returns the current cap attribute.

The attribute values should be provided in pixels.

Candlestick

# fc.webglSeriesCandlestick()

Used to construct a new WebGL Candlestick series.

# webglSeriesCandlestick.lineWidth(width)

If width is specified, sets the width to the given value and returns this series. If width is not specified, returns the current width value.

The value should be provided in pixels.

# webglSeriesCandlestick.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesCandlestick.openValueAttribute(attribute)

If attribute is specified, sets the open value attribute and returns this series. If attribute is not specified, returns the current open value attribute.

# webglSeriesCandlestick.highValueAttribute(attribute)

If attribute is specified, sets the high value attribute and returns this series. If attribute is not specified, returns the current high value attribute.

# webglSeriesCandlestick.lowValueAttribute(attribute)

If attribute is specified, sets the low value attribute and returns this series. If attribute is not specified, returns the current low value attribute.

# webglSeriesCandlestick.closeValueAttribute(attribute)

If attribute is specified, sets the close value attribute and returns this series. If attribute is not specified, returns the current close value attribute.

# webglSeriesCandlestick.bandwidthAttribute(attribute)

If attribute is specified, sets the bandwidth attribute and returns this series. If attribute is not specified, returns the current bandwidth attribute.

The attribute values should be provided in pixels.

ErrorBar

# fc.webglSeriesErrorBar()

Used to construct a new WebGL ErrorBar series.

# webglSeriesErrorBar.lineWidth(width)

If width is specified, sets the width to the given value and returns this series. If width is not specified, returns the current width value.

The value should be provided in pixels.

# webglSeriesErrorBar.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesErrorBar.highValueAttribute(attribute)

If attribute is specified, sets the high value attribute and returns this series. If attribute is not specified, returns the current high value attribute.

# webglSeriesErrorBar.lowValueAttribute(attribute)

If attribute is specified, sets the low value attribute and returns this series. If attribute is not specified, returns the current low value attribute.

# webglSeriesErrorBar.bandwidthAttribute(attribute)

If attribute is specified, sets the bandwidth attribute and returns this series. If attribute is not specified, returns the current bandwidth attribute.

The attribute values should be provided in pixels.

Line

# fc.webglSeriesLine()

Used to construct a new WebGL Line series.

# webglSeriesLine.lineWidth(width)

If width is specified, sets the width to the given value and returns this series. If width is not specified, returns the current width value.

The value should be provided in pixels.

# webglSeriesLine.crossPreviousValueAttribute(attribute)

If attribute is specified, sets the cross previous value attribute and returns this series. If attribute is not specified, returns the current cross previous value attribute.

# webglSeriesLine.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesLine.crossNextValueAttribute(attribute)

If attribute is specified, sets the cross next value attribute and returns this series. If attribute is not specified, returns the current cross next value attribute.

# webglSeriesLine.crossNextNextValueAttribute(attribute)

If attribute is specified, sets the cross next next value attribute and returns this series. If attribute is not specified, returns the current cross next next value attribute.

# webglSeriesLine.mainPreviousValueAttribute(attribute)

If attribute is specified, sets the main previous value attribute and returns this series. If attribute is not specified, returns the current main previous value attribute.

# webglSeriesLine.mainValueAttribute(attribute)

If attribute is specified, sets the main value attribute and returns this series. If attribute is not specified, returns the current main value attribute.

# webglSeriesLine.mainNextValueAttribute(attribute)

If attribute is specified, sets the main next value attribute and returns this series. If attribute is not specified, returns the current main next value attribute.

# webglSeriesLine.mainNextNextValueAttribute(attribute)

If attribute is specified, sets the main next next value attribute and returns this series. If attribute is not specified, returns the current main next next value attribute.

# webglSeriesLine.definedNextAttribute(attribute)

If attribute is specified, sets the defined next attribute and returns this series. If attribute is not specified, returns the current defined next attribute.

The attribute values should either be 1 (to indicate the data point is defined) or 0 (to indicate the data point is not defined).

Ohlc

# fc.webglSeriesOhlc()

Used to construct a new WebGL Ohlc series.

# webglSeriesOhlc.lineWidth(width)

If width is specified, sets the width to the given value and returns this series. If width is not specified, returns the current width value.

The value should be provided in pixels.

# webglSeriesOhlc.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesOhlc.openValueAttribute(attribute)

If attribute is specified, sets the open value attribute and returns this series. If attribute is not specified, returns the current open value attribute.

# webglSeriesOhlc.highValueAttribute(attribute)

If attribute is specified, sets the high value attribute and returns this series. If attribute is not specified, returns the current high value attribute.

# webglSeriesOhlc.lowValueAttribute(attribute)

If attribute is specified, sets the low value attribute and returns this series. If attribute is not specified, returns the current low value attribute.

# webglSeriesOhlc.closeValueAttribute(attribute)

If attribute is specified, sets the close value attribute and returns this series. If attribute is not specified, returns the current close value attribute.

# webglSeriesOhlc.bandwidthAttribute(attribute)

If attribute is specified, sets the bandwidth attribute and returns this series. If attribute is not specified, returns the current bandwidth attribute.

The attribute values should be provided in pixels.

Point

# fc.webglSeriesPoint()

Used to construct a new WebGL Point series.

# webglSeriesPoint.type(symbolTypeShader)

If symbolTypeShader is specified, sets the symbol type shader and returns this series. If symbolTypeShader is not specified, returns the current symbol type shader.

A symbolTypeShader can be generated using the webglSymbolMapper.

# webglSeriesPoint.crossValueAttribute(attribute)

If attribute is specified, sets the cross value attribute and returns this series. If attribute is not specified, returns the current cross value attribute.

# webglSeriesPoint.mainValueAttribute(attribute)

If attribute is specified, sets the main value attribute and returns this series. If attribute is not specified, returns the current main value attribute.

# webglSeriesPoint.sizeAttribute(attribute)

If attribute is specified, sets the size attribute and returns this series. If attribute is not specified, returns the current size attribute.

The attribute values should be provided as pixel areas.

Buffers

The buffer components can be used for creating and modifying WebGL buffers. These are used to pass values into attributes and uniforms so that they can be accessed in a shader.

The types file is also available for managing the typing of values being passed into the WebGL pipeline.

Attribute Buffer Builders

The attribute components can be used to generate WebGLBuffers and bind them to the context of a given webglProgramBuilder. A number of different builders are available to accomodate the most common use cases.

Example use of the builders can be seen in the series components where the builders are used to provide the attribute values.

Attribute

# fc.webglAttribute()

Used to generate a buffer containing values for the shaders.

# webglAttribute.normalized(boolean)

If boolean is specified, sets the normalized property and returns this attribute builder. If boolean is not specified, returns the current value of normalized.

The normalized property specifies whether integer data values should be normalized when being cast to a float, the default value is false.

More information on how values are normalized can be found here.

# webglAttribute.location(index)

If index is specified, sets the location property and returns this attribute builder. If index is not specified, returns the current value of location.

The location property is used to specify the index of the vertex attribute being modified. The appropriate value for an attribute can be found using WebGLRenderingContext.getAttribLocation(). This is normally specified on your behalf by bufferBuilder.

# webglAttribute.data(array)

If array is specified, sets the data property and returns this attribute builder. If array is not specified, returns the current value of data.

The data property is used to allow the value function to run for each entry in the data set.

# webglAttribute.value(valueFunc)

If valueFunc is specified, sets the value property to the given function and returns this attribute builder. If valueFunc is not specified, returns the current value function.

The value function is run for each entry in the data set, receiving the current data point and its index as arguments, valueFunc(data, index).

If the size property is set to 1, then valueFunc must return a single value. If the size property is set to a value other than 1 then valueFunc must return an array of length equal to the size property.

# webglAttribute.size(size)

If size is specified, sets the size property and returns this attribute builder. If size is not specified, returns the current value of size.

The size property is used to specify the number of components to the attribute. It must have the value 1 (default), 2, 3, or 4, corresponding to the shader types float, vec2, vec3, and vec4 respectively.

# webglAttribute.type(type)

If type is specified, sets the type property and returns this attribute builder. If type is not specified, returns the current type.

The type property is used to specify the type of the typed array used for the buffer data. Valid types can be accessed from webglTypes.

# webglAttribute.clear()

Used to indicate that the buffer should be rebuilt on the next render, by default the buffer will only be rebuilt if a property on the builder changes.

# webglAttribute.divisor(divisor)

If divisor is specified, sets the divisor property and returns this attribute builder. If divisor is not specified, returns the current divisor.

The divisor property is used to specify the rate (the number of instances) at which the attribute advances. A divisor of 0 would be used to repeat the same set of values for each set of vertices making up each instance e.g. vertex[0][0] = a, vertex[0][1] = b, vertex[1][0] = a, vertex[1][1] = b, vertex[2][0] = a, vertex[2][1] = b. A divisor of 1 would be used to pass a value per set of vertices making up each instance e.g. vertex[0][0] = a, vertex[0][1] = a, vertex[1][0] = b, vertex[1][1] = b, vertex[2][0] = c, vertex[2][1] = c.

By default this value is null which causes the value to depend upon whether instanced rendering is enabled, see subInstanceCount. If it is enabled, the divisor will have the value 1 otherwise it will be 0.

Adjacent Element Attribute

# fc.webglAdjacentAttribute(minOffset, maxOffset)

Used to generate a buffer where each element requires data from another element adjacent to it. In this context an element is an instance of a repeatedly drawn object, for example each individual candlestick on a candlestick chart is an element.

minOffset specifies the minimum bound for the offset property, this controls how many previous elements are available to access from the builder. The default value is 0. maxOffset specifies the maximum bound for the offset property, this controls how many following elements are available to access from the builder. The default value is 0.

# webglAdjacentAttribute.offset(offset)

Sets the offset property and returns an attribute builder that accesses the same data with the given offset.

The value of offset must be within the bounds of minOffset and maxOffset.

# webglAdjacentAttribute.normalized(boolean)

If boolean is specified, sets the normalized property and returns this attribute builder. If boolean is not specified, returns the current value of normalized.

The normalized property specifies whether integer data values should be normalized when being cast to a float, the default value is false.

More information on how values are normalized can be found here.

# webglAdjacentAttribute.location(index)

If index is specified, sets the location property and returns this attribute builder. If index is not specified, returns the current value of location.

The location property is used to specify the index of the vertex attribute being modified. The appropriate value for an attribute can be found using WebGLRenderingContext.getAttribLocation(). This is normally specified on your behalf by bufferBuilder.

# webglAdjacentAttribute.data(array)

If array is specified, sets the data property and returns this attribute builder. If array is not specified, returns the current value of data.

The data property is used to allow the value function to run for each entry in the data set.

# webglAdjacentAttribute.value(valueFunc)

If valueFunc is specified, sets the value property to the given function and returns this attribute builder. If valueFunc is not specified, returns the current value function.

The value function is run for each entry in the data set, receiving the current data point and its index as arguments, valueFunc(data, index).

If the size property is set to 1, then valueFunc must return a single value. If the size property is set to a value other than 1 then valueFunc must return an array of length equal to the size property.

# webglAdjacentAttribute.size(size)

If size is specified, sets the size property and returns this attribute builder. If size is not specified, returns the current value of size.

The size property is used to specify the number of components to the attribute. It must have the value 1 (default), 2, 3, or 4, corresponding to the shader types float, vec2, vec3, and vec4 respectively.

# webglAdjacentAttribute.type(type)

If type is specified, sets the type property and returns this attribute builder. If type is not specified, returns the current type.

The type property is used to specify the type of the typed array used for the buffer data, the default is Float. Valid types can be accessed from webglTypes.

# webglAdjacentAttribute.clear()

Used to indicate that the buffer should be rebuilt on the next render, by default the buffer will only be rebuilt if a property on the builder changes.

# webglAdjacentAttribute.divisor(divisor)

If divisor is specified, sets the divisor property and returns this attribute builder. If divisor is not specified, returns the current divisor.

The divisor property is used to specify the rate (the number of instances) at which the attribute advances. A divisor of 0 would be used to repeat the same set of values for each set of vertices making up each instance e.g. vertex[0][0] = a, vertex[0][1] = b, vertex[1][0] = a, vertex[1][1] = b, vertex[2][0] = a, vertex[2][1] = b. A divisor of 1 would be used to pass a value per set of vertices making up each instance e.g. vertex[0][0] = a, vertex[0][1] = a, vertex[1][0] = b, vertex[1][1] = b, vertex[2][0] = c, vertex[2][1] = c.

By default this value is null which causes the value to depend upon whether instanced rendering is enabled, see subInstanceCount. If it is enabled, the divisor will have the value 1 otherwise it will be 0.

Base Attribute

# fc.webglBaseAttribute()

The generic base attribute builder that all the other attribute builders inherit from to provide their functionality. This will bind a buffer to a generic vertex attribute, accessed at location, but is not responsible for binding data to the buffer.

This component can be used to create a custom attribute builder, or to simply bind a buffer to a vertex attribute so that data can be provided.

# webglBaseAttribute.buffer(WebGLBuffer)

If WebGLBuffer is specified, sets the buffer property and returns this attribute builder. If WebGLBuffer is not specified, returns the current buffer.

This property does not need to be set as the component will create a buffer if necessary, a buffer can be manually created using WebGLRenderingContext.createBuffer().

# webglBaseAttribute.location(index)

If index is specified, sets the location property and returns this attribute builder. If index is not specified, returns the current value of location.

The location property is used to specify the index of the vertex attribute being modified. The appropriate value for an attribute can be found using WebGLRenderingContext.getAttribLocation(). This is normally specified on your behalf by bufferBuilder.

# webglBaseAttribute.size(size)

If size is specified, sets the size property and returns this attribute builder. If size is not specified, returns the current value of size.

The size property is used to specify the number of components to the attribute. It must have the value 1 (default), 2, 3, or 4, corresponding to the shader types float, vec2, vec3, and vec4 respectively.

# webglBaseAttribute.type(type)

If type is specified, sets the type property and returns this attribute builder. If type is not specified, returns the current type.

The type property is used to specify the type of the typed array used for the buffer data. Valid types can be accessed from webglTypes.

# webglBaseAttribute.normalized(boolean)

If boolean is specified, sets the normalized property and returns this attribute builder. If boolean is not specified, returns the current value of normalized.

The normalized property specifies whether integer data values should be normalized when being cast to a float, the default value is false.

More information on how values are normalized can be found here.

# webglBaseAttribute.stride(stride)

If stride is specified, sets the stride property and returns this attribute builder. If stride is not specified, returns the current stride.

The stride property is used to specify the offset in bytes between the start of consecutive vertex attribute values, it must be a value from 0 (default) to 255. By using the stride property it is possible to create a buffer of interleaved attribute values.

# webglBaseAttribute.offset(offset)

If offset is specified, sets the offset property and returns this attribute builder. If offset is not specified, returns the current offset.

The offset property is used to specify the offset in bytes of the first value in the vertex attribute array. If set, the offset must be a multiple of the byte length of type.

# webglBaseAttribute.divisor(divisor)

If divisor is specified, sets the divisor property and returns this attribute builder. If divisor is not specified, returns the current divisor.

The divisor property is used to specify the rate (the number of instances) at which the attribute advances. A divisor of 0 would be used to repeat the same set of values for each set of vertices making up each instance e.g. vertex[0][0] = a, vertex[0][1] = b, vertex[1][0] = a, vertex[1][1] = b, vertex[2][0] = a, vertex[2][1] = b. A divisor of 1 would be used to pass a value per set of vertices making up each instance e.g. vertex[0][0] = a, vertex[0][1] = a, vertex[1][0] = b, vertex[1][1] = b, vertex[2][0] = c, vertex[2][1] = c.

By default this value is null which causes the value to depend upon whether instanced rendering is enabled, see subInstanceCount. If it is enabled, the divisor will have the value 1 otherwise it will be 0.

Uniform Builder

# fc.webglUniform()

Used to create a single value that is provided to every vertex.

# webglUniform.location(index)

If index is specified, sets the location property and returns this uniform builder. If index is not specified, returns the current location.

The location property is used to specify the index location of the uniform being modified. The appropriate value can be found using WebGLRenderingContext.getUniformLocation(). This is normally specified on your behalf by bufferBuilder.

# webglUniform.data(data)

If data is specified, sets the data property and returns this uniform builder. If data is not specified, returns the current data.

The data property is used to set the value of the uniform, the value provided can either be a single value or an array with a maximum length of 4.

# webglUniform.clear()

Used to indicate that the buffer should be rebuilt on the next render, by default the buffer will only be rebuilt if a property on the builder changes.

Buffer Builder

# fc.webglBufferBuilder()

This component manages the mapping of attribute/uniform builders to their shader identifiers.

# webglBufferBuilder.flush()

Used to ensure that all attributes and uniforms associated with the builder are rebuilt on the next render. This is equivalent to calling the clear function for all associated attributes and uniforms.

# webglBufferBuilder.attribute(attributeName, attribute)

If attribute is specified, assigns the attribute for the specified attributeName and returns this builder. If attribute is not specified, returns the attribute to attributeName.

# webglBufferBuilder.uniform(uniformName, uniform)

If uniform is specified, assigns the uniform for the specified uniformName and returns this builder. If uniform is not specified, returns the uniform to uniformName.

# webglBufferBuilder.elementIndices(elementIndices)

If elementIndices is specified, sets element indices and returns this builder. If elementIndices is not specified, returns the current element indices.

If this value is null then array-based rendering will be used. Otherwise, element-based rendering will be used see webglElementIndices.

Element Indices

# fc.webglElementIndices()

Used to create an element array buffer. This allows vertices to be defined once and reused by providing an index specifying which vertex we are currently using.

For example to draw two triangles that share a vertex we could provide the values [0, 1, 2, 1, 3, 4]. Here we will draw a triangle with the vertices 0, 1, and 2, and a second triangle with the vertices 1, 3, and 4. We only have to specify the data for 5 vertices as we are reusing vertex 1.

# webglElementIndices.data(data)

If data is specified, sets data and returns this builder. If data is not specified, returns the current data.

data should be an array containing an ordered list of the vertices to draw.

# webglElementIndices.clear()

Used to indicate that the buffer should be rebuilt on the next render, by default the buffer will only be rebuilt if a property on the builder changes.

Types

# fc.webglTypes

An enum used to access the WebGL values associated with different data types.

Scales

The scale components can be used for applying a scaling and translation to a variable within the vertex shader. This is useful for converting values from a data range to screen space.

Any vector variables can have a scaling applied to them.

Please note that the Log and Pow scales do not behave correctly for all base and exponent values respectively, this issue can be tracked here.

Linear

# fc.webglScaleLinear()

Used to apply a linear scaling and translation to variables.

# webglScaleLinear.domain(domain)

If domain is specified, sets the domain and returns this scale. If domain is not specified, returns the current domain.

domain should be an array containing the lower and upper bounds for the data set to be scaled.

# webglScaleLinear.range(range)

If range is specified, sets the range and returns this scale. If range is not specified, returns the current range.

range should be an array containing the lower and upper bounds for the drawing area, given in draw space coordinates. Defaults to [-1, 1], the full canvas.

Log

# fc.webglScaleLog()

Used to apply a logarithmic scaling and translation to variables.

# webglScaleLog.base(base)

If base is specified, sets the base and returns this scale. If base is not specified, returns the current base.

The value provided is used as the logarithm base.

# webglScaleLog.domain(domain)

If domain is specified, sets the domain and returns this scale. If domain is not specified, returns the current domain.

domain should be an array containing the lower and upper bounds for the data set to be scaled.

# webglScaleLog.range(range)

If range is specified, sets the range and returns this scale. If range is not specified, returns the current range.

range should be an array containing the lower and upper bounds for the drawing area, given in draw space coordinates. Defaults to [-1, 1], the full canvas.

Pow

# fc.webglScalePow()

Used to apply an exponential scaling and translation to variables.

# webglScalePow.exponent(exponent)

If exponent is specified, sets the exponent and returns this scale. If exponent is not specified, returns the current exponent.

The value provided is used as the exponent.

# webglScalePow.domain(domain)

If domain is specified, sets the domain and returns this scale. If domain is not specified, returns the current domain.

domain should be an array containing the lower and upper bounds for the data set to be scaled.

# webglScalePow.range(range)

If range is specified, sets the range and returns this scale. If range is not specified, returns the current range.

range should be an array containing the lower and upper bounds for the drawing area, given in draw space coordinates. Defaults to [-1, 1], the full canvas.

Scale Mapper

# fc.webglScaleMapper(scale)

Used to map a D3 Scale (scale) to a matched pair of JavaScript and WebGL scales with appropriate properties (e.g. domain) copied over. Returns an object containing two fields, scale, and webglScale.

The JavaScript scale is guaranteed to be a pure function if the returned reference is equal to a previously returned reference.

As there is no reliable way to test for the type of a scale, this implementation is naive and may return non-optimal mappings.

Shader Builder

# fc.webglShaderBuilder(base)

Used to allow shaders to be built in parts, this can be useful for allowing optional lines of shader code to be added. For example, given a condition, a line can be appended to a shader to change the output color.

base must be a function that accepts two arguments, a header for the shader and a body for the shader. It must return a string that contains the header and a main function surrounding the body.

An example of a base could be:

const base = (header, body) => `
  precision mediump float;
  ${header}
  void main() {
    ${body}
  }
`;

# webglShaderBuilder.appendHeader(header)

Appends header to the end of the current headers.

header must be a string containing GLSL code.

# webglShaderBuilder.insertHeader(header, before)

Inserts header before the line provided in the before argument.

header must be a string containing GLSL code. before must be a string containing GLSL code already in the current headers. If before does not match any existing headers then header will be appended to the end of the current headers.

# webglShaderBuilder.appendHeaderIfNotExists(header)

Appends header to the end of the current headers as long as it does not already exist.

header must be a string containing GLSL code.

# webglShaderBuilder.appendBody(body)

Appends body to the end of the current bodies.

body must be a string containing GLSL code.

# webglShaderBuilder.insertBody(body, before)

Inserts body before the line provided in the before argument.

body must be a string containing GLSL code. before must be a string containing GLSL code already in the current bodies. If before does not match any existing bodies then body will be appended to the end of the current bodies.

# webglShaderBuilder.appendBodyIfNotExists(body)

Appends body to the end of the current bodies as long as it does not already exist.

body must be a string containing GLSL code.

Shader Naming Convention

The naming convention for shader inputs follows the convention found on the series-api page in the web docs.

One key difference is that shader inputs should be written in camelCase and have a qualifier prefix.

Shader inputs can have one of three qualifiers. Each qualifier has a corresponding prefix.

Qualifier Prefix
Attribute a
Uniform u
Varying v

For example: aCrossValue

Program Builder

# fc.webglProgramBuilder()

This component manages the creation and execution of a WebGLProgram. No underlying WebGL methods are invoked until the program builder itself is invoked.

# webglProgramBuilder.extInstancedArrays()

Returns a reference to the ANGLE_instanced_arrays WebGL extension used for drawing to the canvas.

This reference should be used, rather than components obtaining their own, to prevent errors if the context is lost.

# webglProgramBuilder.context(context)

If context is specified, sets the context and returns this builder. If context is not specified, returns the current context.

context must be an instance of WebGLRenderingContext from the canvas to be drawn to. context can also be set to null if the context has been lost, see Handling Lost Context for more information.

# webglProgramBuilder.buffers(bufferBuilder)

If bufferBuilder is specified, sets the buffers and returns this builder. If bufferBuilder is not specified, returns the current buffers.

bufferBuilder must be an instance of webglBufferBuilder

# webglProgramBuilder.vertexShader(shaderBuilder)

If shaderBuilder is specified, sets the vertex shader and returns this builder. If shaderBuilder is not specified, returns the current vertex shader.

shaderBuilder must be an instance of webglShaderBuilder

# webglProgramBuilder.fragmentShader(shaderBuilder)

If shaderBuilder is specified, sets the fragment shader and returns this builder. If shaderBuilder is not specified, returns the current fragment shader.

shaderBuilder must be an instance of webglShaderBuilder

# webglProgramBuilder.mode(mode)

If mode is specified, sets the mode and returns this builder. If mode is not specified, returns the current mode.

mode must be a WebGL draw mode, modes supported by webglProgramBuilder are WebGLRenderingContext.POINTS and WebGLRenderingContext.TRIANGLES.

# webglProgramBuilder.subInstanceCount(subInstanceCount)

If subInstanceCount is specified, sets the count of vertex count per instance and returns this builder. If subInstanceCount is not specified, returns the current value which default to 0.

A value of 0 disables instanced rendering, any other value enables instanced rendering. To control how instanced attribute behaviour see divisor.

# webglProgramBuilder.debug(debug)

If debug is specified, enables or disables additional verification checks and error logging. This is very useful when working with custom shaders or debugging INVALID_OPERATION messages. However, it should not be enabled in production as the checks severely impact rendering performance. If debug is not specified, returns the current debug setting.

Handling Lost Context

As the GPU is a shared resource it is possible for situations to arise where it is taken away from the program, this will result in a webglcontextlost event. If you are working with a Cartesian Chart then both the webglcontextlost and webglcontextrestored events are automatically handled for you. However if you are not working with a Cartesian Chart then you must handle these events yourself.

If the webglcontextlost event occurs then null should be passed to the context property of the component being used, for example program builder or series. This will invalidate the relevant resources associated with the lost context and block the rendering pipeline. If a subsequent webglcontextrestored event occurs then the new context can be passed to the component to recreate the needed resources and unblock the rendering pipeline.

Both the webglcontextlost and webglcontextrestored event listeners must be added to the canvas being used:

canvas.addEventListener('webglcontextlost', event => {
  event.preventDefault();
  component.context(null);
}, false);

canvas.addEventListener('webglcontextrestored', () => {
  component.context(canvas.getContext('webgl'));
  component();
}, false);

For more information on handling lost context you can view this guide.

Symbol Mapper

# fc.webglSymbolMapper(symbol)

Used to map a D3 symbol (symbol) to a shader used for drawing the equivalent symbol.

Supported symbols:

  • Circle
  • Square
  • Triangle
  • Cross

Fill Color

# fc.webglFillColor(color)

Used to set a fill color for the elements being drawn. If color is specified, it is used as the initial value.

# webglFillColor.value(value)

If value is specified, sets value and returns this component. If value is not specified, returns the current value.

Colors are specified as arrays containing four values representing rgba values given in the range 0 to 1 e.g. [1, 1, 0, 1] for yellow. To convert an arbitrary CSS color string into this format -

const webglColor = identifier => {
    const { r, g, b, opacity } = d3.color(identifier).rgb();
    return [r / 255, g / 255, b / 255, opacity];
};

The value can either be an array representing a constant value or a function which returns a color for every datum in data.

# webglFillColor.data(data)

If data is specified, sets the data and returns this component. If data is not specified, returns the current data.

The data property is used to allow the value function to run for each entry in the data set.

Stroke Color

# fc.webglStrokeColor(color)

Used to set a stroke color for the elements being drawn. If color is specified, it is used as the initial value.

# webglStrokeColor.value(value)

If value is specified, sets value and returns this component. If value is not specified, returns the current value.

Colors are specified as arrays containing four values representing rgba values given in the range 0 to 1 e.g. [1, 1, 0, 1] for yellow. To convert an arbitrary CSS color string into this format -

const webglColor = identifier => {
    const { r, g, b, opacity } = d3.color(identifier).rgb();
    return [r / 255, g / 255, b / 255, opacity];
};

The value can either be an array representing a constant value or a function which returns a color for every datum in data.

# webglStrokeColor.data(data)

If data is specified, sets the data and returns this component. If data is not specified, returns the current data.

The data property is used to allow the value function to run for each entry in the data set.