ansi-chart
Version:
A lightweight and simple tool for rendering beautiful charts directly in your terminal using only ANSI-compatible ASCII characters. Create bar charts, line graphs, and more with customizable styles, all without external dependencies. Perfect for CLI appli
65 lines • 3.31 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LineChart = void 0;
const asciichart_1 = require("asciichart");
const chalk_1 = __importDefault(require("chalk"));
class LineChart {
constructor(config) {
this.config = config;
}
plot(data, color) {
const xArray = Array.isArray(data[0]) ? data.map((v) => v[0]) : data.map((v, i) => i);
const yArray = Array.isArray(data[0]) ? data.map((v) => v[1]) : data.map((v) => v);
const chart = (0, asciichart_1.plot)(yArray, this.config);
const fullWidth = chart.split('\n')[0].length;
const reservedYLegendWidth = chart.split('\n')[0].split(/┤|┼╮|┼/)[0].length + 2;
const widthXaxis = fullWidth - reservedYLegendWidth;
const longestXLabel = xArray.map((l) => l.toString().length).sort((a, b) => b - a)[0];
const maxDecimals = xArray.map((l) => this.countDecimals(l)).sort((a, b) => b - a)[0];
const maxNoXLabels = Math.floor(widthXaxis / (longestXLabel + 2));
const valueBetweenLabels = (xArray[xArray.length - 1] - xArray[0]) / (maxNoXLabels - 2);
const factor = Math.pow(10, maxDecimals);
const labels = [Math.round(xArray[0] * factor) / factor];
for (let i = 0; i < maxNoXLabels - 2; ++i) {
labels.push(Math.round((labels[labels.length - 1] + valueBetweenLabels) * factor) / factor);
}
const ticks = this.generateXAxisTicks(widthXaxis, reservedYLegendWidth, xArray, labels);
const { xLabel, yLabel } = this.config;
console.log(`\t(${yLabel})\n${chalk_1.default.hex(color)(chart)}\n${ticks} (${xLabel})\n`);
}
generateXAxisTicks(xAxisWidth, yAxisWidth, xArray, labels) {
const tickPositions = labels.map((value) => Math.round(((value - xArray[0]) / (xArray[xArray.length - 1] - xArray[0])) * xAxisWidth));
const tickString = [...new Array(yAxisWidth)].join(' ') +
[...new Array(xAxisWidth)].map((v, i) => (tickPositions.indexOf(i) > -1 ? '┬' : '─')).join('');
const tickLabelStartPosition = tickPositions.map((pos, i) => pos - Math.floor(labels[i].toString().length / 2));
const reservedWhitespace = [...new Array(yAxisWidth - 1)]
.map((v, i) => {
if (i - yAxisWidth + 1 == tickLabelStartPosition[0])
return labels[0];
else
return ' ';
})
.join('');
const startIndex = reservedWhitespace.length + 1 - yAxisWidth;
const tickLabels = [];
for (let i = startIndex; i < xAxisWidth; ++i) {
if (tickLabelStartPosition.indexOf(i) > -1) {
tickLabels.push(labels[tickLabelStartPosition.indexOf(i)]);
i = startIndex + tickLabels.join('').length - 1;
}
else
tickLabels.push(' ');
}
return `${tickString}\n${reservedWhitespace + tickLabels.join('')}`;
}
countDecimals(value) {
if (value % 1 != 0)
return value.toString().split('.')[1].length;
return 0;
}
}
exports.LineChart = LineChart;
//# sourceMappingURL=line-chart.js.map