Christopher Johnson (WMDE) has submitted this change and it was merged.
Change subject: progress commit on overhaul of stats logic
......................................................................
progress commit on overhaul of stats logic
the object of this is to eliminate inaccuracy in reporting
when tasks undergo several state changes in a single day
Change-Id: I663daf0c86e9cf246a605b0b42f540391a59bef5
---
M rsrc/behavior-c3-chart.js
M src/celerity/map.php
M src/storage/SprintBuildStats.php
M src/storage/SprintTransaction.php
M src/util/BurndownDataDate.php
M src/view/BurndownDataView.php
6 files changed, 227 insertions(+), 87 deletions(-)
Approvals:
Christopher Johnson (WMDE): Verified; Looks good to me, approved
diff --git a/rsrc/behavior-c3-chart.js b/rsrc/behavior-c3-chart.js
index ab45edd..f52c959 100644
--- a/rsrc/behavior-c3-chart.js
+++ b/rsrc/behavior-c3-chart.js
@@ -17,7 +17,7 @@
type: 'line',
types: {
'Ideal Points': 'spline',
- 'Points Today': 'bar'
+ 'Points Closed Today': 'bar'
},
},
axis: {
diff --git a/src/celerity/map.php b/src/celerity/map.php
index ba3674b..b11d88c 100644
--- a/src/celerity/map.php
+++ b/src/celerity/map.php
@@ -7,9 +7,9 @@
*/
return array(
'names' => array(
- 'behavior-c3-chart.js' => '339d1b90',
+ 'behavior-c3-chart.js' => '89d978a3',
'behavior-c3-pie.js' => '4731bdd9',
- 'behavior-sprint-boards.js' => '6ce2b136',
+ 'behavior-sprint-boards.js' => 'b2754b95',
'c3.css' => '93642428',
'c3.js' => '4b517cca',
'd3.min.js' => '1595fbde',
@@ -18,9 +18,9 @@
'c3' => '4b517cca',
'c3-css' => '93642428',
'd3' => '1595fbde',
- 'javelin-behavior-c3-chart' => '339d1b90',
+ 'javelin-behavior-c3-chart' => '89d978a3',
'javelin-behavior-c3-pie' => '4731bdd9',
- 'javelin-behavior-sprint-boards' => '6ce2b136',
+ 'javelin-behavior-sprint-boards' => 'b2754b95',
),
'requires' => array(
'4b517cca' => array(
diff --git a/src/storage/SprintBuildStats.php b/src/storage/SprintBuildStats.php
index db384fd..77f15c5 100644
--- a/src/storage/SprintBuildStats.php
+++ b/src/storage/SprintBuildStats.php
@@ -2,6 +2,8 @@
final class SprintBuildStats {
private $timezone;
+ private $tasks_remaining;
+ private $points_remaining;
public function setTimezone ($viewer) {
$this->timezone = new DateTimeZone($viewer->getTimezoneIdentifier());
@@ -37,19 +39,92 @@
// Now that we have the data for each day, we need to loop over and sum
// up the relevant columns
public function sumSprintStats($dates) {
- $previous = null;
- foreach ($dates as $current) {
- $current->setTasksTotal($current->getTasksAddedToday());
- $current->setPointsTotal($current->getPointsAddedToday());
- $current->setTasksRemaining($current->getTasksAddedToday() -
$current->getTasksClosedToday());
- $current->setPointsRemaining($current->getPointsAddedToday() -
$current->getPointsClosedToday());
- if ($previous) {
- $current->sumTasksTotal($current, $previous);
- $current->sumPointsTotal($current, $previous);
- $current->sumTasksRemaining($current, $previous);
- $current->sumPointsRemaining ($current, $previous);
+ $this->sumTasksTotal($dates);
+ $this->calcTasksRemaining($dates);
+ $this->sumPointsTotal($dates);
+ $this->calcPointsRemaining($dates);
+ return $dates;
+
+ }
+
+ public function sumTasksTotal($dates) {
+ $first = true;
+ $previous = new BurndownDataDate($date=null);
+ foreach ($dates as $date) {
+ $tasks_added = $date->getTasksAddedToday();
+ if ($first) {
+ $date->setTasksTotal($tasks_added);
+ } else {
+ $tasks_total = $date->sumTasksTotal($date, $previous);
+ $date->setTasksTotal($tasks_total);
}
- $previous = $current;
+ $previous = $date;
+ $first = false;
+ }
+ return $dates;
+ }
+
+ public function sumPointsTotal($dates) {
+ $first = true;
+ $previous = new BurndownDataDate($date=null);
+ foreach ($dates as $date) {
+ $points_added = $date->getPointsAddedToday();
+ if ($first) {
+ $points_before = $this->getPointsBefore();
+ $points_total = $points_added + $points_before;
+ $date->setPointsTotal($points_total);
+ } else {
+ $points_total = $date->sumPointsTotal($date, $previous);
+ $date->setPointsTotal($points_total);
+ }
+ $previous = $date;
+ $first = false;
+ }
+ return $dates;
+ }
+
+ public function calcPointsRemaining($dates) {
+ $first = true;
+ foreach ($dates as $date) {
+ $points_added = $date->getPointsAddedToday();
+ $points_closed = $date->getPointsClosedToday();
+ $points_reopened = $date->getPointsReopenedToday();
+ $points_removed = $date->getPointsRemovedToday();
+ if ($first) {
+ $points_total = ($points_added + $points_reopened) - ($points_removed
+ $points_closed);
+ $net_change = 0;
+ } else {
+ $points_total = $this->points_remaining;
+ $net_change = ($points_added + $points_reopened) - ($points_removed +
$points_closed);
+ }
+ $points_diff = abs($net_change);
+ $points_remaining = $points_total - $points_diff;
+ $date->setPointsRemaining($points_remaining);
+ $this->points_remaining = $points_remaining;
+ $first = false;
+ }
+ return $dates;
+ }
+
+ public function calcTasksRemaining($dates) {
+ $first = true;
+ foreach ($dates as $date) {
+ $tasks_added = $date->getTasksAddedToday();
+ $tasks_closed = $date->getTasksClosedToday();
+ $tasks_reopened = $date->getTasksReopenedToday();
+ $tasks_removed = $date->getTasksRemovedToday();
+ if ($first) {
+ $tasks_total = ($tasks_added + $tasks_reopened) - ($tasks_removed +
$tasks_closed);
+ $net_change = 0;
+ } else {
+ $tasks_total = $this->tasks_remaining;
+ $net_change = ($tasks_added + $tasks_reopened) - ($tasks_removed +
$tasks_closed);
+ }
+ $tasks_diff = abs($net_change);
+ $tasks_remaining = $tasks_total - $tasks_diff;
+ $date->setTasksRemaining($tasks_remaining);
+ $this->tasks_remaining = $tasks_remaining;
+ $first = false;
}
return $dates;
}
@@ -83,7 +158,7 @@
pht('Total Points'),
pht('Remaining Points'),
pht('Ideal Points'),
- pht('Points Today'),
+ pht('Points Closed Today'),
));
$future = false;
diff --git a/src/storage/SprintTransaction.php
b/src/storage/SprintTransaction.php
index 29132e9..834956f 100644
--- a/src/storage/SprintTransaction.php
+++ b/src/storage/SprintTransaction.php
@@ -17,15 +17,32 @@
$query = id(new SprintQuery());
foreach ($events as $event) {
+ $date = null;
$xaction = $xactions[$event['transactionPHID']];
$xaction_date = $xaction->getDateCreated();
+ $task_phid = $xaction->getObjectPHID();
+ $points = $query->getStoryPoints($task_phid);
- // Determine which date to attach this data to
- $date = null;
- if ($xaction_date >= $start && $xaction_date <= $end) {
- $task_phid = $xaction->getObjectPHID();
- $points = $query->getStoryPoints($task_phid);
- $date = phabricator_format_local_time($xaction_date, $this->viewer, 'D
M j');
+ $sprint_start = phabricator_format_local_time($start, $this->viewer, 'D
M j');
+ $date = phabricator_format_local_time($xaction_date, $this->viewer, 'D M
j');
+
+ if ( $xaction_date < $start ) {
+
+ switch ($event['type']) {
+ case "task-add":
+ $this->SumTasksBefore($sprint_start, $dates);
+ break;
+ case "points":
+ // Points were changed
+ $old_point_value = $xaction->getOldValue();
+ $this->SetPointsBefore($sprint_start, $task_phid, $points,
$old_point_value, $dates);
+ break;
+ }
+ }
+
+ // Determine which date to attach this data to
+
+ if ( $xaction_date > $start && $xaction_date < $end ) {
switch ($event['type']) {
case "create":
@@ -60,6 +77,7 @@
// Points were changed
$old_point_value = $xaction->getOldValue();
$this->changePoints($date, $task_phid, $points,
$old_point_value, $dates);
+ $this->closePoints($date, $task_phid, $points, $old_point_value,
$dates);
break;
}
}
@@ -93,7 +111,7 @@
}
private function ReopenedTasksToday($date, $dates) {
- $dates[$date]->setTasksReopenedToday();
+ $dates[$date]->setTasksReopenedToday();
return $dates;
}
@@ -103,7 +121,7 @@
}
private function RemovePointsToday($date, $points, $dates) {
- $dates[$date]->setPointsRemovedToday($points);
+ $dates[$date]->setPointsRemovedToday($points);
return $dates;
}
@@ -137,17 +155,32 @@
return $this->task_statuses[$task_phid];
}
+ private function SetPointsBefore($points, $old_point_value, $dates) {
+ foreach ($dates as $date) {
+ $before = $points - $old_point_value;
+ $this->setPointsBefore = $before;
+ }
+ }
+
+ private function SumTasksBefore($sprint_start, $dates) {
+ $dates[$sprint_start]->setTasksAddedToday();
+ return $dates;
+ }
+
private function changePoints($date, $task_phid, $points, $old_point_value,
$dates) {
- // Adjust points for that day
- $this->task_points[$task_phid] = $points - $old_point_value;
- $dates[$date]->setPointsAddedToday($this->task_points[$task_phid]);
-
- // If the task is closed, adjust completed points as well
- if (isset($this->task_statuses[$task_phid]) &&
$this->task_statuses[$task_phid] == 'closed') {
- $this->task_points[$task_phid] = $points - $old_point_value;
- $dates[$date]->setPointsClosedToday($this->task_points[$task_phid]);
- }
+ // Adjust points for that day
+ $this->task_points[$task_phid] = $points - $old_point_value;
+ $dates[$date]->setPointsAddedToday($this->task_points[$task_phid]);
return $dates;
}
+
+ private function closePoints($date, $task_phid, $points, $old_point_value,
$dates)
+ {
+ // If the task is closed, adjust completed points as well
+ if (isset($this->task_statuses[$task_phid]) &&
$this->task_statuses[$task_phid] == 'closed') {
+ $this->task_points[$task_phid] = $points - $old_point_value;
+ $dates[$date]->setPointsClosedToday($this->task_points[$task_phid]);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/util/BurndownDataDate.php b/src/util/BurndownDataDate.php
index bb2d4e3..30dd899 100644
--- a/src/util/BurndownDataDate.php
+++ b/src/util/BurndownDataDate.php
@@ -9,12 +9,17 @@
private $date;
private $tasks_added_today;
private $tasks_closed_today;
+ private $tasks_removed_today;
+ private $tasks_reopened_today;
private $points_added_today;
private $points_closed_today;
+ private $points_removed_today;
+ private $points_reopened_today;
// Totals over time
private $tasks_total;
private $tasks_remaining;
+ private $points_before;
private $points_total;
private $points_remaining;
private $points_ideal_remaining;
@@ -24,66 +29,45 @@
return $this;
}
- // Tasks and points added and closed today
+
+ public function setTasksAddedToday () {
+ return $this->tasks_added_today = $this->tasks_added_today +1;
+ return $this;
+ }
+
public function getTasksAddedToday () {
return $this->tasks_added_today;
+ }
+
+ public function setTasksRemovedToday () {
+ return $this->tasks_removed_today = $this->tasks_removed_today + 1;
+ return $this;
+ }
+
+ public function setTasksClosedToday () {
+ return $this->tasks_closed_today = $this->tasks_closed_today + 1;
+ return $this;
}
public function getTasksClosedToday () {
return $this->tasks_closed_today;
}
- public function setTasksAddedToday () {
- return $this->tasks_added_today = $this->tasks_added_today +1;
+ public function setTasksReopenedToday () {
+ return $this->tasks_reopened_today = $this->tasks_reopened_today + 1;
+ return $this;
}
- public function setTasksRemovedToday ()
- {
- return $this->tasks_added_today = $this->tasks_added_today - 1;
+ public function getTasksReopenedToday () {
+ return $this->tasks_reopened_today;
}
- public function setTasksClosedToday ()
- {
- return $this->tasks_closed_today = $this->tasks_closed_today + 1;
- }
-
- public function setTasksReopenedToday ()
- {
- return $this->tasks_closed_today = $this->tasks_closed_today - 1;
- }
-
- public function getPointsAddedToday () {
- return $this->points_added_today;
- }
-
- public function getPointsClosedToday () {
- return $this->points_closed_today;
- }
-
- public function setPointsAddedToday ($task_points) {
- $this->points_added_today = $this->points_added_today + $task_points;
- return $this->points_added_today;
- }
-
- public function setPointsRemovedToday ($task_points) {
- return $this->points_added_today = $this->points_added_today -
$task_points;
- }
-
- public function setPointsClosedToday ($task_points) {
- return $this->points_closed_today = $this->points_closed_today +
$task_points;
- }
-
- public function setPointsReopenedToday ($task_points) {
- return $this->points_closed_today = $this->points_closed_today -
$task_points;
- }
-
- public function getDate() {
- return $this->date;
+ public function getTasksRemovedToday () {
+ return $this->tasks_reopened_today;
}
public function setTasksTotal($tasks_added_today) {
$this->tasks_total = $tasks_added_today;
- return $this->tasks_total ;
}
public function getTasksTotal() {
@@ -92,16 +76,58 @@
public function setTasksRemaining($tasks_remaining) {
$this->tasks_remaining = $tasks_remaining;
- return $this->tasks_remaining;
}
public function getTasksRemaining() {
return $this->tasks_remaining;
}
+ public function setPointsAddedToday ($points) {
+ $this->points_added_today = $points;
+ }
+
+ public function getPointsAddedToday () {
+ return $this->points_added_today;
+ }
+
+ public function setPointsClosedToday ($points) {
+ $this->points_closed_today = $points;
+ }
+
+ public function getPointsClosedToday () {
+ return $this->points_closed_today;
+ }
+
+ public function setPointsRemovedToday ($points) {
+ $this->points_removed_today = $points;
+ }
+
+ public function getPointsRemovedToday () {
+ return $this->points_removed_today;
+ }
+
+ public function setPointsReopenedToday ($points) {
+ $this->points_reopened_today = $points;
+ }
+
+ public function getPointsReopenedToday () {
+ return $this->points_reopened_today;
+ }
+
+ public function getDate() {
+ return $this->date;
+ }
+
+ public function setPointsBefore($points) {
+ $this->points_before = $this->points_before + $points;
+ }
+
+ public function getPointsBefore() {
+ return $this->points_before;
+ }
+
public function setPointsTotal($points_total) {
$this->points_total = $points_total;
- return $this->points_total;
}
public function getPointsTotal() {
@@ -110,7 +136,6 @@
public function setPointsRemaining($points_remaining) {
$this->points_remaining = $points_remaining;
- return $this->points_remaining;
}
public function getPointsRemaining() {
@@ -135,13 +160,20 @@
return $current->points_total;
}
- public function sumTasksRemaining($current, $previous) {
- $current->tasks_remaining = $previous->tasks_remaining +
$current->tasks_remaining;
- return $current->tasks_remaining;
+ public function sumTasksRemaining($added, $closed) {
+ $this->tasks_remaining = $added - $closed;
+ return $this->tasks_remaining;
}
public function sumPointsRemaining($current, $previous) {
- $current->points_remaining = $previous->points_remaining +
$current->points_remaining;
+ $current->points_remaining = $previous->points_remaining -
$current->points_remaining;
return $current->points_remaining;
}
+
+ public function changePoints($points, $old_point_value, $dates) {
+ // Adjust points for that day
+ $points = $points - $old_point_value;
+ return $this->setPointsAddedToday($points);
+ }
+
}
diff --git a/src/view/BurndownDataView.php b/src/view/BurndownDataView.php
index 7a44321..440af96 100644
--- a/src/view/BurndownDataView.php
+++ b/src/view/BurndownDataView.php
@@ -55,11 +55,11 @@
$stats = id(new SprintBuildStats());
$tasks = $query->getTasks();
$query->checkNull($start, $end, $tasks);
-
$timezone = $stats->setTimezone($this->viewer);
$dates = $stats->buildDateArray($start, $end, $timezone);
$this->timeseries = $stats->buildTimeSeries($start, $end);
+
$xactions = $query->getXactions($tasks);
$events = $query->getEvents($xactions, $tasks);
--
To view, visit https://gerrit.wikimedia.org/r/177017
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I663daf0c86e9cf246a605b0b42f540391a59bef5
Gerrit-PatchSet: 2
Gerrit-Project: phabricator/extensions/Sprint
Gerrit-Branch: master
Gerrit-Owner: Christopher Johnson (WMDE) <[email protected]>
Gerrit-Reviewer: Christopher Johnson (WMDE) <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits