/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import OperationError from "../errors/OperationError.mjs";
/**
* Frequency distribution operation
*/
class FrequencyDistribution extends Operation {
/**
* FrequencyDistribution constructor
*/
constructor() {
super();
this.name = "Frequency distribution";
this.module = "Default";
this.description = "Displays the distribution of bytes in the data as a graph.";
this.infoURL = "https://wikipedia.org/wiki/Frequency_distribution";
this.inputType = "ArrayBuffer";
this.outputType = "json";
this.presentType = "html";
this.args = [
{
"name": "Show 0%s",
"type": "boolean",
"value": true
},
{
"name": "Show ASCII",
"type": "boolean",
"value": true
}
];
}
/**
* @param {ArrayBuffer} input
* @param {Object[]} args
* @returns {json}
*/
run(input, args) {
const data = new Uint8Array(input);
if (!data.length) throw new OperationError("No data");
const distrib = new Array(256).fill(0),
percentages = new Array(256),
len = data.length;
let i;
// Count bytes
for (i = 0; i < len; i++) {
distrib[data[i]]++;
}
// Calculate percentages
let repr = 0;
for (i = 0; i < 256; i++) {
if (distrib[i] > 0) repr++;
percentages[i] = distrib[i] / len * 100;
}
return {
"dataLength": len,
"percentages": percentages,
"distribution": distrib,
"bytesRepresented": repr
};
}
/**
* Displays the frequency distribution as a bar chart for web apps.
*
* @param {json} freq
* @returns {html}
*/
present(freq, args) {
const [showZeroes, showAscii] = args;
// Print
let output = `
Total data length: ${freq.dataLength}
Number of bytes represented: ${freq.bytesRepresented}
Number of bytes not represented: ${256 - freq.bytesRepresented}
Byte | ${showAscii ? "ASCII | " : ""}Percentage | ${Utils.hex(i, 2)} | `, ascii = showAscii ? `${c} | ` : "", percentage = `${(freq.percentages[i].toFixed(2).replace(".00", "") + "%").padEnd(8, " ")} | `, bars = `${Array(Math.ceil(freq.percentages[i])+1).join("|")} | `; output += `
---|---|---|---|