Skip to content

Commit 7fbab4d

Browse files
authored
Merge pull request #142 from cmu-delphi/staging
Staging
2 parents e2d7fc4 + ecb1245 commit 7fbab4d

33 files changed

+1039
-460
lines changed

src/assets/js/indicatorHandler.js

+413
Large diffs are not rendered by default.

src/assets/js/signal_sets.js

+67-177
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const indicatorHandler = new IndicatorHandler();
2+
13
function initSelect2(elementId, data) {
24
$(`#${elementId}`).select2({
35
data: data,
@@ -15,73 +17,34 @@ function showWarningAlert(warningMessage, slideUpTime = 2000) {
1517
});
1618
}
1719

18-
function checkGeoCoverage(geoType, geoValue) {
19-
var notCoveredSignals = [];
20-
$.ajax({
21-
url: "epidata/covidcast/geo_coverage/",
22-
type: 'GET',
23-
async: false,
24-
data: {
25-
'geo': `${geoType}:${geoValue}`
26-
},
27-
success: function (result) {
28-
checkedSignalMembers.forEach(signal => {
29-
var covered = result["epidata"].some(
30-
e => (e.source === signal.data_source && e.signal === signal.signal)
31-
)
32-
if (!covered) {
33-
notCoveredSignals.push(signal);
34-
}
35-
})
36-
}
37-
})
38-
return notCoveredSignals;
39-
}
40-
41-
42-
43-
function plotData() {
44-
var dataSets = {};
45-
var geographicValues = $('#geographic_value').select2('data');
46-
checkedSignalMembers.forEach((signal) => {
47-
geographicValues.forEach((geoValue) => {
48-
var geographicValue = (typeof geoValue.id === 'string') ? geoValue.id.toLowerCase() : geoValue.id;
49-
var geographicType = geoValue.geoType;
50-
var epivisCustomTitle;
51-
if (signal["member_short_name"]) {
52-
epivisCustomTitle = `${signal["signal_set_short_name"]}:${signal["member_short_name"]} : ${geoValue.text}`
53-
} else {
54-
epivisCustomTitle = `${signal["signal_set_short_name"]} : ${geoValue.text}`
20+
async function checkGeoCoverage(geoType, geoValue) {
21+
const notCoveredSignals = [];
22+
23+
try {
24+
const result = await $.ajax({
25+
url: "epidata/covidcast/geo_coverage/",
26+
type: 'GET',
27+
data: {
28+
'geo': `${geoType}:${geoValue}`
5529
}
56-
dataSets[`${signal["signal"]}_${geographicValue}`] = {
57-
color: '#'+(Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, '0'),
58-
title: "value",
59-
params: {
60-
_endpoint: signal["_endpoint"],
61-
data_source: signal["data_source"],
62-
signal: signal["signal"],
63-
time_type: signal["time_type"],
64-
geo_type: geographicType,
65-
geo_value: geographicValue,
66-
custom_title: epivisCustomTitle
67-
}
30+
});
31+
32+
checkedSignalMembers.filter(signal => signal["_endpoint"] === "covidcast").forEach(signal => {
33+
const covered = result["epidata"].some(
34+
e => (e.source === signal.data_source && e.signal === signal.signal)
35+
);
36+
if (!covered) {
37+
notCoveredSignals.push(signal);
6838
}
69-
})
39+
});
7040

71-
});
72-
73-
var requestParams = [];
74-
for (var key in dataSets) {
75-
requestParams.push(dataSets[key]);
41+
return notCoveredSignals;
42+
} catch (error) {
43+
console.error('Error fetching geo coverage:', error);
44+
return notCoveredSignals;
7645
}
77-
78-
var urlParamsEncoded = btoa(`{"datasets":${JSON.stringify(requestParams)}}`);
79-
80-
var linkToEpivis = `${epiVisUrl}#${urlParamsEncoded}`
81-
window.open(linkToEpivis, '_blank').focus();
8246
}
8347

84-
8548
// Function to update the modal content
8649
function updateSelectedSignals(dataSource, signalDisplayName, signalSet, signal) {
8750
var selectedSignalsList = document.getElementById('selectedSignalsList');
@@ -115,6 +78,7 @@ function addSelectedSignal(element) {
11578
document.getElementById(`${element.dataset.datasource}_${element.dataset.signal}`).remove();
11679
}
11780

81+
indicatorHandler.indicators = checkedSignalMembers;
11882

11983
if (checkedSignalMembers.length > 0) {
12084
$("#showSelectedSignalsButton").show();
@@ -123,6 +87,33 @@ function addSelectedSignal(element) {
12387
}
12488
}
12589

90+
$("#showSelectedSignalsButton").click(function() {
91+
alertPlaceholder.innerHTML = "";
92+
if (!indicatorHandler.checkForCovidcastIndicators()) {
93+
$("#geographic_value").prop("disabled", true);
94+
} else {
95+
$("#geographic_value").prop("disabled", false);
96+
}
97+
$('#geographic_value').select2("data").forEach(geo => {
98+
checkGeoCoverage(geo.geoType, geo.id).then((notCoveredSignals) => {
99+
if (notCoveredSignals.length > 0) {
100+
showNotCoveredGeoWarningMessage(notCoveredSignals, geo.text);
101+
}
102+
})
103+
});
104+
var otherEndpointLocationsWarning = `<div class="alert alert-info" data-mdb-alert-init role="alert">` +
105+
` <div>Please, note that some indicator sets may require to select location(s) that is/are different from location above.<br> `
106+
nonCovidcastSignalSets = [...new Set(checkedSignalMembers.filter(signal => signal["_endpoint"] != "covidcast").map((signal) => signal["signal_set"]))];
107+
otherEndpointLocationsWarning += `Different location is required for following signal set(s): ${nonCovidcastSignalSets.join(", ")}`
108+
otherEndpointLocationsWarning += `</div></div>`
109+
if (indicatorHandler.getFluviewIndicators().length > 0) {
110+
$("#differentLocationNote").html(otherEndpointLocationsWarning)
111+
if (document.getElementsByName("fluviewRegions").length === 0) {
112+
indicatorHandler.showFluviewRegions();
113+
}
114+
}
115+
});
116+
126117
// Add an event listener to each 'bulk-select' element
127118
let bulkSelectDivs = document.querySelectorAll('.bulk-select');
128119
bulkSelectDivs.forEach(div => {
@@ -254,116 +245,6 @@ function format (signalSetId, relatedSignals, signalSetDescription) {
254245
return data;
255246
}
256247

257-
258-
function exportData() {
259-
var geographicValues = $('#geographic_value').select2('data');
260-
geographicValues = Object.groupBy(geographicValues, ({ geoType }) => [geoType])
261-
var geoTypes = Object.keys(geographicValues);
262-
263-
var startDate = document.getElementById('start_date').value;
264-
var endDate = document.getElementById('end_date').value;
265-
266-
var manualDataExport = "To download data, please click on the link or copy/paste command into your terminal: \n\n"
267-
var requests = [];
268-
269-
checkedSignalMembers.forEach((signal) => {
270-
geoTypes.forEach((geoType) => {
271-
var geoValues = geographicValues[geoType].map((el) => (typeof el.id === 'string') ? el.id.toLowerCase() : el.id).join(",");
272-
if (signal["time_type"] === "week") {
273-
var request = $.ajax({
274-
url: "get_epiweek/",
275-
type: 'POST',
276-
async: true,
277-
data: {
278-
csrfmiddlewaretoken: csrf_token,
279-
start_date: startDate,
280-
end_date: endDate,
281-
},
282-
success: function (result) {
283-
var exportUrl = `https://api.delphi.cmu.edu/epidata/covidcast/csv?signal=${signal["data_source"]}:${signal["signal"]}&start_day=${result.start_date}&end_day=${result.end_date}&geo_type=${geoType}&geo_values=${geoValues}`;
284-
manualDataExport += `wget --content-disposition <a href="${exportUrl}">${exportUrl}</a>\n`
285-
}
286-
})
287-
requests.push(request);
288-
} else {
289-
var exportUrl = `https://api.delphi.cmu.edu/epidata/covidcast/csv?signal=${signal["data_source"]}:${signal["signal"]}&start_day=${startDate}&end_day=${endDate}&geo_type=${geoType}&geo_values=${geoValues}`;
290-
manualDataExport += `wget --content-disposition <a href="${exportUrl}">${exportUrl}</a>\n`
291-
}
292-
});
293-
});
294-
$.when.apply($, requests).then(function() {
295-
$('#modeSubmitResult').html(manualDataExport);
296-
})
297-
298-
}
299-
300-
function previewData() {
301-
var geographicValues = $('#geographic_value').select2('data');
302-
geographicValues = Object.groupBy(geographicValues, ({ geoType }) => [geoType])
303-
var geoTypes = Object.keys(geographicValues);
304-
var previewExample = [];
305-
var requests = [];
306-
307-
var startDate = document.getElementById("start_date").value;
308-
var endDate = document.getElementById("end_date").value;
309-
310-
checkedSignalMembers.forEach((signal) => {
311-
var timeValues;
312-
313-
if (signal["time_type"] === "week") {
314-
$.ajax({
315-
url: "get_epiweek/",
316-
type: 'POST',
317-
async: false,
318-
data: {
319-
csrfmiddlewaretoken: csrf_token,
320-
start_date: startDate,
321-
end_date: endDate,
322-
},
323-
success: function (result) {
324-
timeValues = `${result.start_date}-${result.end_date}`;
325-
}
326-
})
327-
};
328-
329-
var requestSent = false;
330-
if (!requestSent) {
331-
geoTypes.forEach((geoType) => {
332-
var geoValues = geographicValues[geoType].map((el) => (typeof el.id === 'string') ? el.id.toLowerCase() : el.id).join(",");
333-
$('#loader').show();
334-
timeValues = signal["time_type"] === "week" ? timeValues : `${startDate}--${endDate}`;
335-
var request = $.ajax({
336-
url: "epidata/covidcast/",
337-
type: 'GET',
338-
async: true,
339-
data: {
340-
'time_type': signal["time_type"],
341-
'time_values': timeValues,
342-
'data_source': signal["data_source"],
343-
'signal': signal["signal"],
344-
'geo_type': geoType,
345-
'geo_values': geoValues
346-
},
347-
success: function (result) {
348-
if (result["epidata"].length != 0) {
349-
previewExample.push({epidata: result["epidata"][0], result: result["result"], message: result["message"]})
350-
} else {
351-
previewExample.push({epidata: result["epidata"], result: result["result"], message: result["message"]})
352-
}
353-
}
354-
})
355-
requests.push(request);
356-
})
357-
}
358-
})
359-
$.when.apply($, requests).then(function() {
360-
$('#loader').hide();
361-
$('#modeSubmitResult').html(JSON.stringify(previewExample, null, 2));
362-
requestSent = true;
363-
})
364-
}
365-
366-
367248
// Plot/Export/Preview data block
368249

369250
var currentMode = 'epivis';
@@ -439,22 +320,31 @@ function showNotCoveredGeoWarningMessage(notCoveredSignals, geoValue) {
439320

440321
$('#geographic_value').on('select2:select', function (e) {
441322
var geo = e.params.data;
442-
var notCoveredSignals = checkGeoCoverage(geo.geoType, geo.id)
443-
if (notCoveredSignals.length > 0) {
444-
showNotCoveredGeoWarningMessage(notCoveredSignals, geo.text);
323+
checkGeoCoverage(geo.geoType, geo.id).then((notCoveredSignals) => {
324+
if (notCoveredSignals.length > 0) {
325+
showNotCoveredGeoWarningMessage(notCoveredSignals, geo.text);
326+
}
445327
}
328+
);
446329
});
447330

448331

449332
function submitMode(event) {
450333
event.preventDefault();
334+
var geographicValues = $('#geographic_value').select2('data');
335+
if (indicatorHandler.checkForCovidcastIndicators()) {
336+
if (geographicValues.length === 0) {
337+
appendAlert("Please select at least one geographic location", "warning")
338+
return;
339+
}
340+
}
451341

452342
if (currentMode === 'epivis') {
453-
plotData();
343+
indicatorHandler.plotData();
454344
} else if (currentMode === 'export') {
455-
exportData();
345+
indicatorHandler.exportData();
456346
} else {
457-
previewData();
347+
indicatorHandler.previewData();
458348
}
459349
}
460350

src/datasources/resources.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,21 @@ def process_links(row, dua_column_name="DUA", link_column_name="Link"):
2727
links.append(link.id)
2828
else:
2929
for match in matches:
30-
link, _ = Link.objects.get_or_create(url=match[1], defaults={'link_type': match[0], })
30+
link, _ = Link.objects.get_or_create(
31+
url=match[1],
32+
defaults={
33+
"link_type": match[0],
34+
},
35+
)
3136
links.append(link.id)
3237
row["Links"] = links
3338

3439

40+
def process_datasource_name(row):
41+
if row["Name"]:
42+
row["Name"] = row["Name"].capitalize()
43+
44+
3545
def process_datasources(row):
3646
datasource, _ = DataSource.objects.get_or_create(
3747
name=row["DB Source"],
@@ -67,5 +77,6 @@ class Meta:
6777
skip_unchanged = True
6878

6979
def before_import_row(self, row, **kwargs):
80+
process_datasource_name(row)
7081
process_links(row)
7182
process_datasources(row)

0 commit comments

Comments
 (0)