bezel-charts 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /*! Bezel Charts v1.6.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
1
+ /*! Bezel Charts v1.7.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
2
 
3
3
  // src/core/util.js
4
4
  var SANS = "ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif";
@@ -268,7 +268,7 @@ var THEMES = {
268
268
  };
269
269
 
270
270
  // src/render.js
271
- var NAMES = ["spark", "line", "area", "bars", "histogram", "boxplot", "scatter", "ring", "donut", "gauge", "progress", "heatmap"];
271
+ var NAMES = ["spark", "line", "area", "bars", "combo", "histogram", "boxplot", "scatter", "ring", "donut", "gauge", "progress", "heatmap"];
272
272
  var TYPES = {};
273
273
  function register(type, fn) {
274
274
  TYPES[type] = fn;
@@ -351,7 +351,14 @@ var ATTRIBUTES = [
351
351
  "bin-width",
352
352
  "mark",
353
353
  "percent",
354
- "whiskers"
354
+ "whiskers",
355
+ "line",
356
+ "line-series",
357
+ "line-prefix",
358
+ "line-suffix",
359
+ "line-decimals",
360
+ "line-label",
361
+ "line-zero"
355
362
  ];
356
363
  var HOST_CSS = `:host{display:block;position:relative;max-width:100%}:host([hidden]){display:none}svg{display:block;max-width:100%;height:auto;overflow:visible}.tip{position:absolute;left:0;top:0;pointer-events:none;background:#0b0b10;color:#f2f1f7;font:600 12px/1.5 ${MONO};padding:7px 10px;border-radius:10px;white-space:pre;opacity:0;transform:translate(-50%,calc(-100% - 12px));transition:opacity .12s;z-index:3;border:1px solid #2a2935;box-shadow:0 8px 24px rgba(0,0,0,.35)}.tip.on{opacity:1}.c{outline:none}.c:focus-visible{outline:2px solid #fff;outline-offset:3px;box-shadow:0 0 0 7px #000}.k{stroke:currentColor;stroke-width:2;stroke-opacity:1}.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media (forced-colors:active){.c:focus-visible{outline-color:Highlight}}`;
357
364
  var STEPS = { ArrowLeft: -1, ArrowUp: -1, ArrowRight: 1, ArrowDown: 1 };
@@ -1169,6 +1176,224 @@ bars.table = function(o) {
1169
1176
  register("bars", bars);
1170
1177
  define("bars");
1171
1178
 
1179
+ // src/charts/combo.js
1180
+ function combo(o, th) {
1181
+ var B = series(o.values), L = series(o.line), pal = palette(o, th), k = B.length, m = L.length;
1182
+ var labels = list(o.labels), bnames = list(o.series), lnames = list(o.lineSeries), stacked = k > 1 && bool(o.stacked);
1183
+ var n = Math.max.apply(null, [0].concat(B.concat(L).map(function(s) {
1184
+ return s.length;
1185
+ })));
1186
+ var lo = lineOpts(o), h = num(o.height, 200);
1187
+ var barName = function(j) {
1188
+ return bnames[j] || (k === 1 ? "Bars" : "Bars " + (j + 1));
1189
+ };
1190
+ var lineName = function(j) {
1191
+ return lnames[j] || (m === 1 ? "Line" : "Line " + (j + 1));
1192
+ };
1193
+ var barCol = function(j) {
1194
+ return pal[j % pal.length];
1195
+ }, lineCol = function(j) {
1196
+ return pal[(k + j) % pal.length];
1197
+ };
1198
+ var val = function(s, i2) {
1199
+ return i2 < s.length ? s[i2] : 0;
1200
+ };
1201
+ var dashOf = styleOf(o.dash, Object.keys(DASHES), "solid"), markOf = styleOf(o.markers, SHAPES, "none");
1202
+ var patOf = k > 1 ? styleOf(o.patterns, PATTERNS, "solid") : null, bg = o.background || th.tile, defs = "", fills = [];
1203
+ for (var q = 0; patOf && q < k; q++) {
1204
+ if (patOf(q) === "solid") continue;
1205
+ var pid = newId("g");
1206
+ defs += pattern(pid, patOf(q), barCol(q), bg);
1207
+ fills[q] = "url(#" + pid + ")";
1208
+ }
1209
+ var key = function(e, x, y) {
1210
+ if (e < k) return '<rect x="' + r2(x) + '" y="' + r2(y + 1) + '" width="10" height="10" rx="2" fill="' + (fills[e] || barCol(e)) + '"/>';
1211
+ var j = e - k, c = lineCol(j), dk = dashOf ? DASHES[dashOf(j)] : "", mk = markOf ? markOf(j) : "none";
1212
+ return '<line x1="' + r2(x) + '" x2="' + r2(x + 18) + '" y1="' + r2(y + 6) + '" y2="' + r2(y + 6) + '" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round"' + (dk ? ' stroke-dasharray="' + dk + '"' : "") + "/>" + (mk !== "none" ? marker(mk, x + 9, y + 6, 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"') : "");
1213
+ };
1214
+ var tops = [], bottoms = [];
1215
+ for (var i = 0; i < n; i++) {
1216
+ var up = 0, down = 0;
1217
+ B.forEach(function(s) {
1218
+ var v = val(s, i);
1219
+ if (stacked) {
1220
+ if (v >= 0) up += v;
1221
+ else down += v;
1222
+ } else {
1223
+ up = Math.max(up, v);
1224
+ down = Math.min(down, v);
1225
+ }
1226
+ });
1227
+ tops.push(up);
1228
+ bottoms.push(down);
1229
+ }
1230
+ return tile(o, th, h, function(x0, y0, w, h2) {
1231
+ if (!n || !k) return emptyState(th, x0, y0, w, h2);
1232
+ var s = defs ? "<defs>" + defs + "</defs>" : "", top = y0;
1233
+ var lg = legend(B.map(function(_, j) {
1234
+ return barName(j);
1235
+ }).concat(L.map(function(_, j) {
1236
+ return lineName(j);
1237
+ })), pal, th, x0, top, w, key, 24);
1238
+ s += lg.svg;
1239
+ top += lg.height;
1240
+ var titled = has(o.yLabel) || has(o.lineLabel);
1241
+ if (titled) top += 16;
1242
+ var sc = niceScale(Math.min.apply(null, bottoms), Math.max.apply(null, tops), 4), steps = sc.ticks.length - 1;
1243
+ var all = [].concat.apply([], L);
1244
+ var lmin = Math.min.apply(null, all), lmax = Math.max.apply(null, all);
1245
+ if (bool(o.lineZero)) {
1246
+ lmin = Math.min(0, lmin);
1247
+ lmax = Math.max(0, lmax);
1248
+ }
1249
+ var sc2 = m ? matched(lmin, lmax, steps) : null;
1250
+ var tl = sc.ticks.map(function(t2) {
1251
+ return fmt(t2, o, true);
1252
+ }), tr = sc2 ? sc2.ticks.map(function(t2) {
1253
+ return fmt(t2, lo, true);
1254
+ }) : [];
1255
+ var lw = Math.max.apply(null, tl.map(function(t2) {
1256
+ return tw(t2, 10, true);
1257
+ })) + 10;
1258
+ var rw = sc2 ? Math.max.apply(null, tr.map(function(t2) {
1259
+ return tw(t2, 10, true);
1260
+ })) + 10 : 0;
1261
+ var px = x0 + lw, pw = w - lw - rw, ph = h2 - (top - y0) - (labels.length ? 20 : 4), band = pw / n;
1262
+ var X = function(i2) {
1263
+ return px + band * (i2 + 0.5);
1264
+ };
1265
+ var Y = function(v) {
1266
+ return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph;
1267
+ };
1268
+ var Y2 = function(v) {
1269
+ return top + ph - (v - sc2.lo) / (sc2.hi - sc2.lo) * ph;
1270
+ };
1271
+ sc.ticks.forEach(function(t2, i2) {
1272
+ var y = Y(t2);
1273
+ s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t2 === 0 ? "" : ' stroke-dasharray="2 4"') + "/>" + text(px - 8, y + 3.5, tl[i2], small(th, 10, 'text-anchor="end"')) + (sc2 ? text(px + pw + 8, y + 3.5, tr[i2], small(th, 10, 'text-anchor="start"')) : "");
1274
+ });
1275
+ var leftC = k === 1 ? barCol(0) : th.muted, rightC = m === 1 ? lineCol(0) : th.muted;
1276
+ s += '<line x1="' + r2(px) + '" x2="' + r2(px) + '" y1="' + r2(top) + '" y2="' + r2(top + ph) + '" stroke="' + leftC + '" stroke-width="2"/>';
1277
+ if (sc2) s += '<line x1="' + r2(px + pw) + '" x2="' + r2(px + pw) + '" y1="' + r2(top) + '" y2="' + r2(top + ph) + '" stroke="' + rightC + '" stroke-width="2"/>';
1278
+ if (has(o.yLabel)) s += text(x0, top - 8, o.yLabel, small(th, 10, "", k === 1 ? leftC : th.fg));
1279
+ if (has(o.lineLabel) && sc2) s += text(x0 + w, top - 8, o.lineLabel, small(th, 10, 'text-anchor="end"', m === 1 ? rightC : th.fg));
1280
+ if (labels.length) {
1281
+ var every = Math.max(1, Math.ceil((Math.max.apply(null, labels.map(function(l) {
1282
+ return tw(l, 10, true);
1283
+ })) + 10) / band));
1284
+ for (i = 0; i < n; i += every) if (labels[i] != null) s += text(X(i), top + ph + 15, labels[i], small(th, 10, 'text-anchor="middle"'));
1285
+ }
1286
+ var gw = band * 0.72, bw = stacked ? gw : gw / k;
1287
+ for (i = 0; i < n; i++) {
1288
+ var up2 = 0, down2 = 0;
1289
+ B.forEach(function(ser, j) {
1290
+ if (i >= ser.length) return;
1291
+ var v = ser[i], a, b, x = stacked ? X(i) - gw / 2 : X(i) - gw / 2 + j * bw;
1292
+ if (stacked) {
1293
+ if (v >= 0) {
1294
+ a = up2;
1295
+ up2 += v;
1296
+ b = up2;
1297
+ } else {
1298
+ a = down2;
1299
+ down2 += v;
1300
+ b = down2;
1301
+ }
1302
+ } else {
1303
+ a = 0;
1304
+ b = v;
1305
+ }
1306
+ var ya = Y(a), yb = Y(b);
1307
+ s += '<rect x="' + r2(x + 0.5) + '" y="' + r2(Math.min(ya, yb)) + '" width="' + r2(Math.max(1, bw - 1)) + '" height="' + r2(Math.abs(yb - ya)) + '" rx="2" fill="' + (fills[j] || barCol(j)) + '"' + anim(o, v < 0 ? "bzc-gn" : "bzc-g", Math.min(0.6, i * 0.04)) + "/>";
1308
+ });
1309
+ }
1310
+ L.forEach(function(ser, j) {
1311
+ var c = lineCol(j), P = ser.map(function(v, i2) {
1312
+ return [X(i2), Y2(v)];
1313
+ }), mk = markOf ? markOf(j) : "none";
1314
+ s += seriesLine(o, pathOf(P, bool(o.straight)), c, j, dashOf ? DASHES[dashOf(j)] : "");
1315
+ if (mk !== "none") s += pointMarks(o, mk, ser, X, Y2, c, bg, j);
1316
+ else s += '<circle cx="' + r2(P[P.length - 1][0]) + '" cy="' + r2(P[P.length - 1][1]) + '" r="4" fill="' + c + '" stroke="' + bg + '" stroke-width="2"/>';
1317
+ });
1318
+ for (i = 0; i < n; i++) {
1319
+ var tip = labels[i] || "#" + (i + 1), t = 0;
1320
+ B.forEach(function(ser, j) {
1321
+ if (i < ser.length) {
1322
+ tip += "\n" + barName(j) + ": " + fmt(ser[i], o);
1323
+ t += ser[i];
1324
+ }
1325
+ });
1326
+ if (stacked) tip += "\nTotal: " + fmt(t, o);
1327
+ L.forEach(function(ser, j) {
1328
+ if (i < ser.length) tip += "\n" + lineName(j) + ": " + fmt(ser[i], lo);
1329
+ });
1330
+ s += hit(X(i) - band / 2, top, band, ph, tip);
1331
+ }
1332
+ return s;
1333
+ }, { summary: k + " bar series" + (stacked ? " stacked" : "") + " and " + m + (m === 1 ? " line" : " lines") + " over " + n + " points" });
1334
+ }
1335
+ combo.table = function(o) {
1336
+ var B = series(o.values), L = series(o.line), labels = list(o.labels), bn = list(o.series), ln = list(o.lineSeries);
1337
+ var k = B.length, m = L.length, stacked = k > 1 && bool(o.stacked), lo = lineOpts(o), rows = [];
1338
+ var n = Math.max.apply(null, [0].concat(B.concat(L).map(function(s) {
1339
+ return s.length;
1340
+ })));
1341
+ for (var i = 0; i < n; i++) {
1342
+ var row = [labels[i] || "#" + (i + 1)], t = 0;
1343
+ B.forEach(function(s) {
1344
+ row.push(i < s.length ? fmt(s[i], o) : "");
1345
+ t += i < s.length ? s[i] : 0;
1346
+ });
1347
+ if (stacked) row.push(fmt(t, o));
1348
+ L.forEach(function(s) {
1349
+ row.push(i < s.length ? fmt(s[i], lo) : "");
1350
+ });
1351
+ rows.push(row);
1352
+ }
1353
+ return {
1354
+ head: ["Label"].concat(
1355
+ B.map(function(_, j) {
1356
+ return bn[j] || (k === 1 ? "Bars" : "Bars " + (j + 1));
1357
+ }),
1358
+ stacked ? ["Total"] : [],
1359
+ L.map(function(_, j) {
1360
+ return ln[j] || (m === 1 ? "Line" : "Line " + (j + 1));
1361
+ })
1362
+ ),
1363
+ rows
1364
+ };
1365
+ };
1366
+ function lineOpts(o) {
1367
+ return { prefix: o.linePrefix, suffix: o.lineSuffix, decimals: o.lineDecimals, compact: o.compact, lang: o.lang };
1368
+ }
1369
+ function matched(min, max, n) {
1370
+ if (min === max) {
1371
+ if (min === 0) max = 1;
1372
+ else {
1373
+ var p = Math.abs(min) * 0.1;
1374
+ min -= p;
1375
+ max += p;
1376
+ }
1377
+ }
1378
+ var mag = Math.pow(10, Math.floor(Math.log10((max - min) / n))), steps = [1, 2, 5, 10], i = 0, step, lo;
1379
+ for (; ; ) {
1380
+ step = steps[i] * mag;
1381
+ lo = Math.floor(min / step) * step;
1382
+ if (lo + n * step >= max - step * 1e-9) break;
1383
+ if (++i === 4) {
1384
+ i = 1;
1385
+ mag *= 10;
1386
+ }
1387
+ }
1388
+ var ticks = [];
1389
+ for (var t = 0; t <= n; t++) ticks.push(+(lo + t * step).toFixed(10));
1390
+ return { lo: ticks[0], hi: ticks[n], ticks };
1391
+ }
1392
+
1393
+ // src/entries/combo.js
1394
+ register("combo", combo);
1395
+ define("combo");
1396
+
1172
1397
  // src/charts/histogram.js
1173
1398
  function histogram(o, th) {
1174
1399
  var b = binned(o), names = list(o.series), pal = palette(o, th), h = num(o.height, 190);
@@ -1992,7 +2217,7 @@ register("heatmap", heatmap);
1992
2217
  define("heatmap");
1993
2218
 
1994
2219
  // src/index.js
1995
- var version = "1.6.0";
2220
+ var version = "1.7.0";
1996
2221
  var types = NAMES.slice();
1997
2222
  export {
1998
2223
  BezelChart,