@hpcc-js/chart 2.81.10 → 2.83.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hpcc-js/chart",
3
- "version": "2.81.10",
3
+ "version": "2.83.1",
4
4
  "description": "hpcc-js - Viz Chart",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.es6",
@@ -78,5 +78,5 @@
78
78
  "url": "https://github.com/hpcc-systems/Visualization/issues"
79
79
  },
80
80
  "homepage": "https://github.com/hpcc-systems/Visualization",
81
- "gitHead": "6a9c3dabbcea36fec7d25461ca3149c4846926da"
81
+ "gitHead": "fed2428e5cdf328d07d8b5521e0ab9c18e2044fb"
82
82
  }
package/src/Axis.ts CHANGED
@@ -311,6 +311,7 @@ export class Axis extends SVGWidget {
311
311
  break;
312
312
  }
313
313
  }
314
+
314
315
  this.d3Axis
315
316
  .scale(this.d3Scale)
316
317
  .tickFormat(this.formatter)
@@ -550,7 +551,8 @@ export class Axis extends SVGWidget {
550
551
  const overlap = this.calcOverflow(element);
551
552
 
552
553
  const lowerPos: number = this.isHorizontal() ? overlap.left : this.height() - overlap.top - overlap.bottom;
553
- const upperPos: number = this.isHorizontal() ? this.width() - overlap.right : 0;
554
+ const upperPos: number = this.isHorizontal() ? this.width() - overlap.right - this.padding() : 0 + this.padding();
555
+
554
556
  this.range(this.reverse() ? [upperPos, lowerPos] : [lowerPos, upperPos]);
555
557
 
556
558
  const context = this;
@@ -703,6 +705,8 @@ export interface Axis {
703
705
  ordinalMappings(_: { [key: string]: string }): this;
704
706
  ordinalMappings(): { [key: string]: string };
705
707
  ordinalMappings_exists(): boolean;
708
+ padding(): number;
709
+ padding(_: number): this;
706
710
  }
707
711
 
708
712
  Axis.prototype.publish("title", null, "string", "Title");
@@ -726,3 +730,4 @@ Axis.prototype.publish("hidden", false, "boolean", "Hides axis when 'true'");
726
730
  Axis.prototype.publish("ordinalPaddingInner", 0.1, "number", "Determines the ratio of the range that is reserved for blank space between band (0->1)", null, { disable: (w: Axis) => w.type() !== "ordinal" });
727
731
  Axis.prototype.publish("ordinalPaddingOuter", 0.1, "number", "Determines the ratio of the range that is reserved for blank space before the first band and after the last band (0->1)", null, { disable: (w: Axis) => w.type() !== "ordinal" });
728
732
  Axis.prototype.publish("ordinalMappings", null, "object", "Alternative label mappings (icons)", null, { optional: true });
733
+ Axis.prototype.publish("padding", 0, "number", "Padding space at top of axis (pixels)", null, { optional: true });
package/src/Column.ts CHANGED
@@ -19,6 +19,7 @@ export class Column extends XYAxis {
19
19
 
20
20
  protected _linearGap: number;
21
21
  private textLocal = d3Local<Text>();
22
+ private stackedTextLocal = d3Local<Text>();
22
23
  private isHorizontal: boolean;
23
24
 
24
25
  constructor() {
@@ -87,6 +88,7 @@ export class Column extends XYAxis {
87
88
  if (this.useClonedPalette()) {
88
89
  this._palette = this._palette.cloneNotExists(this.paletteID() + "_" + this.id());
89
90
  }
91
+ const formatPct = d3Format(context.showValueAsPercentFormat());
90
92
 
91
93
  let dataLen = 10;
92
94
  let offset = 0;
@@ -111,34 +113,29 @@ export class Column extends XYAxis {
111
113
  .paddingInner(this.xAxisSeriesPaddingInner())
112
114
  .paddingOuter(0)
113
115
  ;
114
- const rowData = this.adjustedData(host);
115
116
  let domainSums = [];
116
117
  const seriesSums = [];
117
118
  const columnLength = this.columns().length;
118
- if (this.showValue()) {
119
- switch (this.showValueAsPercent()) {
120
- case "series":
121
- rowData.forEach((row) => {
122
- row.filter((_, idx) => idx > 0 && idx < columnLength).forEach((col, idx) => {
123
- if (seriesSums[idx + 1] === undefined) {
124
- seriesSums[idx + 1] = 0;
125
- }
126
- seriesSums[idx + 1] += col;
127
- });
119
+ const rowData = this.data();
120
+ if (this.showValue() && this.showValueAsPercent() === "series") {
121
+ rowData.forEach((row) => {
122
+ row.filter((_, idx) => idx > 0 && idx < columnLength).forEach((col, idx) => {
123
+ if (seriesSums[idx + 1] === undefined) {
124
+ seriesSums[idx + 1] = 0;
125
+ }
126
+ seriesSums[idx + 1] += col;
127
+ });
128
+ });
129
+ }
128
130
 
129
- });
130
- break;
131
- case "domain":
132
- domainSums = rowData.map(row => {
133
- return row.filter((cell, idx) => idx > 0 && idx < columnLength).reduce((sum, cell) => {
134
- return sum + cell;
135
- }, 0);
136
- });
137
- break;
138
- case null:
139
- default:
140
- }
131
+ if (this.showDomainTotal() || (this.showValue() && this.showValueAsPercent() === "domain")) {
132
+ domainSums = rowData.map(row => {
133
+ return row.filter((cell, idx) => idx > 0 && idx < columnLength).reduce((sum, cell) => {
134
+ return sum + cell;
135
+ }, 0);
136
+ });
141
137
  }
138
+
142
139
  const column = element.selectAll(".dataRow")
143
140
  .data(this.adjustedData(host))
144
141
  ;
@@ -206,11 +203,11 @@ export class Column extends XYAxis {
206
203
  switch (context.showValueAsPercent()) {
207
204
  case "series":
208
205
  const seriesSum = typeof dm.sum !== "undefined" ? dm.sum : seriesSums[d.idx];
209
- valueText = d3Format(context.showValueAsPercentFormat())(valueText / seriesSum);
206
+ valueText = formatPct(valueText / seriesSum);
210
207
  break;
211
208
  case "domain":
212
- const domainSum = typeof dm.sum !== "undefined" ? dm.sum : domainSums[d.idx];
213
- valueText = d3Format(context.showValueAsPercentFormat())(valueText / domainSum);
209
+ const domainSum = typeof dm.sum !== "undefined" ? dm.sum : domainSums[dataRowIdx];
210
+ valueText = formatPct(valueText / domainSum);
214
211
  break;
215
212
  case null:
216
213
  default:
@@ -395,7 +392,6 @@ export class Column extends XYAxis {
395
392
  pos.y = dataRect.y + (dataRect.height / 2);
396
393
  }
397
394
  } else { // Bar
398
-
399
395
  noRoomInside = dataRect.width < textSize.width;
400
396
  isOutside = !context.valueCentered() || noRoomInside;
401
397
 
@@ -436,7 +432,8 @@ export class Column extends XYAxis {
436
432
 
437
433
  // Prevent overlapping labels on stacked columns
438
434
  const columns = context.columns();
439
- const hideValue = isOutside && context.yAxisStacked() && columns.indexOf(d.column) !== columns.length - 1;
435
+ const hideValue = (context.yAxisStacked() && noRoomInside) ||
436
+ (isOutside && context.yAxisStacked() && columns.indexOf(d.column) !== columns.length - 1);
440
437
  context.textLocal.get(this)
441
438
  .pos(pos)
442
439
  .anchor(valueAnchor)
@@ -460,6 +457,59 @@ export class Column extends XYAxis {
460
457
  .style("opacity", 0)
461
458
  .remove()
462
459
  ;
460
+
461
+ const value4pos = host.yAxisStacked() ? domainSums[dataRowIdx] : Math.max(...dataRow.filter((_, idx) => idx > 0 && idx < columnLength));
462
+ const stackedTotalText = element.selectAll(".stackedTotalText").data(context.showDomainTotal() ? [domainSums[dataRowIdx]] : []);
463
+ const stackedTotalTextEnter = stackedTotalText.enter().append("g")
464
+ .attr("class", "stackedTotalText")
465
+ .each(function (this: SVGElement, d) {
466
+ context.stackedTextLocal.set(this, new Text().target(this).colorStroke_default("transparent"));
467
+ });
468
+ stackedTotalTextEnter.merge(stackedTotalText as any)
469
+ .each(function (this: SVGElement, d: any) {
470
+ const pos = { x: 0, y: 0 };
471
+ const domainPos = host.dataPos(dataRow[0]);
472
+ const valuePos = host.valuePos(value4pos);
473
+
474
+ const valueFontFamily = context.valueFontFamily();
475
+ const valueFontSize = context.valueFontSize();
476
+ const textSize = context.textSize(d, valueFontFamily, valueFontSize);
477
+
478
+ const isPositive = parseFloat(d) >= 0;
479
+ let valueAnchor: "start" | "middle" | "end" = "middle";
480
+ if (isHorizontal) {
481
+ pos.x = domainPos;
482
+ if (isPositive) {
483
+ pos.y = valuePos - textSize.height / 2;
484
+ } else {
485
+ pos.y = valuePos + textSize.height / 2;
486
+ }
487
+ } else {
488
+ valueAnchor = "start";
489
+ pos.y = domainPos;
490
+ if (isPositive) {
491
+ pos.x = valuePos + textSize.width / 2;
492
+ } else {
493
+ pos.x = valuePos - textSize.width / 2;
494
+ }
495
+ }
496
+
497
+ context.stackedTextLocal.get(this)
498
+ .pos(pos)
499
+ .anchor(valueAnchor)
500
+ .fontFamily(valueFontFamily)
501
+ .fontSize(valueFontSize)
502
+ .text(d)
503
+ .render()
504
+ ;
505
+
506
+ });
507
+ stackedTotalText.exit()
508
+ .each(function (this: SVGElement, d) {
509
+ context.textLocal.get(this).target(null);
510
+ })
511
+ .remove()
512
+ ;
463
513
  });
464
514
  column.exit().transition().duration(duration)
465
515
  .remove()
@@ -554,6 +604,8 @@ export interface Column {
554
604
  showValueAsPercent(_: null | "series" | "domain"): this;
555
605
  showValueAsPercentFormat(): string;
556
606
  showValueAsPercentFormat(_: string): this;
607
+ showDomainTotal(): boolean;
608
+ showDomainTotal(_: boolean): this;
557
609
  valueCentered(): boolean;
558
610
  valueCentered(_: boolean): this;
559
611
  valueAnchor(): "start" | "middle" | "end";
@@ -589,6 +641,7 @@ Column.prototype.publish("showInnerText", false, "boolean", "Show Label in colum
589
641
  Column.prototype.publish("showValueFormat", ",", "string", "D3 Format for Value", null, { disable: (w: Column) => !w.showValue() || !!w.showValueAsPercent() });
590
642
  Column.prototype.publish("showValueAsPercent", null, "set", "If showValue is true, optionally show value as a percentage by Series or Domain", [null, "series", "domain"], { disable: w => !w.showValue(), optional: true });
591
643
  Column.prototype.publish("showValueAsPercentFormat", ".0%", "string", "D3 Format for %", null, { disable: (w: Column) => !w.showValue() || !w.showValueAsPercent() });
644
+ Column.prototype.publish("showDomainTotal", false, "boolean", "Show Total Value for Stacked Columns", null);
592
645
  Column.prototype.publish("valueCentered", false, "boolean", "Show Value in center of column");
593
646
  Column.prototype.publish("valueAnchor", "middle", "set", "text-anchor for shown value text", ["start", "middle", "end"]);
594
647
  Column.prototype.publish("xAxisSeriesPaddingInner", 0, "number", "Determines the ratio of the range that is reserved for blank space between band (0->1)");
package/src/XYAxis.ts CHANGED
@@ -750,6 +750,10 @@ export interface XYAxis {
750
750
  regions(_: object[]): this;
751
751
  layers(): XYAxis[];
752
752
  layers(_: XYAxis[]): this;
753
+ xAxisPadding(): number;
754
+ xAxisPadding(_: number): this;
755
+ yAxisPadding(): number;
756
+ yAxisPadding(_: number): this;
753
757
  }
754
758
 
755
759
  XYAxis.prototype.publish("orientation", "horizontal", "set", "Selects orientation for the axis", ["horizontal", "vertical"]);
@@ -795,3 +799,5 @@ XYAxis.prototype.publish("yAxisGuideLines", true, "boolean", "Y-Axis Guide Lines
795
799
  XYAxis.prototype.publishProxy("yAxisHidden", "valueAxis", "hidden");
796
800
  XYAxis.prototype.publish("regions", [], "array", "Regions");
797
801
  XYAxis.prototype.publish("layers", [], "widgetArray", "Layers", null, { render: false });
802
+ XYAxis.prototype.publishProxy("xAxisPadding", "domainAxis", "padding");
803
+ XYAxis.prototype.publishProxy("yAxisPadding", "valueAxis", "padding");
@@ -1,3 +1,3 @@
1
1
  export const PKG_NAME = "@hpcc-js/chart";
2
- export const PKG_VERSION = "2.81.10";
3
- export const BUILD_VERSION = "2.104.37";
2
+ export const PKG_VERSION = "2.83.1";
3
+ export const BUILD_VERSION = "2.105.2";