refactor
diff --git a/asterix-examples/src/main/resources/black-cherry/static/js/rainbowvis.js b/asterix-examples/src/main/resources/black-cherry/static/js/rainbowvis.js
new file mode 100644
index 0000000..1f444dc
--- /dev/null
+++ b/asterix-examples/src/main/resources/black-cherry/static/js/rainbowvis.js
@@ -0,0 +1,178 @@
+/*
+RainbowVis-JS
+Released under MIT License
+
+Source: https://github.com/anomal/RainbowVis-JS
+*/
+
+function Rainbow()
+{
+ var gradients = null;
+ var minNum = 0;
+ var maxNum = 100;
+ var colours = ['ff0000', 'ffff00', '00ff00', '0000ff'];
+ setColours(colours);
+
+ function setColours (spectrum)
+ {
+ if (spectrum.length < 2) {
+ throw new Error('Rainbow must have two or more colours.');
+ } else {
+ var increment = (maxNum - minNum)/(spectrum.length - 1);
+ var firstGradient = new ColourGradient();
+ firstGradient.setGradient(spectrum[0], spectrum[1]);
+ firstGradient.setNumberRange(minNum, minNum + increment);
+ gradients = [ firstGradient ];
+
+ for (var i = 1; i < spectrum.length - 1; i++) {
+ var colourGradient = new ColourGradient();
+ colourGradient.setGradient(spectrum[i], spectrum[i + 1]);
+ colourGradient.setNumberRange(minNum + increment * i, minNum + increment * (i + 1));
+ gradients[i] = colourGradient;
+ }
+
+ colours = spectrum;
+ return this;
+ }
+ }
+
+ this.setColors = this.setColours;
+
+ this.setSpectrum = function ()
+ {
+ setColours(arguments);
+ return this;
+ }
+
+ this.setSpectrumByArray = function (array)
+ {
+ setColours(array);
+ return this;
+ }
+
+ this.colourAt = function (number)
+ {
+ if (isNaN(number)) {
+ throw new TypeError(number + ' is not a number');
+ } else if (gradients.length === 1) {
+ return gradients[0].colourAt(number);
+ } else {
+ var segment = (maxNum - minNum)/(gradients.length);
+ var index = Math.min(Math.floor((Math.max(number, minNum) - minNum)/segment), gradients.length - 1);
+ return gradients[index].colourAt(number);
+ }
+ }
+
+ this.colorAt = this.colourAt;
+
+ this.setNumberRange = function (minNumber, maxNumber)
+ {
+ if (maxNumber > minNumber) {
+ minNum = minNumber;
+ maxNum = maxNumber;
+ setColours(colours);
+ } else {
+ throw new RangeError('maxNumber (' + maxNumber + ') is not greater than minNumber (' + minNumber + ')');
+ }
+ return this;
+ }
+}
+
+function ColourGradient()
+{
+ var startColour = 'ff0000';
+ var endColour = '0000ff';
+ var minNum = 0;
+ var maxNum = 100;
+
+ this.setGradient = function (colourStart, colourEnd)
+ {
+ startColour = getHexColour(colourStart);
+ endColour = getHexColour(colourEnd);
+ }
+
+ this.setNumberRange = function (minNumber, maxNumber)
+ {
+ if (maxNumber > minNumber) {
+ minNum = minNumber;
+ maxNum = maxNumber;
+ } else {
+ throw new RangeError('maxNumber (' + maxNumber + ') is not greater than minNumber (' + minNumber + ')');
+ }
+ }
+
+ this.colourAt = function (number)
+ {
+ return calcHex(number, startColour.substring(0,2), endColour.substring(0,2))
+ + calcHex(number, startColour.substring(2,4), endColour.substring(2,4))
+ + calcHex(number, startColour.substring(4,6), endColour.substring(4,6));
+ }
+
+ function calcHex(number, channelStart_Base16, channelEnd_Base16)
+ {
+ var num = number;
+ if (num < minNum) {
+ num = minNum;
+ }
+ if (num > maxNum) {
+ num = maxNum;
+ }
+ var numRange = maxNum - minNum;
+ var cStart_Base10 = parseInt(channelStart_Base16, 16);
+ var cEnd_Base10 = parseInt(channelEnd_Base16, 16);
+ var cPerUnit = (cEnd_Base10 - cStart_Base10)/numRange;
+ var c_Base10 = Math.round(cPerUnit * (num - minNum) + cStart_Base10);
+ return formatHex(c_Base10.toString(16));
+ }
+
+ formatHex = function (hex)
+ {
+ if (hex.length === 1) {
+ return '0' + hex;
+ } else {
+ return hex;
+ }
+ }
+
+ function isHexColour(string)
+ {
+ var regex = /^#?[0-9a-fA-F]{6}$/i;
+ return regex.test(string);
+ }
+
+ function getHexColour(string)
+ {
+ if (isHexColour(string)) {
+ return string.substring(string.length - 6, string.length);
+ } else {
+ var colourNames =
+ [
+ ['red', 'ff0000'],
+ ['lime', '00ff00'],
+ ['blue', '0000ff'],
+ ['yellow', 'ffff00'],
+ ['orange', 'ff8000'],
+ ['aqua', '00ffff'],
+ ['fuchsia', 'ff00ff'],
+ ['white', 'ffffff'],
+ ['black', '000000'],
+ ['gray', '808080'],
+ ['grey', '808080'],
+ ['silver', 'c0c0c0'],
+ ['maroon', '800000'],
+ ['olive', '808000'],
+ ['green', '008000'],
+ ['teal', '008080'],
+ ['navy', '000080'],
+ ['purple', '800080']
+ ];
+ for (var i = 0; i < colourNames.length; i++) {
+ if (string.toLowerCase() === colourNames[i][0]) {
+ return colourNames[i][1];
+ }
+ }
+ throw new Error(string + ' is not a valid colour.');
+ }
+ }
+}
+