Skip to content

Commit

Permalink
Merge pull request #40 from pfizer-opensource/moving-range-with-click…
Browse files Browse the repository at this point in the history
…-event

Emit events with the work items info when clicking on a data point in the moving range chart
  • Loading branch information
ClaudiaGivan authored Sep 9, 2024
2 parents 2ea88b8 + 878ea00 commit 058a909
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/graphs/cfd/CFDRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ class CFDRenderer extends UIControlsRenderer {
let { cycleTimeDateBefore, averageCycleTime, biggestCycleTime, currentStateCumulativeCount, cycleTimesByState } =
this.computeCycleTimeAndLeadTimeMetrics(currentDataEntry, filteredData, currentDate, currentStateIndex);
const averageLeadTime = leadTimeDateBefore
? Math.floor(calculateDaysBetweenDates(leadTimeDateBefore, currentDate).roundedDays)
? Math.floor(calculateDaysBetweenDates(leadTimeDateBefore, currentDate).exactTimeDiff)
: null;
const noOfItemsBefore = this.#getNoOfItems(currentDataEntry, this.states[this.states.indexOf('delivered')]);
const noOfItemsAfter = this.#getNoOfItems(currentDataEntry, this.states[this.states.indexOf('analysis_active')]);
Expand Down Expand Up @@ -682,7 +682,7 @@ class CFDRenderer extends UIControlsRenderer {
let stateCumulativeCount = this.#getNoOfItems(currentDataEntry, this.states[i]);
let cycleTimeDate = this.#computeCycleTimeDate(stateCumulativeCount, i, filteredData);
cycleTimesByState[this.states[i + 1]] = cycleTimeDate
? Math.floor(calculateDaysBetweenDates(cycleTimeDate, currentDate).roundedDays)
? Math.floor(calculateDaysBetweenDates(cycleTimeDate, currentDate).exactTimeDiff)
: null;
if (cycleTimesByState[this.states[i + 1]] > biggestCycleTime) {
biggestCycleTime = cycleTimesByState[this.states[i + 1]];
Expand Down
9 changes: 9 additions & 0 deletions src/graphs/control-chart/ControlRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ class ControlRenderer extends ScatterplotRenderer {
this.y.domain([minY, maxY]);
}

populateTooltip(event) {
this.tooltip
.style('pointer-events', 'auto')
.style('opacity', 0.9)
.append('p')
.style('text-decoration', 'underline')
.text(`${event.deliveredDate}`);
}

drawScatterplot(chartArea, data, x, y) {
chartArea
.selectAll(`.${this.dotClass}`)
Expand Down
5 changes: 3 additions & 2 deletions src/graphs/moving-range/MovingRangeGraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class MovingRangeGraph {
this.dataSet.push({
fromDate: new Date(this.data[i - 1].deliveredDate),
deliveredDate: new Date(this.data[i].deliveredTimestamp * 1000),
// leadTime: Math.floor(Math.abs(Number(this.data[i].exactLeadTime) - Number(this.data[i - 1].exactLeadTime))),
leadTime: Math.floor(Math.abs(Number(this.data[i].leadTime) - Number(this.data[i - 1].leadTime))),
leadTime: Math.abs(Number(this.data[i].leadTime) - Number(this.data[i - 1].leadTime)),
workItem1: this.data[i - 1].ticketId,
workItem2: this.data[i].ticketId,
});
}
}
Expand Down
19 changes: 15 additions & 4 deletions src/graphs/moving-range/MovingRangeRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ class MovingRangeRenderer extends ScatterplotRenderer {
color = '#0ea5e9';
timeScale = 'linear';

constructor(data, avgMovingRange, chartName) {
constructor(data, avgMovingRange, workTicketsURL, chartName) {
super(data);
this.avgMovingRange = avgMovingRange;
this.workTicketsURL = workTicketsURL;
this.chartName = chartName;
this.chartType = 'MOVING_RANGE';
this.dotClass = 'moving-range-dot';
Expand Down Expand Up @@ -38,9 +39,19 @@ class MovingRangeRenderer extends ScatterplotRenderer {
this.tooltip
.style('pointer-events', 'auto')
.style('opacity', 0.9)
.append('p')
.append('div')
.append('a')
.style('text-decoration', 'underline')
.text(`${event.date}`);
.attr('href', `${this.workTicketsURL}/${event.workItem1}`)
.text(event.workItem1)
.attr('target', '_blank');
this.tooltip
.append('div')
.append('a')
.style('text-decoration', 'underline')
.attr('href', `${this.workTicketsURL}/${event.workItem2}`)
.text(event.workItem1)
.attr('target', '_blank');
}

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

// Define the line generator
const line = d3
Expand Down
5 changes: 1 addition & 4 deletions src/graphs/scatterplot/ScatterplotGraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,16 @@ class ScatterplotGraph {
this.data.forEach((ticket) => {
if (ticket.delivered) {
const deliveredDate = new Date(ticket.delivered * 1000);
deliveredDate.setHours(0, 0, 0, 0);
const scatterplotTicket = {
deliveredDate: deliveredDate,
deliveredTimestamp: ticket.delivered,
leadTime: 0,
exactLeadTime: 0,
ticketId: ticket.work_id,
};
for (const state of this.states) {
if (ticket[state]) {
const diff = calculateDaysBetweenDates(ticket[state], ticket.delivered);
scatterplotTicket.leadTime = diff.roundedDays;
scatterplotTicket.exactLeadTime = diff.exactTimeDiff;
scatterplotTicket.leadTime = diff.exactTimeDiff;
break;
}
}
Expand Down
25 changes: 14 additions & 11 deletions src/graphs/scatterplot/ScatterplotRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ class ScatterplotRenderer extends UIControlsRenderer {

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

if (this.timeScale === 'logarithmic') {
this.y = d3
Expand All @@ -265,9 +265,9 @@ class ScatterplotRenderer extends UIControlsRenderer {
}

applyYScale(yScale, value) {
if (this.timeScale === 'logarithmic' && value <= 0) {
if (this.timeScale === 'logarithmic' && value <= 0.5) {
// Handle zero or negative values explicitly
return yScale(0.6);
return yScale(0.5);
} else {
return yScale(value);
}
Expand Down Expand Up @@ -302,7 +302,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
.append('rect')
.attr('class', 'axis-background')
.attr('x', 0)
.attr('y', 0)
.attr('y', 4)
.attr('width', this.width)
.attr('height', axisHeight)
.attr('fill', 'gray')
Expand All @@ -312,7 +312,11 @@ class ScatterplotRenderer extends UIControlsRenderer {
const xAxisGroup = g.attr('class', 'x-axis-group').attr('transform', `translate(0, ${height})`);
xAxisGroup.call(axis);
xAxisGroup.selectAll('.tick line').attr('stroke', 'black').attr('opacity', 0.3).attr('y1', 15).attr('y2', -this.height);
xAxisGroup.selectAll('.tick text').attr('fill', 'black').attr('y', axisHeight).attr('dy', '10px');
xAxisGroup
.selectAll('.tick text')
.attr('fill', 'black')
.attr('y', axisHeight + 6)
.attr('dy', '10px');
xAxisGroup.select('.domain').remove();
grayBand.on('mouseover', function () {
d3.select(this)
Expand Down Expand Up @@ -343,10 +347,10 @@ class ScatterplotRenderer extends UIControlsRenderer {
gy.call(yAxis).selectAll('.tick line').attr('opacity', 0.1);

if (this.timeScale === 'logarithmic') {
// Manually add tick for 0.6 value which is rendered as value 0
// Manually add tick for 0.5 value which is rendered as value 0
gy.append('g')
.attr('class', 'tick')
.attr('transform', `translate(0, ${y(0.6)})`) // Position tick line at y(0.6)
.attr('transform', `translate(0, ${y(0.5)})`) // Position tick line at y(0.5)
.append('line')
.attr('x2', this.width)
.attr('stroke', 'black')
Expand All @@ -355,7 +359,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
// Manually add text label for 0.6 value is rendered as value 0
gy.append('g')
.attr('class', 'tick')
.attr('transform', `translate(0, ${y(0.6)})`) // Position text at y(0.6)
.attr('transform', `translate(0, ${y(0.5)})`) // Position text at y(0.5)
.append('text')
.attr('x', -4)
.attr('dy', '.32em')
Expand Down Expand Up @@ -515,8 +519,7 @@ class ScatterplotRenderer extends UIControlsRenderer {
*/
handleMouseClickEvent(event, d) {
let data = {
date: d.date,
ticketId: d.ticketId,
...d,
tooltipLeft: event.pageX,
tooltipTop: event.pageY,
};
Expand All @@ -531,8 +534,8 @@ class ScatterplotRenderer extends UIControlsRenderer {
observationBody: observation?.body,
observationId: observation?.id,
};
this.eventBus?.emitEvents(`${this.chartName}-click`, data);
}
this.eventBus?.emitEvents(`${this.chartName}-click`, data);
this.showTooltip(data);
}

Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import MovingRangeRenderer from './graphs/moving-range/MovingRangeRenderer.js';
import ControlRenderer from './graphs/control-chart/ControlRenderer.js';
import HistogramRenderer from './graphs/histogram/HistogramRenderer.js';
import { eventBus } from './utils/EventBus.js';
import { processServiceData } from './data-processor.js';
import ObservationLoggingService from './graphs/ObservationLoggingService.js';

export {
Expand All @@ -22,4 +23,5 @@ export {
HistogramRenderer,
ObservationLoggingService,
eventBus,
processServiceData,
};
41 changes: 29 additions & 12 deletions test/testData/ScatterplotGraphExpectedOutput.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
const scatterplotGraphOutput =
[
{
"deliveredDate": "2023-03-20T22:00:00.000Z",
"leadTime": 42,
"ticketId": "T-91730136"
deliveredDate: "2023-03-21T15:09:35.000Z",
deliveredTimestamp: '1679411375',
leadTime: 42.04,
ticketId: 'T-91730136'
},
{
"deliveredDate": "2023-04-03T21:00:00.000Z",
"leadTime": 4,
"ticketId": "T-91730806"
deliveredDate: "2023-04-04T15:04:38.000Z",
deliveredTimestamp: '1680620678',
leadTime: 0.14,
ticketId: 'T-91730847'
},
{
"deliveredDate": "2023-04-04T21:00:00.000Z",
"leadTime": 1,
"ticketId": "T-91730832"
deliveredDate: "2023-04-04T15:26:07.000Z",
deliveredTimestamp: '1680621967',
leadTime: 4.61,
ticketId: 'T-91730806'
},
{
"deliveredDate": "2023-04-13T21:00:00.000Z",
"leadTime": 7,
"ticketId": "T-91720964"
deliveredDate: "2023-04-05T13:12:22.000Z",
deliveredTimestamp: '1680700342',
leadTime: 2,
ticketId: 'T-91730832'
},
{
deliveredDate: "2023-04-06T11:26:07.000Z",
deliveredTimestamp: '1680780367',
leadTime: 0.82,
ticketId: 'T-91730873'
},
{
deliveredDate: "2023-04-14T07:07:04.000Z",
deliveredTimestamp: '1681456024',
leadTime: 7.54,
ticketId: 'T-91720964'
}
]


export default scatterplotGraphOutput;

0 comments on commit 058a909

Please sign in to comment.