X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Ftemplate%2Fhistogram-svg.js;fp=src%2Ftemplate%2Fhistogram-svg.js;h=13d0c91becb0d4ae94f9dcfe454f8e279e1390c6;hb=737fbd003d5c4dfea81b667ef906f1c106a60612;hp=0000000000000000000000000000000000000000;hpb=17b4ff9c1974842c02071d2cd02144d2e5a99eb5;p=websub-hub
diff --git a/src/template/histogram-svg.js b/src/template/histogram-svg.js
new file mode 100644
index 0000000..13d0c91
--- /dev/null
+++ b/src/template/histogram-svg.js
@@ -0,0 +1,131 @@
+'use strict';
+
+const th = require('./template-helper');
+
+const optionsDefaults = {
+ barWidth: 20,
+ barHeight: 100,
+ scaleBars: true,
+ barCaptionFn: () => '',
+ labelZero: undefined,
+ labelX: undefined,
+ labelHeight: 8,
+ fontFamily: 'DejaVu Sans,Verdana,Geneva,sans-serif',
+ frameColor: 'gray',
+ tickEvery: undefined,
+ tickHeight: 4,
+ tickColor: 'gray',
+ minItems: 0,
+ maxItems: undefined,
+};
+
+function grey(percent) {
+ const value = Math.round(95 * (1.0 - percent));
+ return `rgb(${value}%, ${value}%, ${value}%)`;
+}
+
+function svgHeader(options, width, height) {
+ return [
+ `';
+}
+
+function svgBar(options, value, index, maxValue) {
+ const id = `i${index}`;
+ const x = options.barWidth * index;
+ const width = options.barWidth;
+ const height = options.barHeight;
+ const scale = value / Math.max(1, maxValue);
+ const scaleHeight = options.scaleBars ? height * scale : height;
+ const yOffset = height - scaleHeight;
+ const fill = grey(scale);
+ const emptyFill = grey(0);
+ const title = th.xmlEscape(options.barCaptionFn(index, value));
+ return [
+ ...(options.scaleBars && [
+ `\t`,
+ ...(title && `${title}`),
+ '\t\n',
+ ]),
+ `\t`,
+ ...(title && `${title}`),
+ '\t\n',
+ ].join('');
+}
+
+module.exports = (items, options = {}) => {
+ options = Object.assign({}, optionsDefaults, options);
+
+ const maxValue = items.reduce((a, b) => Math.max(a, b), 0);
+ const hasLabel = !!options.labelX || !!options.labelZero;
+ const height = options.barHeight + 2 + (hasLabel ? options.labelHeight + 2 : 0);
+ const width = Math.max(items.length, options.minItems) * options.barWidth;
+
+ return [
+ ...svgHeader(options, width, height),
+ ...items.slice(0, options.maxItems).map((value, index) => svgBar(options, value, index, maxValue)),
+ svgFrame(options, width),
+ svgTicks(options, width),
+ ...svgLabels(options, width, height),
+ svgFooter(),
+ ].join('');
+};
\ No newline at end of file