Skip to content

Commit 058a909

Browse files
authored
Merge pull request #40 from pfizer-opensource/moving-range-with-click-event
Emit events with the work items info when clicking on a data point in the moving range chart
2 parents 2ea88b8 + 878ea00 commit 058a909

File tree

8 files changed

+75
-35
lines changed

8 files changed

+75
-35
lines changed

src/graphs/cfd/CFDRenderer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ class CFDRenderer extends UIControlsRenderer {
641641
let { cycleTimeDateBefore, averageCycleTime, biggestCycleTime, currentStateCumulativeCount, cycleTimesByState } =
642642
this.computeCycleTimeAndLeadTimeMetrics(currentDataEntry, filteredData, currentDate, currentStateIndex);
643643
const averageLeadTime = leadTimeDateBefore
644-
? Math.floor(calculateDaysBetweenDates(leadTimeDateBefore, currentDate).roundedDays)
644+
? Math.floor(calculateDaysBetweenDates(leadTimeDateBefore, currentDate).exactTimeDiff)
645645
: null;
646646
const noOfItemsBefore = this.#getNoOfItems(currentDataEntry, this.states[this.states.indexOf('delivered')]);
647647
const noOfItemsAfter = this.#getNoOfItems(currentDataEntry, this.states[this.states.indexOf('analysis_active')]);
@@ -682,7 +682,7 @@ class CFDRenderer extends UIControlsRenderer {
682682
let stateCumulativeCount = this.#getNoOfItems(currentDataEntry, this.states[i]);
683683
let cycleTimeDate = this.#computeCycleTimeDate(stateCumulativeCount, i, filteredData);
684684
cycleTimesByState[this.states[i + 1]] = cycleTimeDate
685-
? Math.floor(calculateDaysBetweenDates(cycleTimeDate, currentDate).roundedDays)
685+
? Math.floor(calculateDaysBetweenDates(cycleTimeDate, currentDate).exactTimeDiff)
686686
: null;
687687
if (cycleTimesByState[this.states[i + 1]] > biggestCycleTime) {
688688
biggestCycleTime = cycleTimesByState[this.states[i + 1]];

src/graphs/control-chart/ControlRenderer.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ class ControlRenderer extends ScatterplotRenderer {
4747
this.y.domain([minY, maxY]);
4848
}
4949

50+
populateTooltip(event) {
51+
this.tooltip
52+
.style('pointer-events', 'auto')
53+
.style('opacity', 0.9)
54+
.append('p')
55+
.style('text-decoration', 'underline')
56+
.text(`${event.deliveredDate}`);
57+
}
58+
5059
drawScatterplot(chartArea, data, x, y) {
5160
chartArea
5261
.selectAll(`.${this.dotClass}`)

src/graphs/moving-range/MovingRangeGraph.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ class MovingRangeGraph {
1212
this.dataSet.push({
1313
fromDate: new Date(this.data[i - 1].deliveredDate),
1414
deliveredDate: new Date(this.data[i].deliveredTimestamp * 1000),
15-
// leadTime: Math.floor(Math.abs(Number(this.data[i].exactLeadTime) - Number(this.data[i - 1].exactLeadTime))),
16-
leadTime: Math.floor(Math.abs(Number(this.data[i].leadTime) - Number(this.data[i - 1].leadTime))),
15+
leadTime: Math.abs(Number(this.data[i].leadTime) - Number(this.data[i - 1].leadTime)),
16+
workItem1: this.data[i - 1].ticketId,
17+
workItem2: this.data[i].ticketId,
1718
});
1819
}
1920
}

src/graphs/moving-range/MovingRangeRenderer.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ class MovingRangeRenderer extends ScatterplotRenderer {
55
color = '#0ea5e9';
66
timeScale = 'linear';
77

8-
constructor(data, avgMovingRange, chartName) {
8+
constructor(data, avgMovingRange, workTicketsURL, chartName) {
99
super(data);
1010
this.avgMovingRange = avgMovingRange;
11+
this.workTicketsURL = workTicketsURL;
1112
this.chartName = chartName;
1213
this.chartType = 'MOVING_RANGE';
1314
this.dotClass = 'moving-range-dot';
@@ -38,9 +39,19 @@ class MovingRangeRenderer extends ScatterplotRenderer {
3839
this.tooltip
3940
.style('pointer-events', 'auto')
4041
.style('opacity', 0.9)
41-
.append('p')
42+
.append('div')
43+
.append('a')
4244
.style('text-decoration', 'underline')
43-
.text(`${event.date}`);
45+
.attr('href', `${this.workTicketsURL}/${event.workItem1}`)
46+
.text(event.workItem1)
47+
.attr('target', '_blank');
48+
this.tooltip
49+
.append('div')
50+
.append('a')
51+
.style('text-decoration', 'underline')
52+
.attr('href', `${this.workTicketsURL}/${event.workItem2}`)
53+
.text(event.workItem1)
54+
.attr('target', '_blank');
4455
}
4556

4657
drawScatterplot(chartArea, data, x, y) {
@@ -55,7 +66,7 @@ class MovingRangeRenderer extends ScatterplotRenderer {
5566
.attr('cy', (d) => this.applyYScale(y, d.leadTime))
5667
.style('cursor', 'pointer')
5768
.attr('fill', this.color)
58-
.on('mouseover', (event, d) => this.handleMouseClickEvent(event, { date: d.deliveredDate }));
69+
.on('click', (event, d) => this.handleMouseClickEvent(event, { ...d, date: d.deliveredDate }));
5970

6071
// Define the line generator
6172
const line = d3

src/graphs/scatterplot/ScatterplotGraph.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,16 @@ class ScatterplotGraph {
6565
this.data.forEach((ticket) => {
6666
if (ticket.delivered) {
6767
const deliveredDate = new Date(ticket.delivered * 1000);
68-
deliveredDate.setHours(0, 0, 0, 0);
6968
const scatterplotTicket = {
7069
deliveredDate: deliveredDate,
7170
deliveredTimestamp: ticket.delivered,
7271
leadTime: 0,
73-
exactLeadTime: 0,
7472
ticketId: ticket.work_id,
7573
};
7674
for (const state of this.states) {
7775
if (ticket[state]) {
7876
const diff = calculateDaysBetweenDates(ticket[state], ticket.delivered);
79-
scatterplotTicket.leadTime = diff.roundedDays;
80-
scatterplotTicket.exactLeadTime = diff.exactTimeDiff;
77+
scatterplotTicket.leadTime = diff.exactTimeDiff;
8178
break;
8279
}
8380
}

src/graphs/scatterplot/ScatterplotRenderer.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
250250

251251
computeYScale() {
252252
// Start domain from a small positive value: 0.6 to avoid log(0) issues
253-
const yDomain = [0.6, d3.max(this.data, (d) => d.leadTime)];
253+
const yDomain = [0.5, d3.max(this.data, (d) => d.leadTime)];
254254

255255
if (this.timeScale === 'logarithmic') {
256256
this.y = d3
@@ -265,9 +265,9 @@ class ScatterplotRenderer extends UIControlsRenderer {
265265
}
266266

267267
applyYScale(yScale, value) {
268-
if (this.timeScale === 'logarithmic' && value <= 0) {
268+
if (this.timeScale === 'logarithmic' && value <= 0.5) {
269269
// Handle zero or negative values explicitly
270-
return yScale(0.6);
270+
return yScale(0.5);
271271
} else {
272272
return yScale(value);
273273
}
@@ -302,7 +302,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
302302
.append('rect')
303303
.attr('class', 'axis-background')
304304
.attr('x', 0)
305-
.attr('y', 0)
305+
.attr('y', 4)
306306
.attr('width', this.width)
307307
.attr('height', axisHeight)
308308
.attr('fill', 'gray')
@@ -312,7 +312,11 @@ class ScatterplotRenderer extends UIControlsRenderer {
312312
const xAxisGroup = g.attr('class', 'x-axis-group').attr('transform', `translate(0, ${height})`);
313313
xAxisGroup.call(axis);
314314
xAxisGroup.selectAll('.tick line').attr('stroke', 'black').attr('opacity', 0.3).attr('y1', 15).attr('y2', -this.height);
315-
xAxisGroup.selectAll('.tick text').attr('fill', 'black').attr('y', axisHeight).attr('dy', '10px');
315+
xAxisGroup
316+
.selectAll('.tick text')
317+
.attr('fill', 'black')
318+
.attr('y', axisHeight + 6)
319+
.attr('dy', '10px');
316320
xAxisGroup.select('.domain').remove();
317321
grayBand.on('mouseover', function () {
318322
d3.select(this)
@@ -343,10 +347,10 @@ class ScatterplotRenderer extends UIControlsRenderer {
343347
gy.call(yAxis).selectAll('.tick line').attr('opacity', 0.1);
344348

345349
if (this.timeScale === 'logarithmic') {
346-
// Manually add tick for 0.6 value which is rendered as value 0
350+
// Manually add tick for 0.5 value which is rendered as value 0
347351
gy.append('g')
348352
.attr('class', 'tick')
349-
.attr('transform', `translate(0, ${y(0.6)})`) // Position tick line at y(0.6)
353+
.attr('transform', `translate(0, ${y(0.5)})`) // Position tick line at y(0.5)
350354
.append('line')
351355
.attr('x2', this.width)
352356
.attr('stroke', 'black')
@@ -355,7 +359,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
355359
// Manually add text label for 0.6 value is rendered as value 0
356360
gy.append('g')
357361
.attr('class', 'tick')
358-
.attr('transform', `translate(0, ${y(0.6)})`) // Position text at y(0.6)
362+
.attr('transform', `translate(0, ${y(0.5)})`) // Position text at y(0.5)
359363
.append('text')
360364
.attr('x', -4)
361365
.attr('dy', '.32em')
@@ -515,8 +519,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
515519
*/
516520
handleMouseClickEvent(event, d) {
517521
let data = {
518-
date: d.date,
519-
ticketId: d.ticketId,
522+
...d,
520523
tooltipLeft: event.pageX,
521524
tooltipTop: event.pageY,
522525
};
@@ -531,8 +534,8 @@ class ScatterplotRenderer extends UIControlsRenderer {
531534
observationBody: observation?.body,
532535
observationId: observation?.id,
533536
};
534-
this.eventBus?.emitEvents(`${this.chartName}-click`, data);
535537
}
538+
this.eventBus?.emitEvents(`${this.chartName}-click`, data);
536539
this.showTooltip(data);
537540
}
538541

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import MovingRangeRenderer from './graphs/moving-range/MovingRangeRenderer.js';
88
import ControlRenderer from './graphs/control-chart/ControlRenderer.js';
99
import HistogramRenderer from './graphs/histogram/HistogramRenderer.js';
1010
import { eventBus } from './utils/EventBus.js';
11+
import { processServiceData } from './data-processor.js';
1112
import ObservationLoggingService from './graphs/ObservationLoggingService.js';
1213

1314
export {
@@ -22,4 +23,5 @@ export {
2223
HistogramRenderer,
2324
ObservationLoggingService,
2425
eventBus,
26+
processServiceData,
2527
};
Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
11
const scatterplotGraphOutput =
22
[
33
{
4-
"deliveredDate": "2023-03-20T22:00:00.000Z",
5-
"leadTime": 42,
6-
"ticketId": "T-91730136"
4+
deliveredDate: "2023-03-21T15:09:35.000Z",
5+
deliveredTimestamp: '1679411375',
6+
leadTime: 42.04,
7+
ticketId: 'T-91730136'
78
},
89
{
9-
"deliveredDate": "2023-04-03T21:00:00.000Z",
10-
"leadTime": 4,
11-
"ticketId": "T-91730806"
10+
deliveredDate: "2023-04-04T15:04:38.000Z",
11+
deliveredTimestamp: '1680620678',
12+
leadTime: 0.14,
13+
ticketId: 'T-91730847'
1214
},
1315
{
14-
"deliveredDate": "2023-04-04T21:00:00.000Z",
15-
"leadTime": 1,
16-
"ticketId": "T-91730832"
16+
deliveredDate: "2023-04-04T15:26:07.000Z",
17+
deliveredTimestamp: '1680621967',
18+
leadTime: 4.61,
19+
ticketId: 'T-91730806'
1720
},
1821
{
19-
"deliveredDate": "2023-04-13T21:00:00.000Z",
20-
"leadTime": 7,
21-
"ticketId": "T-91720964"
22+
deliveredDate: "2023-04-05T13:12:22.000Z",
23+
deliveredTimestamp: '1680700342',
24+
leadTime: 2,
25+
ticketId: 'T-91730832'
26+
},
27+
{
28+
deliveredDate: "2023-04-06T11:26:07.000Z",
29+
deliveredTimestamp: '1680780367',
30+
leadTime: 0.82,
31+
ticketId: 'T-91730873'
32+
},
33+
{
34+
deliveredDate: "2023-04-14T07:07:04.000Z",
35+
deliveredTimestamp: '1681456024',
36+
leadTime: 7.54,
37+
ticketId: 'T-91720964'
2238
}
2339
]
2440

41+
2542
export default scatterplotGraphOutput;

0 commit comments

Comments
 (0)