mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 06:55:08 -04:00
autofix eslint
This commit is contained in:
parent
c9cbc4ab81
commit
5f3226a8f7
10 changed files with 243 additions and 245 deletions
|
@ -1,7 +1,6 @@
|
||||||
import Utils from '../core/Utils';
|
import Utils from '../core/Utils';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bitwise operations.
|
* Bitwise operations.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import Utils from '../core/Utils';
|
import Utils from '../core/Utils';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Byte representation operations.
|
* Byte representation operations.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,7 +16,7 @@ const Zlib = {
|
||||||
Gunzip: zlibAndGzip.Zlib.Gunzip,
|
Gunzip: zlibAndGzip.Zlib.Gunzip,
|
||||||
Zip: zip.Zlib.Zip,
|
Zip: zip.Zlib.Zip,
|
||||||
Unzip: zip.Zlib.Unzip,
|
Unzip: zip.Zlib.Unzip,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -160,7 +160,7 @@ const HTML = {
|
||||||
* @returns {html}
|
* @returns {html}
|
||||||
*/
|
*/
|
||||||
run_parse_colour_code(input, args) {
|
run_parse_colour_code(input, args) {
|
||||||
var m = null,
|
let m = null,
|
||||||
r = 0,
|
r = 0,
|
||||||
g = 0,
|
g = 0,
|
||||||
b = 0,
|
b = 0,
|
||||||
|
@ -201,7 +201,7 @@ const HTML = {
|
||||||
b = Math.round(255 * (1 - y_) * (1 - k_));
|
b = Math.round(255 * (1 - y_) * (1 - k_));
|
||||||
}
|
}
|
||||||
|
|
||||||
var hsl_ = HTML._rgb_to_hsl(r, g, b),
|
let hsl_ = HTML._rgb_to_hsl(r, g, b),
|
||||||
h = Math.round(hsl_[0] * 360),
|
h = Math.round(hsl_[0] * 360),
|
||||||
s = Math.round(hsl_[1] * 100),
|
s = Math.round(hsl_[1] * 100),
|
||||||
l = Math.round(hsl_[2] * 100),
|
l = Math.round(hsl_[2] * 100),
|
||||||
|
@ -226,7 +226,7 @@ const HTML = {
|
||||||
cmyk = `cmyk(${c}, ${m}, ${y}, ${k})`;
|
cmyk = `cmyk(${c}, ${m}, ${y}, ${k})`;
|
||||||
|
|
||||||
// Generate output
|
// Generate output
|
||||||
return `${"<div data-cyber-chef-func='colorpicker' data-rgba='" + rgba + "' id='colorpicker' style='display: inline-block'></div>" +
|
return `${`<div data-cyber-chef-func='colorpicker' data-rgba='${rgba}' id='colorpicker' style='display: inline-block'></div>` +
|
||||||
'Hex: '}${hex}\n` +
|
'Hex: '}${hex}\n` +
|
||||||
`RGB: ${rgb}\n` +
|
`RGB: ${rgb}\n` +
|
||||||
`RGBA: ${rgba}\n` +
|
`RGBA: ${rgba}\n` +
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import Utils from '../core/Utils';
|
import Utils from '../core/Utils';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hexdump operations.
|
* Hexdump operations.
|
||||||
*
|
*
|
||||||
|
|
|
@ -126,13 +126,13 @@ const IP = {
|
||||||
// Teredo tunneling
|
// Teredo tunneling
|
||||||
output += '\nTeredo tunneling IPv6 address detected\n';
|
output += '\nTeredo tunneling IPv6 address detected\n';
|
||||||
let server_ipv4 = (ipv6[2] << 16) + ipv6[3],
|
let server_ipv4 = (ipv6[2] << 16) + ipv6[3],
|
||||||
udp_port = (~ipv6[5]) & 0xffff,
|
udp_port = (~ipv6[5]) & 0xffff,
|
||||||
client_ipv4 = ~((ipv6[6] << 16) + ipv6[7]),
|
client_ipv4 = ~((ipv6[6] << 16) + ipv6[7]),
|
||||||
flag_cone = (ipv6[4] >>> 15) & 1,
|
flag_cone = (ipv6[4] >>> 15) & 1,
|
||||||
flag_r = (ipv6[4] >>> 14) & 1,
|
flag_r = (ipv6[4] >>> 14) & 1,
|
||||||
flag_random1 = (ipv6[4] >>> 10) & 15,
|
flag_random1 = (ipv6[4] >>> 10) & 15,
|
||||||
flag_ug = (ipv6[4] >>> 8) & 3,
|
flag_ug = (ipv6[4] >>> 8) & 3,
|
||||||
flag_random2 = ipv6[4] & 255;
|
flag_random2 = ipv6[4] & 255;
|
||||||
|
|
||||||
output += `\nServer IPv4 address: ${IP._ipv4_to_str(server_ipv4)
|
output += `\nServer IPv4 address: ${IP._ipv4_to_str(server_ipv4)
|
||||||
}\nClient IPv4 address: ${IP._ipv4_to_str(client_ipv4)
|
}\nClient IPv4 address: ${IP._ipv4_to_str(client_ipv4)
|
||||||
|
@ -141,76 +141,76 @@ const IP = {
|
||||||
`\n\tCone: ${flag_cone}`;
|
`\n\tCone: ${flag_cone}`;
|
||||||
|
|
||||||
if (flag_cone) {
|
if (flag_cone) {
|
||||||
output += ' (Client is behind a cone NAT)';
|
output += ' (Client is behind a cone NAT)';
|
||||||
} else {
|
} else {
|
||||||
output += ' (Client is not behind a cone NAT)';
|
output += ' (Client is not behind a cone NAT)';
|
||||||
}
|
}
|
||||||
|
|
||||||
output += `\n\tR: ${flag_r}`;
|
output += `\n\tR: ${flag_r}`;
|
||||||
|
|
||||||
if (flag_r) {
|
if (flag_r) {
|
||||||
output += ' Error: This flag should be set to 0. See RFC 5991 and RFC 4380.';
|
output += ' Error: This flag should be set to 0. See RFC 5991 and RFC 4380.';
|
||||||
}
|
}
|
||||||
|
|
||||||
output += `\n\tRandom1: ${Utils.bin(flag_random1, 4)
|
output += `\n\tRandom1: ${Utils.bin(flag_random1, 4)
|
||||||
}\n\tUG: ${Utils.bin(flag_ug, 2)}`;
|
}\n\tUG: ${Utils.bin(flag_ug, 2)}`;
|
||||||
|
|
||||||
if (flag_ug) {
|
if (flag_ug) {
|
||||||
output += ' Error: This flag should be set to 00. See RFC 4380.';
|
output += ' Error: This flag should be set to 00. See RFC 4380.';
|
||||||
}
|
}
|
||||||
|
|
||||||
output += `\n\tRandom2: ${Utils.bin(flag_random2, 8)}`;
|
output += `\n\tRandom2: ${Utils.bin(flag_random2, 8)}`;
|
||||||
|
|
||||||
if (!flag_r && !flag_ug && flag_random1 && flag_random2) {
|
if (!flag_r && !flag_ug && flag_random1 && flag_random2) {
|
||||||
output += '\n\nThis is a valid Teredo address which complies with RFC 4380 and RFC 5991.';
|
output += '\n\nThis is a valid Teredo address which complies with RFC 4380 and RFC 5991.';
|
||||||
} else if (!flag_r && !flag_ug) {
|
} else if (!flag_r && !flag_ug) {
|
||||||
output += '\n\nThis is a valid Teredo address which complies with RFC 4380, however it does not comply with RFC 5991 (Teredo Security Updates) as there are no randomised bits in the flag field.';
|
output += '\n\nThis is a valid Teredo address which complies with RFC 4380, however it does not comply with RFC 5991 (Teredo Security Updates) as there are no randomised bits in the flag field.';
|
||||||
} else {
|
} else {
|
||||||
output += '\n\nThis is an invalid Teredo address.';
|
output += '\n\nThis is an invalid Teredo address.';
|
||||||
}
|
}
|
||||||
output += '\n\nTeredo prefix range: 2001::/32';
|
output += '\n\nTeredo prefix range: 2001::/32';
|
||||||
} else if (ipv6[0] === 0x2001 && ipv6[1] === 0x2 && ipv6[2] === 0) {
|
} else if (ipv6[0] === 0x2001 && ipv6[1] === 0x2 && ipv6[2] === 0) {
|
||||||
// Benchmarking
|
// Benchmarking
|
||||||
output += '\nAssigned to the Benchmarking Methodology Working Group (BMWG) for benchmarking IPv6. Corresponds to 198.18.0.0/15 for benchmarking IPv4. See RFC 5180 for more details.';
|
output += '\nAssigned to the Benchmarking Methodology Working Group (BMWG) for benchmarking IPv6. Corresponds to 198.18.0.0/15 for benchmarking IPv4. See RFC 5180 for more details.';
|
||||||
output += '\nBMWG range: 2001:2::/48';
|
output += '\nBMWG range: 2001:2::/48';
|
||||||
} else if (ipv6[0] == 0x2001 && ipv6[1] >= 0x10 && ipv6[1] <= 0x1f) {
|
} else if (ipv6[0] == 0x2001 && ipv6[1] >= 0x10 && ipv6[1] <= 0x1f) {
|
||||||
// ORCHIDv1
|
// ORCHIDv1
|
||||||
output += '\nDeprecated, previously ORCHIDv1 (Overlay Routable Cryptographic Hash Identifiers).\nORCHIDv1 range: 2001:10::/28\nORCHIDv2 now uses 2001:20::/28.';
|
output += '\nDeprecated, previously ORCHIDv1 (Overlay Routable Cryptographic Hash Identifiers).\nORCHIDv1 range: 2001:10::/28\nORCHIDv2 now uses 2001:20::/28.';
|
||||||
} else if (ipv6[0] == 0x2001 && ipv6[1] >= 0x20 && ipv6[1] <= 0x2f) {
|
} else if (ipv6[0] == 0x2001 && ipv6[1] >= 0x20 && ipv6[1] <= 0x2f) {
|
||||||
// ORCHIDv2
|
// ORCHIDv2
|
||||||
output += '\nORCHIDv2 (Overlay Routable Cryptographic Hash Identifiers).\nThese are non-routed IPv6 addresses used for Cryptographic Hash Identifiers.';
|
output += '\nORCHIDv2 (Overlay Routable Cryptographic Hash Identifiers).\nThese are non-routed IPv6 addresses used for Cryptographic Hash Identifiers.';
|
||||||
output += '\nORCHIDv2 range: 2001:20::/28';
|
output += '\nORCHIDv2 range: 2001:20::/28';
|
||||||
} else if (ipv6[0] == 0x2001 && ipv6[1] == 0xdb8) {
|
} else if (ipv6[0] == 0x2001 && ipv6[1] == 0xdb8) {
|
||||||
// Documentation
|
// Documentation
|
||||||
output += '\nThis is a documentation IPv6 address. This range should be used whenever an example IPv6 address is given or to model networking scenarios. Corresponds to 192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24 in IPv4.';
|
output += '\nThis is a documentation IPv6 address. This range should be used whenever an example IPv6 address is given or to model networking scenarios. Corresponds to 192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24 in IPv4.';
|
||||||
output += '\nDocumentation range: 2001:db8::/32';
|
output += '\nDocumentation range: 2001:db8::/32';
|
||||||
} else if (ipv6[0] == 0x2002) {
|
} else if (ipv6[0] == 0x2002) {
|
||||||
// 6to4
|
// 6to4
|
||||||
output += '\n6to4 transition IPv6 address detected. See RFC 3056 for more details.' +
|
output += '\n6to4 transition IPv6 address detected. See RFC 3056 for more details.' +
|
||||||
'\n6to4 prefix range: 2002::/16';
|
'\n6to4 prefix range: 2002::/16';
|
||||||
|
|
||||||
let v4_addr = IP._ipv4_to_str((ipv6[1] << 16) + ipv6[2]),
|
let v4_addr = IP._ipv4_to_str((ipv6[1] << 16) + ipv6[2]),
|
||||||
sla_id = ipv6[3],
|
sla_id = ipv6[3],
|
||||||
interface_id_str = ipv6[4].toString(16) + ipv6[5].toString(16) + ipv6[6].toString(16) + ipv6[7].toString(16),
|
interface_id_str = ipv6[4].toString(16) + ipv6[5].toString(16) + ipv6[6].toString(16) + ipv6[7].toString(16),
|
||||||
interface_id = new BigInteger(interface_id_str, 16);
|
interface_id = new BigInteger(interface_id_str, 16);
|
||||||
|
|
||||||
output += `\n\nEncapsulated IPv4 address: ${v4_addr
|
output += `\n\nEncapsulated IPv4 address: ${v4_addr
|
||||||
}\nSLA ID: ${sla_id
|
}\nSLA ID: ${sla_id
|
||||||
}\nInterface ID (base 16): ${interface_id_str
|
}\nInterface ID (base 16): ${interface_id_str
|
||||||
}\nInterface ID (base 10): ${interface_id.toString()}`;
|
}\nInterface ID (base 10): ${interface_id.toString()}`;
|
||||||
} else if (ipv6[0] >= 0xfc00 && ipv6[0] <= 0xfdff) {
|
} else if (ipv6[0] >= 0xfc00 && ipv6[0] <= 0xfdff) {
|
||||||
// Unique local address
|
// Unique local address
|
||||||
output += '\nThis is a unique local address comparable to the IPv4 private addresses 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. See RFC 4193 for more details.';
|
output += '\nThis is a unique local address comparable to the IPv4 private addresses 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. See RFC 4193 for more details.';
|
||||||
output += '\nUnique local addresses range: fc00::/7';
|
output += '\nUnique local addresses range: fc00::/7';
|
||||||
} else if (ipv6[0] >= 0xfe80 && ipv6[0] <= 0xfebf) {
|
} else if (ipv6[0] >= 0xfe80 && ipv6[0] <= 0xfebf) {
|
||||||
// Link-local address
|
// Link-local address
|
||||||
output += '\nThis is a link-local address comparable to the auto-configuration addresses 169.254.0.0/16 in IPv4.';
|
output += '\nThis is a link-local address comparable to the auto-configuration addresses 169.254.0.0/16 in IPv4.';
|
||||||
output += '\nLink-local addresses range: fe80::/10';
|
output += '\nLink-local addresses range: fe80::/10';
|
||||||
} else if (ipv6[0] >= 0xff00) {
|
} else if (ipv6[0] >= 0xff00) {
|
||||||
// Multicast
|
// Multicast
|
||||||
output += '\nThis is a reserved multicast address.';
|
output += '\nThis is a reserved multicast address.';
|
||||||
output += '\nMulticast addresses range: ff00::/8';
|
output += '\nMulticast addresses range: ff00::/8';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 'Invalid IPv6 address';
|
return 'Invalid IPv6 address';
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import Utils from '../core/Utils';
|
||||||
import JsDiff from '../lib/diff';
|
import JsDiff from '../lib/diff';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String utility operations.
|
* String utility operations.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,7 +3,6 @@ import HTMLOperation from './HTMLOperation';
|
||||||
import Sortable from '../../lib/Sortable';
|
import Sortable from '../../lib/Sortable';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle events related to the operations.
|
* Waiter to handle events related to the operations.
|
||||||
*
|
*
|
||||||
|
|
|
@ -5,15 +5,15 @@ import CanvasComponents from './utils/CanvasComponents';
|
||||||
const inlineFuncs = {
|
const inlineFuncs = {
|
||||||
colorpicker({ rgba }) {
|
colorpicker({ rgba }) {
|
||||||
$('#colorpicker').colorpicker({
|
$('#colorpicker').colorpicker({
|
||||||
format: 'rgba',
|
format: 'rgba',
|
||||||
color: rgba,
|
color: rgba,
|
||||||
container: true,
|
container: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
}).on('changeColor', function(e) {
|
}).on('changeColor', (e) => {
|
||||||
const { r, g, b, a} = e.color.toRGB();
|
const { r, g, b, a } = e.color.toRGB();
|
||||||
const css = `rgba(${r}, ${g}, ${b}, ${a})`;
|
const css = `rgba(${r}, ${g}, ${b}, ${a})`;
|
||||||
document.getElementById('input-text').value = css;
|
document.getElementById('input-text').value = css;
|
||||||
window.app.auto_bake();
|
window.app.auto_bake();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
entropy({ entropy }) {
|
entropy({ entropy }) {
|
||||||
|
@ -23,15 +23,15 @@ const inlineFuncs = {
|
||||||
canvas.width = parent_rect.width * 0.95;
|
canvas.width = parent_rect.width * 0.95;
|
||||||
canvas.height = height > 150 ? 150 : height;
|
canvas.height = height > 150 ? 150 : height;
|
||||||
CanvasComponents.draw_scale_bar(canvas, entropy, 8, [
|
CanvasComponents.draw_scale_bar(canvas, entropy, 8, [
|
||||||
{
|
{
|
||||||
label: 'English text',
|
label: 'English text',
|
||||||
min: 3.5,
|
min: 3.5,
|
||||||
max: 5
|
max: 5,
|
||||||
},{
|
}, {
|
||||||
label: 'Encrypted/compressed',
|
label: 'Encrypted/compressed',
|
||||||
min: 7.5,
|
min: 7.5,
|
||||||
max: 8
|
max: 8,
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
freq({ percentages }) {
|
freq({ percentages }) {
|
||||||
|
@ -41,8 +41,8 @@ const inlineFuncs = {
|
||||||
canvas.width = parent_rect.width * 0.95;
|
canvas.width = parent_rect.width * 0.95;
|
||||||
canvas.height = parent_rect.height * 0.9;
|
canvas.height = parent_rect.height * 0.9;
|
||||||
CanvasComponents.draw_bar_chart(canvas, scores, 'Byte', 'Frequency %', 16, 6);
|
CanvasComponents.draw_bar_chart(canvas, scores, 'Byte', 'Frequency %', 16, 6);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle events related to the output.
|
* Waiter to handle events related to the output.
|
||||||
|
|
|
@ -10,175 +10,178 @@
|
||||||
*/
|
*/
|
||||||
const CanvasComponents = {
|
const CanvasComponents = {
|
||||||
|
|
||||||
draw_line: function(ctx, start_x, start_y, end_x, end_y) {
|
draw_line(ctx, start_x, start_y, end_x, end_y) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(start_x, start_y);
|
ctx.moveTo(start_x, start_y);
|
||||||
ctx.lineTo(end_x, end_y);
|
ctx.lineTo(end_x, end_y);
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
draw_bar_chart(canvas, scores, x_axis_label, y_axis_label, num_x_labels, num_y_labels, font_size) {
|
||||||
|
font_size = font_size || 15;
|
||||||
|
if (!num_x_labels || num_x_labels > Math.round(canvas.width / 50)) {
|
||||||
|
num_x_labels = Math.round(canvas.width / 50);
|
||||||
|
}
|
||||||
|
if (!num_y_labels || num_y_labels > Math.round(canvas.width / 50)) {
|
||||||
|
num_y_labels = Math.round(canvas.height / 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Graph properties
|
||||||
|
let ctx = canvas.getContext('2d'),
|
||||||
|
left_padding = canvas.width * 0.08,
|
||||||
|
right_padding = canvas.width * 0.03,
|
||||||
|
top_padding = canvas.height * 0.08,
|
||||||
|
bottom_padding = canvas.height * 0.15,
|
||||||
|
graph_height = canvas.height - top_padding - bottom_padding,
|
||||||
|
graph_width = canvas.width - left_padding - right_padding,
|
||||||
|
base = top_padding + graph_height,
|
||||||
|
ceil = top_padding;
|
||||||
|
|
||||||
|
ctx.font = `${font_size}px Arial`;
|
||||||
|
|
||||||
|
// Draw axis
|
||||||
|
ctx.lineWidth = '1.0';
|
||||||
|
ctx.strokeStyle = '#444';
|
||||||
|
CanvasComponents.draw_line(ctx, left_padding, base, graph_width + left_padding, base); // x
|
||||||
|
CanvasComponents.draw_line(ctx, left_padding, base, left_padding, ceil); // y
|
||||||
|
|
||||||
|
// Bar properties
|
||||||
|
let bar_padding = graph_width * 0.003,
|
||||||
|
bar_width = (graph_width - (bar_padding * scores.length)) / scores.length,
|
||||||
|
curr_x = left_padding + bar_padding,
|
||||||
|
max = Math.max(...scores);
|
||||||
|
|
||||||
|
// Draw bars
|
||||||
|
ctx.fillStyle = 'green';
|
||||||
|
for (var i = 0; i < scores.length; i++) {
|
||||||
|
const h = scores[i] / max * graph_height;
|
||||||
|
ctx.fillRect(curr_x, base - h, bar_width, h);
|
||||||
|
curr_x += bar_width + bar_padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark x axis
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
curr_x = left_padding + bar_padding;
|
||||||
|
if (num_x_labels >= scores.length) {
|
||||||
|
// Mark every score
|
||||||
|
for (let j = 0; j <= scores.length; j++) {
|
||||||
|
ctx.fillText(j, curr_x, base + (bottom_padding * 0.3));
|
||||||
|
curr_x += bar_width + bar_padding;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mark some scores
|
||||||
|
for (let k = 0; k <= num_x_labels; k++) {
|
||||||
|
const val = Math.ceil((scores.length / num_x_labels) * k);
|
||||||
|
curr_x = (graph_width / num_x_labels) * k + left_padding;
|
||||||
|
ctx.fillText(val, curr_x, base + (bottom_padding * 0.3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark y axis
|
||||||
|
ctx.textAlign = 'right';
|
||||||
|
let curr_y;
|
||||||
|
if (num_y_labels >= max) {
|
||||||
|
// Mark every increment
|
||||||
|
for (let l = 0; l <= max; l++) {
|
||||||
|
curr_y = base - (l / max * graph_height) + font_size / 3;
|
||||||
|
ctx.fillText(i, left_padding * 0.8, curr_y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mark some increments
|
||||||
|
for (let m = 0; m <= num_y_labels; m++) {
|
||||||
|
const val2 = Math.ceil((max / num_y_labels) * m);
|
||||||
|
curr_y = base - (val2 / max * graph_height) + font_size / 3;
|
||||||
|
ctx.fillText(val2, left_padding * 0.8, curr_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Label x axis
|
||||||
|
if (x_axis_label) {
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.fillText(x_axis_label, graph_width / 2 + left_padding, base + bottom_padding * 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Label y axis
|
||||||
|
if (y_axis_label) {
|
||||||
|
ctx.save();
|
||||||
|
let x = left_padding * 0.3,
|
||||||
|
y = graph_height / 2 + top_padding;
|
||||||
|
ctx.translate(x, y);
|
||||||
|
ctx.rotate(-Math.PI / 2);
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.fillText(y_axis_label, 0, 0);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
draw_scale_bar(canvas, score, max, markings) {
|
||||||
|
// Bar properties
|
||||||
|
let ctx = canvas.getContext('2d'),
|
||||||
|
left_padding = canvas.width * 0.01,
|
||||||
|
right_padding = canvas.width * 0.01,
|
||||||
|
top_padding = canvas.height * 0.1,
|
||||||
|
bottom_padding = canvas.height * 0.3,
|
||||||
|
bar_height = canvas.height - top_padding - bottom_padding,
|
||||||
|
bar_width = canvas.width - left_padding - right_padding;
|
||||||
|
|
||||||
|
// Scale properties
|
||||||
|
const proportion = score / max;
|
||||||
|
|
||||||
|
// Draw bar outline
|
||||||
|
ctx.strokeRect(left_padding, top_padding, bar_width, bar_height);
|
||||||
|
|
||||||
|
// Shade in up to proportion
|
||||||
|
const grad = ctx.createLinearGradient(left_padding, 0, bar_width + left_padding, 0);
|
||||||
|
grad.addColorStop(0, 'green');
|
||||||
|
grad.addColorStop(0.5, 'gold');
|
||||||
|
grad.addColorStop(1, 'red');
|
||||||
|
ctx.fillStyle = grad;
|
||||||
|
ctx.fillRect(left_padding, top_padding, bar_width * proportion, bar_height);
|
||||||
|
|
||||||
|
// Add markings
|
||||||
|
let x0,
|
||||||
|
y0,
|
||||||
|
x1,
|
||||||
|
y1;
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.textAlign = 'center';
|
||||||
|
ctx.font = '13px Arial';
|
||||||
|
for (let i = 0; i < markings.length; i++) {
|
||||||
|
// Draw min line down
|
||||||
|
x0 = bar_width / max * markings[i].min + left_padding;
|
||||||
|
y0 = top_padding + bar_height + (bottom_padding * 0.1);
|
||||||
|
x1 = x0;
|
||||||
|
y1 = top_padding + bar_height + (bottom_padding * 0.3);
|
||||||
|
CanvasComponents.draw_line(ctx, x0, y0, x1, y1);
|
||||||
|
|
||||||
|
// Draw max line down
|
||||||
|
x0 = bar_width / max * markings[i].max + left_padding;
|
||||||
|
x1 = x0;
|
||||||
|
CanvasComponents.draw_line(ctx, x0, y0, x1, y1);
|
||||||
|
|
||||||
|
// Join min and max lines
|
||||||
|
x0 = bar_width / max * markings[i].min + left_padding;
|
||||||
|
y0 = top_padding + bar_height + (bottom_padding * 0.3);
|
||||||
|
x1 = bar_width / max * markings[i].max + left_padding;
|
||||||
|
y1 = y0;
|
||||||
|
CanvasComponents.draw_line(ctx, x0, y0, x1, y1);
|
||||||
|
|
||||||
|
// Add label
|
||||||
|
if (markings[i].max >= max * 0.9) {
|
||||||
|
ctx.textAlign = 'right';
|
||||||
|
x0 = x1;
|
||||||
|
} else if (markings[i].max <= max * 0.1) {
|
||||||
|
ctx.textAlign = 'left';
|
||||||
|
} else {
|
||||||
|
x0 += (x1 - x0) / 2;
|
||||||
|
}
|
||||||
|
y0 = top_padding + bar_height + (bottom_padding * 0.8);
|
||||||
|
ctx.fillText(markings[i].label, x0, y0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
draw_bar_chart: function(canvas, scores, x_axis_label, y_axis_label, num_x_labels, num_y_labels, font_size) {
|
|
||||||
font_size = font_size || 15;
|
|
||||||
if (!num_x_labels || num_x_labels > Math.round(canvas.width / 50)) {
|
|
||||||
num_x_labels = Math.round(canvas.width / 50);
|
|
||||||
}
|
|
||||||
if (!num_y_labels || num_y_labels > Math.round(canvas.width / 50)) {
|
|
||||||
num_y_labels = Math.round(canvas.height / 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Graph properties
|
|
||||||
var ctx = canvas.getContext("2d"),
|
|
||||||
left_padding = canvas.width * 0.08,
|
|
||||||
right_padding = canvas.width * 0.03,
|
|
||||||
top_padding = canvas.height * 0.08,
|
|
||||||
bottom_padding = canvas.height * 0.15,
|
|
||||||
graph_height = canvas.height - top_padding - bottom_padding,
|
|
||||||
graph_width = canvas.width - left_padding - right_padding,
|
|
||||||
base = top_padding + graph_height,
|
|
||||||
ceil = top_padding;
|
|
||||||
|
|
||||||
ctx.font = font_size + "px Arial";
|
|
||||||
|
|
||||||
// Draw axis
|
|
||||||
ctx.lineWidth = "1.0";
|
|
||||||
ctx.strokeStyle = "#444";
|
|
||||||
CanvasComponents.draw_line(ctx, left_padding, base, graph_width + left_padding, base); // x
|
|
||||||
CanvasComponents.draw_line(ctx, left_padding, base, left_padding, ceil); // y
|
|
||||||
|
|
||||||
// Bar properties
|
|
||||||
var bar_padding = graph_width * 0.003,
|
|
||||||
bar_width = (graph_width - (bar_padding * scores.length)) / scores.length,
|
|
||||||
curr_x = left_padding + bar_padding,
|
|
||||||
max = Math.max.apply(Math, scores);
|
|
||||||
|
|
||||||
// Draw bars
|
|
||||||
ctx.fillStyle = "green";
|
|
||||||
for (var i = 0; i < scores.length; i++) {
|
|
||||||
var h = scores[i] / max * graph_height;
|
|
||||||
ctx.fillRect(curr_x, base - h, bar_width, h);
|
|
||||||
curr_x += bar_width + bar_padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark x axis
|
|
||||||
ctx.fillStyle = "black";
|
|
||||||
ctx.textAlign = "center";
|
|
||||||
curr_x = left_padding + bar_padding;
|
|
||||||
if (num_x_labels >= scores.length) {
|
|
||||||
// Mark every score
|
|
||||||
for (var j = 0; j <= scores.length; j++) {
|
|
||||||
ctx.fillText(j, curr_x, base + (bottom_padding * 0.3));
|
|
||||||
curr_x += bar_width + bar_padding;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Mark some scores
|
|
||||||
for (var k = 0; k <= num_x_labels; k++) {
|
|
||||||
var val = Math.ceil((scores.length / num_x_labels) * k);
|
|
||||||
curr_x = (graph_width / num_x_labels) * k + left_padding;
|
|
||||||
ctx.fillText(val, curr_x, base + (bottom_padding * 0.3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark y axis
|
|
||||||
ctx.textAlign = "right";
|
|
||||||
var curr_y;
|
|
||||||
if (num_y_labels >= max) {
|
|
||||||
// Mark every increment
|
|
||||||
for (var l = 0; l <= max; l++) {
|
|
||||||
curr_y = base - (l / max * graph_height) + font_size / 3;
|
|
||||||
ctx.fillText(i, left_padding * 0.8, curr_y);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Mark some increments
|
|
||||||
for (var m = 0; m <= num_y_labels; m++) {
|
|
||||||
var val2 = Math.ceil((max / num_y_labels) * m);
|
|
||||||
curr_y = base - (val2 / max * graph_height) + font_size / 3;
|
|
||||||
ctx.fillText(val2, left_padding * 0.8, curr_y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Label x axis
|
|
||||||
if (x_axis_label) {
|
|
||||||
ctx.textAlign = "center";
|
|
||||||
ctx.fillText(x_axis_label, graph_width / 2 + left_padding, base + bottom_padding * 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Label y axis
|
|
||||||
if (y_axis_label) {
|
|
||||||
ctx.save();
|
|
||||||
var x = left_padding * 0.3,
|
|
||||||
y = graph_height / 2 + top_padding;
|
|
||||||
ctx.translate(x, y);
|
|
||||||
ctx.rotate(-Math.PI / 2);
|
|
||||||
ctx.textAlign = "center";
|
|
||||||
ctx.fillText(y_axis_label, 0, 0);
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
draw_scale_bar: function(canvas, score, max, markings) {
|
|
||||||
// Bar properties
|
|
||||||
var ctx = canvas.getContext("2d"),
|
|
||||||
left_padding = canvas.width * 0.01,
|
|
||||||
right_padding = canvas.width * 0.01,
|
|
||||||
top_padding = canvas.height * 0.1,
|
|
||||||
bottom_padding = canvas.height * 0.3,
|
|
||||||
bar_height = canvas.height - top_padding - bottom_padding,
|
|
||||||
bar_width = canvas.width - left_padding - right_padding;
|
|
||||||
|
|
||||||
// Scale properties
|
|
||||||
var proportion = score / max;
|
|
||||||
|
|
||||||
// Draw bar outline
|
|
||||||
ctx.strokeRect(left_padding, top_padding, bar_width, bar_height);
|
|
||||||
|
|
||||||
// Shade in up to proportion
|
|
||||||
var grad = ctx.createLinearGradient(left_padding, 0, bar_width + left_padding, 0);
|
|
||||||
grad.addColorStop(0, "green");
|
|
||||||
grad.addColorStop(0.5, "gold");
|
|
||||||
grad.addColorStop(1, "red");
|
|
||||||
ctx.fillStyle = grad;
|
|
||||||
ctx.fillRect(left_padding, top_padding, bar_width * proportion, bar_height);
|
|
||||||
|
|
||||||
// Add markings
|
|
||||||
var x0, y0, x1, y1;
|
|
||||||
ctx.fillStyle = "black";
|
|
||||||
ctx.textAlign = "center";
|
|
||||||
ctx.font = "13px Arial";
|
|
||||||
for (var i = 0; i < markings.length; i++) {
|
|
||||||
// Draw min line down
|
|
||||||
x0 = bar_width / max * markings[i].min + left_padding;
|
|
||||||
y0 = top_padding + bar_height + (bottom_padding * 0.1);
|
|
||||||
x1 = x0;
|
|
||||||
y1 = top_padding + bar_height + (bottom_padding * 0.3);
|
|
||||||
CanvasComponents.draw_line(ctx, x0, y0, x1, y1);
|
|
||||||
|
|
||||||
// Draw max line down
|
|
||||||
x0 = bar_width / max * markings[i].max + left_padding;
|
|
||||||
x1 = x0;
|
|
||||||
CanvasComponents.draw_line(ctx, x0, y0, x1, y1);
|
|
||||||
|
|
||||||
// Join min and max lines
|
|
||||||
x0 = bar_width / max * markings[i].min + left_padding;
|
|
||||||
y0 = top_padding + bar_height + (bottom_padding * 0.3);
|
|
||||||
x1 = bar_width / max * markings[i].max + left_padding;
|
|
||||||
y1 = y0;
|
|
||||||
CanvasComponents.draw_line(ctx, x0, y0, x1, y1);
|
|
||||||
|
|
||||||
// Add label
|
|
||||||
if (markings[i].max >= max * 0.9) {
|
|
||||||
ctx.textAlign = "right";
|
|
||||||
x0 = x1;
|
|
||||||
} else if (markings[i].max <= max * 0.1) {
|
|
||||||
ctx.textAlign = "left";
|
|
||||||
} else {
|
|
||||||
x0 = x0 + (x1 - x0) / 2;
|
|
||||||
}
|
|
||||||
y0 = top_padding + bar_height + (bottom_padding * 0.8);
|
|
||||||
ctx.fillText(markings[i].label, x0, y0);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CanvasComponents;
|
export default CanvasComponents;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue