PluginProbe
SQL Chart Builder / 3.0.6
SQL Chart Builder v3.0.6
3.0.6 3.0.5 3.0.4 3.0.3 3.0.2 3.0.1 trunk 1.0.2 1.0.3 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 2.3.7.1 2.3.7.2 2.3.8 3.0.0
← All changes | asset/front.js +74 -0 3.0.13.0.6 View file →
@@ -52,8 +52,82 @@
52 52 }
53 53 });
54 54 })();
55 55
56 +/* "Scale X axis by date/time" option: the PHP side emits {x: <utc ms>, y: value} points on a linear
57 + X scale whose tick callback and tooltip title callback are the two globals below. UTC getters are
58 + used on purpose so a date never shifts by a day in the viewer's time zone. */
59 +(function () {
60 + function pad(n) { return (n < 10 ? '0' : '') + n; }
61 + function fmt(ms, withTime) {
62 + var d = new Date(ms);
63 + if (isNaN(d.getTime())) return ms;
64 + var s = d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate());
65 + if (withTime) s += ' ' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes());
66 + return s;
67 + }
68 + function hasTime(chart) {
69 + if (!chart || chart.__gvnHasTime !== undefined) return chart ? chart.__gvnHasTime : false;
70 + var found = false;
71 + (chart.data.datasets || []).forEach(function (ds) {
72 + (ds.data || []).forEach(function (p) {
73 + if (p && typeof p === 'object' && p.x % 86400000 !== 0) found = true;
74 + });
75 + });
76 + chart.__gvnHasTime = found;
77 + return found;
78 + }
79 + // Labels of dates that sit too close together on the axis are moved to a lower line (one below the
80 + // other) instead of being drawn over each other. Returns the line level (0, 1, 2) per tick index.
81 + function staggerLevels(scale, ticks, withTime) {
82 + var sig = ticks.length + ':' + scale.min + ':' + scale.max + ':' + scale.width;
83 + if (scale.__gvnStagger && scale.__gvnStagger.sig === sig) return scale.__gvnStagger.levels;
84 + var span = (scale.max - scale.min) || 1, width = scale.width || 0, levels = [], px = [], i, j, L, ok;
85 + var labelW = (withTime ? 16 : 10) * 7 + 12; // approx. pixel width of "YYYY-MM-DD[ HH:MM]" plus a gap
86 + for (i = 0; i < ticks.length; i++) {
87 + px[i] = (ticks[i].value - scale.min) / span * width;
88 + for (L = 0; L < 3; L++) {
89 + ok = true;
90 + for (j = 0; j < i; j++) if (levels[j] === L && Math.abs(px[i] - px[j]) < labelW) { ok = false; break; }
91 + if (ok) break;
92 + }
93 + levels[i] = ok ? L : -1; // -1: no free line, the label is hidden (the tooltip still shows the date)
94 + }
95 + scale.__gvnStagger = { sig: sig, levels: levels };
96 + return levels;
97 + }
98 + // scales.x.ticks.callback – "this" is the scale
99 + window.gvnSqlChartsTimeTick = function (value, index, ticks) {
100 + var withTime = hasTime(this && this.chart);
101 + var label = fmt(value, withTime);
102 + if (!this || !ticks || !ticks.length || typeof index !== 'number') return label;
103 + var level = staggerLevels(this, ticks, withTime)[index] || 0;
104 + if (level < 0) return '';
105 + if (!level) return label;
106 + var lines = [];
107 + for (var k = 0; k < level; k++) lines.push('');
108 + lines.push(label);
109 + return lines;
110 + };
111 + // scales.x.afterBuildTicks – label only the dates that exist in the data instead of evenly spaced values
112 + window.gvnSqlChartsTimeTicks = function (scale) {
113 + var seen = {}, xs = [];
114 + (scale.chart.data.datasets || []).forEach(function (ds, i) {
115 + if (scale.chart.getDatasetMeta(i).hidden) return;
116 + (ds.data || []).forEach(function (p) {
117 + if (p && typeof p === 'object' && typeof p.x === 'number' && !seen[p.x]) { seen[p.x] = true; xs.push(p.x); }
118 + });
119 + });
120 + if (!xs.length) return;
121 + xs.sort(function (a, b) { return a - b; });
122 + scale.ticks = xs.map(function (v) { return { value: v }; });
123 + };
124 + // plugins.tooltip.callbacks.title
125 + window.gvnSqlChartsTimeTooltipTitle = function (items) {
126 + return items && items.length ? fmt(items[0].parsed.x, hasTime(items[0].chart)) : '';
127 + };
128 +})();
129 +
56 130 /* Datepicker for [type: date] dynamic filters */
57 131 jQuery(function ($) {
58 132 if ($.fn.datepicker) {
59 133 $('[data-toggle="datepicker"]').datepicker({ format: 'yyyy-mm-dd', autoHide: true });