pict-section-activitygraph 1.0.3 → 1.0.4

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": "pict-section-activitygraph",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Pict section that renders a stacked-bar activity timeline: one bar per period, stacked by type or actor, across parallel domains. Themed SVG, no chart dependency.",
5
5
  "main": "source/Pict-Section-ActivityGraph.js",
6
6
  "scripts": {
@@ -73,7 +73,7 @@ function _colorFor(pStackBy, pKey, pIndex)
73
73
  /**
74
74
  * pModel:
75
75
  * { Period, StackBy ('ActivityType'|'ActorKind'), Measure ('EventCount'|'Volume'),
76
- * LegendPosition ('top-left'|'top-right'|'bottom-left'|'bottom-right'|'none', default 'bottom-right'),
76
+ * LegendPosition ('top-left'|'top-right'|'bottom-left'|'bottom-right'|'none', default 'bottom-right'), Title (chart title; '' omits it, default 'System Activity'),
77
77
  * Columns: [ { Key, Title, Accent } ], Buckets: [ { PeriodStart, PeriodKey, Domain, ActivityType, ActorKind, EventCount, Volume } ] }
78
78
  */
79
79
  function buildSVG(pModel)
@@ -86,6 +86,8 @@ function buildSVG(pModel)
86
86
  let tmpBuckets = Array.isArray(tmpModel.Buckets) ? tmpModel.Buckets : [];
87
87
  let tmpLegendOptions = { 'top-left': 1, 'top-right': 1, 'bottom-left': 1, 'bottom-right': 1, 'none': 1 };
88
88
  let tmpLegendPosition = tmpLegendOptions[tmpModel.LegendPosition] ? tmpModel.LegendPosition : 'bottom-right';
89
+ // Title text; pass an empty string to omit it (e.g. when the host page already has its own heading).
90
+ let tmpTitle = (typeof tmpModel.Title === 'string') ? tmpModel.Title : 'System Activity';
89
91
 
90
92
  // --- geometry ---
91
93
  const WIDTH = 940;
@@ -148,7 +150,9 @@ function buildSVG(pModel)
148
150
  let tmpLegendRight = tmpLegendPosition.indexOf('right') >= 0;
149
151
  let tmpShowLegend = (tmpLegendPosition !== 'none') && (tmpStackKeys.length > 0);
150
152
 
151
- let tmpChartTop = TOP + ((tmpShowLegend && tmpLegendTop) ? LEGEND_H : 10);
153
+ // Without a title, reclaim its band so the chart starts higher.
154
+ let tmpTop = tmpTitle ? TOP : (TOP - 22);
155
+ let tmpChartTop = tmpTop + ((tmpShowLegend && tmpLegendTop) ? LEGEND_H : 10);
152
156
  const GROUP_H = 22; // a super-group (quarter/year) gets its own header band, so its label
153
157
  // never shares a line with the per-row date labels.
154
158
  // Count the super-group bands up front so the SVG height accounts for them.
@@ -160,8 +164,11 @@ function buildSVG(pModel)
160
164
  let tmpSVG = [];
161
165
  tmpSVG.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + WIDTH + ' ' + tmpHeight + '" width="100%" role="img" aria-label="System activity, one bar per ' + _esc(tmpPeriod) + ' stacked by ' + _esc(tmpStackBy) + ', each column scaled 0 to ' + tmpMaxTotal + '" font-family="-apple-system, Segoe UI, Roboto, sans-serif">');
162
166
 
163
- // title (always top-left)
164
- tmpSVG.push('<text x="0" y="' + (TOP - 22) + '" font-size="15" font-weight="600" fill="' + _C.text + '">System Activity</text>');
167
+ // title (top-left; omitted when Title is an empty string)
168
+ if (tmpTitle)
169
+ {
170
+ tmpSVG.push('<text x="0" y="' + (tmpTop - 22) + '" font-size="15" font-weight="600" fill="' + _C.text + '">' + _esc(tmpTitle) + '</text>');
171
+ }
165
172
 
166
173
  // legend: a swatch + label per stack key, placed per LegendPosition. The total width is measured
167
174
  // first so a right-aligned legend ends flush with the chart's right edge.
@@ -170,8 +177,8 @@ function buildSVG(pModel)
170
177
  let tmpItems = tmpStackKeys.map((pKey) => ({ Key: pKey, Color: tmpColorByKey[pKey], W: 16 + _esc(pKey).length * 6.8 }));
171
178
  let tmpTotalW = tmpItems.reduce((pSum, pItem) => pSum + pItem.W + 16, 0) - 16;
172
179
  let tmpLX = tmpLegendRight ? (WIDTH - PAD_R - tmpTotalW) : PAD_L;
173
- let tmpSwatchY = tmpLegendTop ? (TOP - 4) : (tmpBodyBottom + 14);
174
- let tmpTextY = tmpLegendTop ? (TOP + 5) : (tmpBodyBottom + 23);
180
+ let tmpSwatchY = tmpLegendTop ? (tmpTop - 4) : (tmpBodyBottom + 14);
181
+ let tmpTextY = tmpLegendTop ? (tmpTop + 5) : (tmpBodyBottom + 23);
175
182
  tmpItems.forEach((pItem) =>
176
183
  {
177
184
  tmpSVG.push('<rect x="' + tmpLX.toFixed(1) + '" y="' + tmpSwatchY + '" width="11" height="11" rx="2" fill="' + pItem.Color + '"/>');
@@ -26,6 +26,7 @@ const _DEFAULTS =
26
26
  StackBy: 'ActivityType',
27
27
  Measure: 'EventCount',
28
28
  LegendPosition: 'bottom-right',
29
+ Title: 'System Activity',
29
30
  Columns: [
30
31
  { Key: 'WorkItems', Title: 'Work Items', Accent: '#e0891e' },
31
32
  { Key: 'Knowledge', Title: 'Knowledge', Accent: '#3f7fd0' }
@@ -73,6 +74,7 @@ class PictViewActivityGraph extends libPictView
73
74
  StackBy: tmpConfig.StackBy || _DEFAULTS.StackBy,
74
75
  Measure: tmpConfig.Measure || _DEFAULTS.Measure,
75
76
  LegendPosition: tmpConfig.LegendPosition || _DEFAULTS.LegendPosition,
77
+ Title: (typeof tmpConfig.Title === 'string') ? tmpConfig.Title : _DEFAULTS.Title,
76
78
  Columns: Array.isArray(tmpConfig.Columns) ? tmpConfig.Columns : _DEFAULTS.Columns,
77
79
  Buckets: []
78
80
  };
@@ -149,6 +151,7 @@ class PictViewActivityGraph extends libPictView
149
151
  StackBy: this._State.StackBy,
150
152
  Measure: this._State.Measure,
151
153
  LegendPosition: this._State.LegendPosition,
154
+ Title: this._State.Title,
152
155
  Columns: this._State.Columns,
153
156
  Buckets: this._State.Buckets
154
157
  });