Languages
[Edit]
EN

JavaScript - color points based distribution model (heatmap color model)

6 points
Created by:
Zayyan-Todd
860

In this short article, we would like to show how in JavaScript, we create color points distribution model.

That model is built using middle color points that are used to compute middle points when needed.

e.g. it can be used to color 3D chart values.

Example color points distribution model visualization using JavaScript.
Example color points distribution model visualization using JavaScript.

Practical example:

// ONLINE-RUNNER:browser;

const findMultiple = (base, value) => {
    return base * Math.ceil(value / base);
};

const findStep = (space, count) => {
    return space / count;
};

const keepRange = (min, max, value) => {
    if (value < min) {
        return min;
    }
    if (value > max) {
        return max;
    }
    return value;
};
  
const createDenormalizer = (min, max, size) => {
    const range = max - min;
    return (versor) => {
        return min + versor * range;
    };
};

// Creates color points based distribution model that provides smooth color transition.
// Arguments:
//   points             indicates middle color points
//   resolution         indicates smooth transition quantization
// Result: retuns function that returns calculated RGB color for indicated versor (from 0 to 1)
//
const createPointsDistribution = (points, resolution) => {
    if (resolution < 1) {
        throw new Error('It is required to use positive resolution.');
    }
    const space = points.length - 1;
    if (space < 1) {
        throw new Error('It is required to provide at least 2 points.');
    }
    const count = findMultiple(space, resolution);
    const step = findStep(space, count);
    let p1 = points[0];
    let p2;
    const colors = new Array(count);
    for (let i = 1, k = 0; i < points.length; ++i) {
        p2 = points[i];
        const calculateRed = createDenormalizer(p1.red, p2.red);
        const calculateGreen = createDenormalizer(p1.green, p2.green);
        const calculateBlue = createDenormalizer(p1.blue, p2.blue);
        for (let t = 0; t < 1.0; t += step, k += 1) {
            colors[k] = {
                red: Math.round(calculateRed(t)),
                green: Math.round(calculateGreen(t)),
                blue: Math.round(calculateBlue(t))
            };
        }
        p1 = p2;
    }
    const limit = count - 1;
    return (versor) => {
        const value = Math.floor(versor * count);
        const index = keepRange(0, limit, value);
        return colors[index];
    };
};


// Helpers:

const drawPixel = (data, width, x, y, rgb) => {
    const roundedX = Math.round(x);
    const roundedY = Math.round(y);
    const index = 4 * (width * roundedY + roundedX);
    data[index + 0] = rgb.red;
    data[index + 1] = rgb.green;
    data[index + 2] = rgb.blue;
    data[index + 3] = 255;
};

const drawDistribution = (canvas, distribution) => {
    const context = canvas.getContext('2d');
    const image = context.createImageData(canvas.width, canvas.height);
    for (let y = 0; y < canvas.height; ++y) {
        for (let x = 0; x < canvas.width; ++x) {
            const versor = 1.0 - y / canvas.height;         // scales y value to versor value (from 0 to 1)
            const color = distribution.call(null, versor);  // returns pixel color
            drawPixel(image.data, canvas.width, x, y, color);
        }
    }
    context.putImageData(image, 0, 0);
};


// Usage example:

const points = [
    {red:  23, green:  23, blue: 230},
    {red:  23, green: 230, blue: 229},
    {red:  23, green: 230, blue:  27},
    {red: 229, green: 230, blue:  23},
    {red: 230, green:  23, blue:  23}
];

const distribution = createPointsDistribution(points, 200);

// To get pixel color just use:
//
//    const versor = 0.0;                             // versor should be from 0.0 to 1.0
//    const color = distribution.call(null, versor);  // color has RGB format

const canvas = document.createElement('canvas');

canvas.width = 50;
canvas.height = 400;

drawDistribution(canvas, distribution);

document.body.appendChild(canvas);

 

Example colors:

const points = [
    {red: 0x31, green: 0x36, blue: 0x95},
    {red: 0x45, green: 0x75, blue: 0xb4},
    {red: 0x74, green: 0xad, blue: 0xd1},
    {red: 0xab, green: 0xd9, blue: 0xe9},
    {red: 0xe0, green: 0xf3, blue: 0xf8},
    {red: 0xff, green: 0xff, blue: 0xbf},
    {red: 0xfe, green: 0xe0, blue: 0x90},
    {red: 0xfd, green: 0xae, blue: 0x61},
    {red: 0xf4, green: 0x6d, blue: 0x43},
    {red: 0xd7, green: 0x30, blue: 0x27},
    {red: 0xa5, green: 0x00, blue: 0x26}
];

Example: Surface Wave - Apache ECharts

const points = [
    {red:  23, green:  23, blue: 230},
    {red:  23, green: 230, blue: 229},
    {red:  23, green: 230, blue:  27},
    {red: 229, green: 230, blue:  23},
    {red: 230, green:  23, blue:  23}
];
const points = [
    {red:   0, green: 230, blue:  27},
    {red: 250, green:   0, blue:  23}
];

 

See also

  1. JavaScript - HSV distribution model (heatmap color model)

Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join