Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dashboard] Fix study progression performance #5887

Merged
merged 3 commits into from
Jan 6, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 63 additions & 55 deletions modules/dashboard/ajax/get_scan_line_data.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,94 +25,102 @@

$DB = Database::singleton();

$scanData = array();
$scanStartDate = $DB->pselectOne(
$scanData = array();
$scanStartDate = $DB->pselectOne(
"SELECT MIN(pf.Value)
FROM parameter_file pf
JOIN parameter_type pt USING (ParameterTypeID)
WHERE pt.Name='acquisition_date'",
array()
);
$scanEndDate = $DB->pselectOne(
$scanEndDate = $DB->pselectOne(
"SELECT MAX(pf.Value)
FROM parameter_file pf
JOIN parameter_type pt USING (ParameterTypeID)
WHERE pt.Name='acquisition_date'",
array()
);
$scanData['labels']
= createLineChartLabels($scanStartDate, $scanEndDate);
$list_of_sites = Utility::getSiteList(true, false);

// Run a query to get all the data. Order matters to ensure that the labels
// are calculated in the correct order.
$data = $DB->pselect(
"SELECT s.CenterID,
CONCAT(MONTH(pf.Value), '-', YEAR(pf.Value)) as datelabel,
COUNT(distinct s.ID) as count
FROM files f
LEFT JOIN parameter_file pf USING (FileID)
LEFT JOIN session s ON (s.ID=f.SessionID)
JOIN parameter_type pt USING (ParameterTypeID)
WHERE pt.Name='acquisition_date'
GROUP BY MONTH(pf.Value), YEAR(pf.Value), s.CenterID
ORDER BY YEAR(pf.Value), MONTH(pf.Value), s.CenterID",
array()
);

$scanData['labels'] = createLineChartLabels($data);

$list_of_sites = Utility::getSiteList(true, false);
foreach ($list_of_sites as $siteID => $siteName) {
$scanData['datasets'][] = array(
"name" => $siteName,
"data" => getScanData($siteID, $scanData['labels']),
"data" => getScanData($data, $siteID, $scanData['labels'])
);
}

print json_encode($scanData);

return 0;

/**
* Create chart labels (dates)
* Massages the data passed into the format expected by the
* C3 library. Extracts the data for $siteID from $data, and
* ensures that each label has a value in the correct index
* of the returned array. Labels not in $data for site are
* given a value of 0.
*
* @param string $startDate start date of scans
* @param string $endDate end date of scans
* @param array $data The data to be extracted from.
* @param int $siteID The siteID to be extracted.
* @param array $labels A list of labels that should appear
* in the result in the correct order.
*
* @return array
* @return array The data for $siteID massaged into the correct form.
*/
function createLineChartLabels($startDate, $endDate)
function getScanData(array $data, int $siteID, array $labels)
{
$startDateYear = substr($startDate, 0, 4);
$endDateYear = substr($endDate, 0, 4);
$startDateMonth = substr($startDate, 4, 2);
$endDateMonth = substr($endDate, 4, 2);
$labels = array();
for ($year = (int)$startDateYear; $year <= (int)$endDateYear; $year++) {
$startMonth = ($year == (int)$startDateYear) ? (int)$startDateMonth : 1;
$endMonth = ($year == (int)$endDateYear) ? (int)$endDateMonth : 12;
for ($month = $startMonth; $month <= $endMonth; $month++) {
$labels[] = $month . "-" . $year;
$sitedata = array_filter(
$data,
function ($row) use ($siteID) {
return $row['CenterID'] == $siteID;
}
);
$mappeddata = [];
foreach ($sitedata as $row) {
$mappeddata[$row['datelabel']] = $row['count'];
}

$data = [];
foreach ($labels as $i => $label) {
$data[$i] = $mappeddata[$label] ?? 0;
}
return $labels;
return $data;
}

/**
* Get scan data for each month in the label array
* Extract all month labels that are in $data.
*
* @param string $siteID ID of a site
* @param array $labels chart labels (months to query)
* @param array $data The data to extract labels from
*
* @return array
* @return array An array of date labels that appear in the data.
*/
function getScanData($siteID, $labels)
function createLineChartLabels(array $data)
{
$DB = Database::singleton();
$data = array();
foreach ($labels as $label) {
$month = (strlen($label) == 6)
? substr($label, 0, 1) : substr($label, 0, 2);
$year = substr($label, -4, 4);
$data[] = $DB->pselectOne(
"SELECT COUNT(distinct s.ID)
FROM files f
LEFT JOIN parameter_file pf USING (FileID)
LEFT JOIN session s ON (s.ID=f.SessionID)
JOIN parameter_type pt USING (ParameterTypeID)
WHERE s.CenterID=:Site
AND pt.Name='acquisition_date'
AND MONTH(pf.Value)=:Month
AND YEAR(pf.Value)=:Year",
array(
'Site' => $siteID,
'Month' => $month,
'Year' => $year,
)
);
// Order was determined by the SQL statement. This should
// ensure that duplicates (for different sites) are stripped
// out.
$labels = [];
foreach ($data as $row) {
$labels[$row['datelabel']] = true;
}
return $data;
return array_keys($labels);
}

print json_encode($scanData);

return 0;