diff --git a/src/assets/js/indicatorHandler.js b/src/assets/js/indicatorHandler.js index 79ba439..ab8201f 100644 --- a/src/assets/js/indicatorHandler.js +++ b/src/assets/js/indicatorHandler.js @@ -10,6 +10,7 @@ function dataLayerPush(payload) { class IndicatorHandler { constructor() { this.indicators = {}; + this.nonCovidcastIndicatorSets = []; } fluviewIndicatorsMapping = { @@ -42,7 +43,7 @@ class IndicatorHandler { { value: "UT", label: "UT" }, ]; - fluviewRegions = [ + fluviewLocations = [ { id: "nat", text: "U.S. National" }, { id: "hhs1", text: "HHS Region 1" }, { id: "hhs2", text: "HHS Region 2" }, @@ -125,6 +126,16 @@ class IndicatorHandler { { id: "jfk", text: "New York City" }, ]; + nidssFluLocations = [ + { id: 'nationwide', text: 'Taiwan National' }, + { id: 'central', text: 'Central' }, + { id: 'eastern', text: 'Eastern' }, + { id: 'kaoping', text: 'Kaoping' }, + { id: 'northern', text: 'Northern' }, + { id: 'southern', text: 'Southern' }, + { id: 'taipei', text: 'Taipei' }, + ]; + checkForCovidcastIndicators() { return this.indicators.some((indicator) => { return indicator["_endpoint"] === "covidcast"; @@ -151,6 +162,16 @@ class IndicatorHandler { return fluviewIndicators; } + getNIDSSFluIndicators() { + var nidssFluIndicators = []; + this.indicators.forEach((indicator) => { + if (indicator["_endpoint"] === "nidss_flu") { + nidssFluIndicators.push(indicator); + } + }); + return nidssFluIndicators; + } + getFromToDate(startDate, endDate, timeType) { if (timeType === "week") { $.ajax({ @@ -180,21 +201,42 @@ class IndicatorHandler { return request; } - showFluviewRegions() { - var fluviewRegionSelect = ` -
+ showfluviewLocations() { + var fluviewLocationselect = ` +
- +
- +
`; if ($("#otherEndpointLocations").length) { - $("#otherEndpointLocations").append(fluviewRegionSelect); - $("#fluviewRegions").select2({ + $("#otherEndpointLocations").append(fluviewLocationselect); + $("#fluviewLocations").select2({ placeholder: "Select ILINet Location(s)", - data: this.fluviewRegions, + data: this.fluviewLocations, + allowClear: true, + width: "100%", + }); + } + } + + showNIDSSFluLocations() { + var nidssFluLocationselect = ` +
+
+ +
+
+ +
+
`; + if ($("#otherEndpointLocations").length) { + $("#otherEndpointLocations").append(nidssFluLocationselect); + $("#nidssFluLocations").select2({ + placeholder: "Select Taiwanese ILI Location(s)", + data: this.nidssFluLocations, allowClear: true, width: "100%", }); @@ -204,11 +246,13 @@ class IndicatorHandler { plotData() { const covidCastGeographicValues = $("#geographic_value").select2("data"); - const fluviewRegions = $("#fluviewRegions").select2("data"); + const fluviewLocations = $("#fluviewLocations").select2("data"); + const nidssFluLocations = $("#nidssFluLocations").select2("data"); const submitData = { indicators: this.indicators, covidCastGeographicValues: covidCastGeographicValues, - fluviewRegions: fluviewRegions, + fluviewLocations: fluviewLocations, + nidssFluLocations: nidssFluLocations, apiKey: document.getElementById("apiKey").value, }; const csrftoken = Cookies.get("csrftoken"); @@ -226,7 +270,8 @@ class IndicatorHandler { formMode: "epivis", indicators: JSON.stringify(submitData["indicators"]), covidcastGeoValues: JSON.stringify(submitData["covidCastGeographicValues"]), - fluviewGeoValues: JSON.stringify(submitData["fluviewRegions"]), + fluviewGeoValues: JSON.stringify(submitData["fluviewLocations"]), + nidssFluLocations: JSON.stringify(submitData["nidssFluLocations"]), epivisUrl: data["epivis_url"], apiKey: submitData["apiKey"] ? submitData["apiKey"] : "Not provided", } @@ -236,7 +281,8 @@ class IndicatorHandler { } exportData() { - var fluviewRegions = $("#fluviewRegions").select2("data"); + var fluviewLocations = $("#fluviewLocations").select2("data"); + var nidssFluLocations = $("#nidssFluLocations").select2("data"); var covidCastGeographicValues = Object.groupBy( $("#geographic_value").select2("data"), @@ -247,7 +293,8 @@ class IndicatorHandler { end_date: document.getElementById("end_date").value, indicators: this.indicators, covidCastGeographicValues: covidCastGeographicValues, - fluviewRegions: fluviewRegions, + fluviewLocations: fluviewLocations, + nidssFluLocations: nidssFluLocations, apiKey: document.getElementById("apiKey").value, } const csrftoken = Cookies.get("csrftoken"); @@ -267,7 +314,8 @@ class IndicatorHandler { formEndDate: submitData["end_date"], indicators: JSON.stringify(submitData["indicators"]), covidcastGeoValues: JSON.stringify(submitData["covidCastGeographicValues"]), - fluviewGeoValues: JSON.stringify(submitData["fluviewRegions"]), + fluviewGeoValues: JSON.stringify(submitData["fluviewLocations"]), + nidssFluLocations: JSON.stringify(submitData["nidssFluLocations"]), apiKey: submitData["apiKey"] ? submitData["apiKey"] : "Not provided", } dataLayerPush(payload); @@ -277,7 +325,8 @@ class IndicatorHandler { previewData() { $('#loader').show(); - var fluviewRegions = $("#fluviewRegions").select2("data"); + var fluviewLocations = $("#fluviewLocations").select2("data"); + var nidssFluLocations = $("#nidssFluLocations").select2("data"); var covidCastGeographicValues = Object.groupBy( $("#geographic_value").select2("data"), @@ -288,7 +337,8 @@ class IndicatorHandler { end_date: document.getElementById("end_date").value, indicators: this.indicators, covidCastGeographicValues: covidCastGeographicValues, - fluviewRegions: fluviewRegions, + fluviewLocations: fluviewLocations, + nidssFluLocations: nidssFluLocations, apiKey: document.getElementById("apiKey").value, } const csrftoken = Cookies.get("csrftoken"); @@ -307,7 +357,8 @@ class IndicatorHandler { formEndDate: submitData["end_date"], indicators: JSON.stringify(submitData["indicators"]), covidcastGeoValues: JSON.stringify(submitData["covidCastGeographicValues"]), - fluviewGeoValues: JSON.stringify(submitData["fluviewRegions"]), + fluviewGeoValues: JSON.stringify(submitData["fluviewLocations"]), + nidssFluLocations: JSON.stringify(submitData["nidssFluLocations"]), apiKey: submitData["apiKey"] ? submitData["apiKey"] : "Not provided", } dataLayerPush(payload); @@ -318,7 +369,8 @@ class IndicatorHandler { createQueryCode() { - var fluviewRegions = $("#fluviewRegions").select2("data"); + var fluviewLocations = $("#fluviewLocations").select2("data"); + var nidssFluLocations = $("#nidssFluLocations").select2("data"); var covidCastGeographicValues = Object.groupBy( $("#geographic_value").select2("data"), @@ -330,7 +382,8 @@ class IndicatorHandler { end_date: document.getElementById("end_date").value, indicators: this.indicators, covidCastGeographicValues: covidCastGeographicValues, - fluviewRegions: fluviewRegions, + fluviewLocations: fluviewLocations, + nidssFluLocations: nidssFluLocations, apiKey: document.getElementById("apiKey").value, } const csrftoken = Cookies.get("csrftoken"); @@ -357,7 +410,8 @@ class IndicatorHandler { formEndDate: submitData["end_date"], indicators: JSON.stringify(submitData["indicators"]), covidcastGeoValues: JSON.stringify(submitData["covidCastGeographicValues"]), - fluviewGeoValues: JSON.stringify(submitData["fluviewRegions"]), + fluviewGeoValues: JSON.stringify(submitData["fluviewLocations"]), + nidssFluLocations: JSON.stringify(submitData["nidssFluLocations"]), apiKey: submitData["apiKey"] ? submitData["apiKey"] : "Not provided", } dataLayerPush(payload); diff --git a/src/assets/js/indicatorSetsTable.js b/src/assets/js/indicatorSetsTable.js index 40d47ec..ee81152 100644 --- a/src/assets/js/indicatorSetsTable.js +++ b/src/assets/js/indicatorSetsTable.js @@ -83,7 +83,7 @@ function format(indicatorSetId, relatedIndicators, indicatorSetDescription) { ).length; var checkboxTitle = ""; checked = checked ? "checked" : ""; - disabled = indicator.endpoint !== "covidcast" && indicator.endpoint !== "fluview" ? "disabled" : ""; + disabled = indicator.endpoint !== "covidcast" && indicator.endpoint !== "fluview" && indicator.endpoint !== "nidss_flu" ? "disabled" : ""; sourceType = indicator.source_type; var restricted = indicator.restricted != "No"; if (disabled === "disabled") { diff --git a/src/assets/js/selectedIndicatorsModal.js b/src/assets/js/selectedIndicatorsModal.js index 77ced08..9c9133c 100644 --- a/src/assets/js/selectedIndicatorsModal.js +++ b/src/assets/js/selectedIndicatorsModal.js @@ -40,6 +40,11 @@ function addSelectedIndicator(element) { element.dataset.indicatorSet, element.dataset.indicator ); + if (element.dataset.endpoint !== "covidcast" && !indicatorHandler.nonCovidcastIndicatorSets.includes(element.dataset.indicatorSet)) { + indicatorHandler.nonCovidcastIndicatorSets.push( + element.dataset.indicatorSet + ); + } } else { checkedIndicatorMembers = checkedIndicatorMembers.filter( (indicator) => indicator.indicator !== element.dataset.indicator @@ -49,6 +54,15 @@ function addSelectedIndicator(element) { `${element.dataset.datasource}_${element.dataset.indicator}` ) .remove(); + const indicatorSet = element.dataset.indicatorSet; + const stillExist = checkedIndicatorMembers.some( + (indicator) => indicator.indicator_set === indicatorSet + ); + if (!stillExist && indicatorHandler.nonCovidcastIndicatorSets.includes(indicatorSet)) { + indicatorHandler.nonCovidcastIndicatorSets = indicatorHandler.nonCovidcastIndicatorSets.filter( + (set) => set !== indicatorSet + ); + } } indicatorHandler.indicators = checkedIndicatorMembers; @@ -210,8 +224,54 @@ $("#geographic_value").on("select2:select", function (e) { }); }); +function showFluviewLocationSelect() { + if (indicatorHandler.getFluviewIndicators().length > 0) { + if (document.getElementsByName("fluviewLocations").length === 0) { + indicatorHandler.showfluviewLocations(); + } else { + // IF code goes here, we assume that otherEndpointLocationWarning & fluviewRegion selector is already on the page, but is just hidden, so we should just show it. + $("#fluviewDiv").show(); + } + } else { + // If there are no non-covidcast indicators selected then hide otherEndpointLocationWarning & fluviewLocations selector. + $("#fluviewLocations").val(null).trigger("change"); + $("#fluviewDiv").hide(); + } +} + +function showNIDSSFluLocationSelect() { + if (indicatorHandler.getNIDSSFluIndicators().length > 0) { + if (document.getElementsByName("nidssFluLocations").length === 0) { + indicatorHandler.showNIDSSFluLocations(); + } else { + // IF code goes here, we assume that otherEndpointLocationWarning & nidssRegion selector is already on the page, but is just hidden, so we should just show it. + $("#nidssFluDiv").show(); + } + } else { + // If there are no non-covidcast indicators selected then hide otherEndpointLocationWarning & nidssFluLocations selector. + $("#nidssFluLocations").val(null).trigger("change"); + $("#nidssFluDiv").hide(); + } +} + +function showNonDelphiIndicatorSetsLocations() { + if (indicatorHandler.nonCovidcastIndicatorSets.length > 0) { + + var otherEndpointIndicatorSetsLocationMessage = `` + $("#differentLocationNote").html(otherEndpointIndicatorSetsLocationMessage); + showFluviewLocationSelect(); + showNIDSSFluLocationSelect(); + $("#otherEndpointLocationsWrapper").show(); + } else { + $("#differentLocationNote").html(""); + $("#otherEndpointLocationsWrapper").hide(); + } +} + + $("#showSelectedIndicatorsButton").click(async function () { + showNonDelphiIndicatorSetsLocations(); alertPlaceholder.innerHTML = ""; const prevSelectedIds = $('#geographic_value').val() || []; @@ -256,20 +316,6 @@ $("#showSelectedIndicatorsButton").click(async function () { } }) }); - if (indicatorHandler.getFluviewIndicators().length > 0) { - var ilinetEndpointLocationsWarning = ''; - $("#differentLocationNote").html(ilinetEndpointLocationsWarning) - if (document.getElementsByName("fluviewRegions").length === 0) { - indicatorHandler.showFluviewRegions(); - } else { - // IF code goes here, we assume that otherEndpointLocationWarning & fluviewRegion selector is already on the page, but is just hidden, so we should just show it. - $("#otherEndpointLocationsWrapper").show(); - } - } else { - // If there are no non-covidcast indicators selected (only fluview is supported for now) then hide otherEndpointLocationWarning & fliviewRegions selector. - $("#fluviewRegions").val(null).trigger("change"); - $("#otherEndpointLocationsWrapper").hide(); - } }); diff --git a/src/indicatorsets/views.py b/src/indicatorsets/views.py index 44d0108..ae2c76c 100644 --- a/src/indicatorsets/views.py +++ b/src/indicatorsets/views.py @@ -234,7 +234,8 @@ def epivis(request): data = json.loads(request.body) indicators = data.get("indicators", []) covidcast_geos = data.get("covidCastGeographicValues", []) - fluview_geos = data.get("fluviewRegions", []) + fluview_geos = data.get("fluviewLocations", []) + nidss_flu_locations = data.get("nidssFluLocations", []) api_key = data.get("apiKey", "") form_activity_logger.info( mode="epivis", @@ -307,6 +308,30 @@ def epivis(request): geo_value=geo["id"], api_key=api_key, ) # noqa: E501 + + elif indicator["_endpoint"] == "nidss_flu": + for geo in nidss_flu_locations: + datasets.append( + { + "color": generate_random_color(), + "title": indicator["indicator"], + "params": { + "_endpoint": indicator["_endpoint"], + "regions": geo["id"], + "custom_title": generate_epivis_custom_title( + indicator, geo["text"] + ), + }, + } + ) + form_activity_logger.info( + mode="epivis", + endpoint=indicator["_endpoint"], + data_source=indicator["data_source"], + indicator=indicator["indicator"], + geo_value=geo["id"], + api_key=api_key, + ) if datasets: datasets_json = json.dumps({"datasets": datasets}) datasets_b64 = base64.b64encode(datasets_json.encode("ascii")).decode( @@ -326,7 +351,8 @@ def generate_export_data_url(request): end_date = data.get("end_date", "") indicators = data.get("indicators", []) covidcast_geos = data.get("covidCastGeographicValues", {}) - fluview_geos = data.get("fluviewRegions", []) + fluview_geos = data.get("fluviewLocations", []) + nidss_flu_locations = data.get("nidssFluLocations", []) api_key = data.get("apiKey", None) form_activity_logger.info( mode="data_export", @@ -380,6 +406,22 @@ def generate_export_data_url(request): data_export_commands.append( f'wget --content-disposition {data_export_url}' ) + if nidss_flu_locations: + regions = ",".join([region["id"] for region in nidss_flu_locations]) + date_from, date_to = get_epiweek(start_date, end_date) + form_activity_logger.info( + mode="data_export", + endpoint="nidss_flu", + regions=regions, + epiweeks=f"{date_from}-{date_to}", + api_key=api_key, + ) # noqa: E501 + data_export_url = f"{settings.EPIDATA_URL}nidss_flu/?regions={regions}&epiweeks={date_from}-{date_to}&format=csv" + if api_key: + data_export_url += f"&api_key={api_key}" + data_export_commands.append( + f'wget --content-disposition {data_export_url}' + ) data_export_block = data_export_block.format("
".join(data_export_commands)) response = { "data_export_block": data_export_block, @@ -395,7 +437,8 @@ def preview_data(request): end_date = data.get("end_date", "") indicators = data.get("indicators", []) covidcast_geos = data.get("covidCastGeographicValues", {}) - fluview_geos = data.get("fluviewRegions", []) + fluview_geos = data.get("fluviewLocations", []) + nidss_flu_locations = data.get("nidssFluLocations", []) api_key = data.get("apiKey", None) preview_data = [] @@ -494,6 +537,39 @@ def preview_data(request): "message": "API key does not exist. Register a new key at https://api.delphi.cmu.edu/epidata/admin/registration_form or contact delphi-support+privacy@andrew.cmu.edu to troubleshoot", } return JsonResponse(preview_data, safe=False) + if nidss_flu_locations: + regions = ",".join([region["id"] for region in nidss_flu_locations]) + date_from, date_to = get_epiweek(start_date, end_date) + params = { + "regions": regions, + "epiweeks": f"{date_from}-{date_to}", + "api_key": api_key if api_key else settings.EPIDATA_API_KEY, + } + form_activity_logger.info( + mode="data_export", + endpoint="nidss_flu", + regions=regions, + epiweeks=f"{date_from}-{date_to}", + api_key=api_key, + ) # noqa: E501 + response = requests.get(f"{settings.EPIDATA_URL}nidss_flu", params=params) + if response.status_code == 200: + data = response.json() + if len(data["epidata"]): + preview_data.append( + { + "epidata": data["epidata"][0], + "result": data["result"], + "message": data["message"], + } + ) + elif response.status_code == 401: + preview_data = { + "epidata": [], + "result": -2, + "message": "API key does not exist. Register a new key at https://api.delphi.cmu.edu/epidata/admin/registration_form or contact delphi-support+privacy@andrew.cmu.edu to troubleshoot", + } + return JsonResponse(preview_data, safe=False) return JsonResponse(preview_data, safe=False) @@ -504,7 +580,8 @@ def create_query_code(request): end_date = data.get("end_date", "") indicators = data.get("indicators", []) covidcast_geos = data.get("covidCastGeographicValues", {}) - fluview_geos = data.get("fluviewRegions", []) + fluview_geos = data.get("fluviewLocations", []) + nidss_flu_locations = data.get("nidssFluLocations", []) api_key = data.get("apiKey", None) python_code_blocks = [ dedent( @@ -634,6 +711,34 @@ def create_query_code(request): """ ) r_code_blocks.append(r_code_block) + if nidss_flu_locations: + regions = ",".join([region["id"] for region in nidss_flu_locations]) + start_week, end_week = get_epiweek(start_date, end_date) + python_code_block = dedent( + f"""\ + nidss_flu_df = epidata.pub_nidss_flu( + regions="{regions}", + epiweeks="{start_week}-{end_week}", + ).df() + """ + ) + form_activity_logger.info( + mode="data_export", + endpoint="nidss_flu", + regions=regions, + epiweeks=f"{start_week}-{end_week}", + api_key=api_key, + ) # noqa: E501 + python_code_blocks.append(python_code_block) + r_code_block = dedent( + f"""\ + epidata_{data_source.replace("-", "_")} <- pub_nidss_flu( + regions = "{regions}", + epiweeks = epirange({start_week}, {end_week}) + ) + """ + ) + r_code_blocks.append(r_code_block) python_code_blocks.append("") r_code_blocks.append("") return JsonResponse(