From 95fecdfa675b0451763b9ebbaac6c4814e8b31ba Mon Sep 17 00:00:00 2001 From: Jonathan Henrique Maia de Moraes Date: Mon, 7 Dec 2020 20:26:32 -0300 Subject: [PATCH] Sort control diagrams --- .../death_rate/death_rate_control_diagram.ex | 165 +++++++++++++++++- .../fragments/analytic_dashboard.ex | 126 ++++++------- 2 files changed, 227 insertions(+), 64 deletions(-) diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/card_data/deaths/death_rate/death_rate_control_diagram.ex b/lib/health_board_web/live/live_views/dashboard_live/data/card_data/deaths/death_rate/death_rate_control_diagram.ex index 1090ec5..013729c 100644 --- a/lib/health_board_web/live/live_views/dashboard_live/data/card_data/deaths/death_rate/death_rate_control_diagram.ex +++ b/lib/health_board_web/live/live_views/dashboard_live/data/card_data/deaths/death_rate/death_rate_control_diagram.ex @@ -1,6 +1,169 @@ defmodule HealthBoardWeb.DashboardLive.CardData.DeathRateControlDiagram do + alias HealthBoard.Contexts + @spec fetch(map()) :: map() - def fetch(card_data) do + def fetch(%{filters: filters} = card_data) do + send(card_data.root_pid, {:exec_and_emit, &do_fetch/1, card_data, {:chart, :combo}}) + card_data + |> Map.put(:view_data, %{event_pushed: true}) + |> Map.put(:filters, Map.update!(filters, :morbidity_context, &Contexts.morbidity_name(&1))) + end + + defp do_fetch(%{id: id, data: data, filters: filters}) do + %{morbidity_context: context, from_year: from_year, to_year: to_year} = filters + %{data_periods: data_periods, weekly_deaths: weekly_cases, yearly_populations: yearly_populations} = data + + weeks = Enum.to_list(1..53) + + data_period = fetch_data_period(data_periods, context, from_year) + + weekly_cases = Map.get(weekly_cases, context, []) + rates = fetch_rates(weekly_cases, yearly_populations) + + {lower, middle, upper} = moving_average_boundaries(rates, weeks, data_period, to_year) + + rates = Enum.filter(rates, &(&1.year == to_year)) + + %{ + id: id, + labels: weeks, + labelString: "Semana", + datasets: [ + %{ + type: "line", + label: "Coeficiente de incidência na semana", + backgroundColor: "#445", + borderColor: "#445", + pointRadius: 2, + borderWidth: 3, + fill: false, + data: Enum.map(weeks, &find_rate_from_week(rates, &1)) + }, + %{ + type: "line", + label: "Limite inferior do canal endêmico", + backgroundColor: "#6dac6d", + borderColor: "#6dac6d", + borderWidth: 2, + pointRadius: 1, + fill: false, + data: lower + }, + %{ + type: "line", + label: "Limite superior do canal endêmico", + backgroundColor: "#e47f7f", + borderColor: "#e47f7f", + borderWidth: 2, + pointRadius: 1, + fill: false, + data: upper + }, + %{ + type: "line", + label: "Índice endêmico", + backgroundColor: "#dbcb37", + borderColor: "#dbcb37", + borderWidth: 1, + pointRadius: 0, + fill: false, + data: middle + } + ] + } + end + + defp fetch_data_period(data_periods, context, from_year) do + data_context = Contexts.data_context!(:deaths) + + data_periods + |> Map.fetch!(data_context) + |> Map.get(context, [%{from_year: from_year, from_week: 1}]) + |> Enum.at(0) + end + + defp fetch_rates(weekly_cases, yearly_populations) do + population_per_year = Enum.group_by(yearly_populations, & &1.year, & &1.total) + Enum.map(weekly_cases, &fetch_rate(&1, population_per_year)) + end + + defp fetch_rate(%{year: year, week: week, total: cases}, population_per_year) do + [population] = Map.get(population_per_year, year, [0]) + + if population > 0 and cases > 0 do + %{year: year, week: week, cases: cases, rate: cases * 100_000 / population} + else + %{year: year, week: week, cases: cases, rate: 0.0} + end + end + + defp moving_average_boundaries(rates, weeks, data_period, to_year) do + rates + |> weekly_rates(weeks, data_period, to_year) + |> displace_by(7) + |> Enum.zip() + |> Enum.map(&calculate_moving_average/1) + |> Enum.group_by(& &1.week, & &1.average) + |> Enum.map(&calculate_moving_average_quartile/1) + |> Enum.reverse() + |> Enum.reduce({[], [], []}, &ungroup_boundaries/2) + end + + defp weekly_rates(rates, weeks, %{from_year: from_year, from_week: from_week}, to_year) do + for year <- from_year..to_year, week <- weeks do + if year < from_year or (year == from_year and week < from_week) do + nil + else + %{week: week, rate: rate} = Enum.find(rates, %{week: week, rate: 0.0}, &(&1.year == year and &1.week == week)) + %{week: week, rate: rate} + end + end + |> Enum.reject(&is_nil/1) + end + + defp displace_by(list, amount, displaced_lists \\ nil) do + if amount == 0 do + displaced_lists + else + if displaced_lists == nil do + displace_by(list, amount - 1, [list]) + else + displace_by(list, amount - 1, [[nil | list] | displaced_lists]) + end + end + end + + defp calculate_moving_average(displaced_data) do + displaced_data + |> Tuple.to_list() + |> Enum.reverse() + |> Enum.reject(&is_nil/1) + |> calculate_average() + end + + defp calculate_average([%{week: week} | _tail] = data) do + size = length(data) + %{week: week, average: Enum.reduce(data, 0.0, &(&1.rate + &2)) / size} + end + + defp calculate_moving_average_quartile({_week, moving_averages}) do + { + Statistics.percentile(moving_averages, 25), + Statistics.percentile(moving_averages, 50), + Statistics.percentile(moving_averages, 75) + } + end + + defp ungroup_boundaries({q1, q2, q3}, {l1, l2, l3}) do + { + [q1 | l1], + [q2 | l2], + [q3 | l3] + } + end + + defp find_rate_from_week(rates, week) do + Enum.find_value(rates, 0.0, &if(&1.week == week, do: &1.rate, else: nil)) end end diff --git a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard.ex b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard.ex index a8fa19f..6996ab3 100644 --- a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard.ex +++ b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard.ex @@ -69,84 +69,84 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard do :if={{ Map.has_key?(sections, :immediate_compulsory_analytic_control_diagrams) }} section={{ sections[:immediate_compulsory_analytic_control_diagrams] }} section_cards_ids={{[ - :accident_by_venomous_animals_incidence_rate_control_diagram, - :accident_by_venomous_animals_death_rate_control_diagram, - :accidental_tetanus_incidence_rate_control_diagram, - :accidental_tetanus_death_rate_control_diagram, - :acute_chagas_disease_incidence_rate_control_diagram, - :acute_chagas_disease_death_rate_control_diagram, - :acute_flaccid_paralysis_incidence_rate_control_diagram, - :acute_flaccid_paralysis_death_rate_control_diagram, :anthrax_incidence_rate_control_diagram, :anthrax_death_rate_control_diagram, :arenavirus_incidence_rate_control_diagram, :arenavirus_death_rate_control_diagram, :botulism_incidence_rate_control_diagram, :botulism_death_rate_control_diagram, - :brazilian_purpuric_fever_incidence_rate_control_diagram, - :brazilian_purpuric_fever_death_rate_control_diagram, :chikungunya_incidence_rate_control_diagram, :chikungunya_death_rate_control_diagram, - :cholera_incidence_rate_control_diagram, - :cholera_death_rate_control_diagram, - :congenital_rubella_syndrome_incidence_rate_control_diagram, - :congenital_rubella_syndrome_death_rate_control_diagram, :coqueluche_incidence_rate_control_diagram, :coqueluche_death_rate_control_diagram, + :cholera_incidence_rate_control_diagram, + :cholera_death_rate_control_diagram, :dengue_incidence_rate_control_diagram, :dengue_death_rate_control_diagram, :diphtheria_incidence_rate_control_diagram, :diphtheria_death_rate_control_diagram, + :meningococcal_disease_incidence_rate_control_diagram, + :meningococcal_disease_death_rate_control_diagram, + :acute_chagas_disease_incidence_rate_control_diagram, + :acute_chagas_disease_death_rate_control_diagram, :ebola_incidence_rate_control_diagram, :ebola_death_rate_control_diagram, - :extra_amazon_malaria_incidence_rate_control_diagram, - :extra_amazon_malaria_death_rate_control_diagram, + :yellow_fever_incidence_rate_control_diagram, + :yellow_fever_death_rate_control_diagram, + :spotted_fever_incidence_rate_control_diagram, + :spotted_fever_death_rate_control_diagram, + :brazilian_purpuric_fever_incidence_rate_control_diagram, + :brazilian_purpuric_fever_death_rate_control_diagram, + :typhoid_fever_incidence_rate_control_diagram, + :typhoid_fever_death_rate_control_diagram, + :west_nile_fever_incidence_rate_control_diagram, + :west_nile_fever_death_rate_control_diagram, :hantavirus_incidence_rate_control_diagram, :hantavirus_death_rate_control_diagram, - :human_rabies_incidence_rate_control_diagram, - :human_rabies_death_rate_control_diagram, :lassa_incidence_rate_control_diagram, :lassa_death_rate_control_diagram, :leptospirosis_incidence_rate_control_diagram, :leptospirosis_death_rate_control_diagram, + :extra_amazon_malaria_incidence_rate_control_diagram, + :extra_amazon_malaria_death_rate_control_diagram, :marburg_incidence_rate_control_diagram, :marburg_death_rate_control_diagram, - :measle_incidence_rate_control_diagram, - :measle_death_rate_control_diagram, - :meningococcal_disease_incidence_rate_control_diagram, - :meningococcal_disease_death_rate_control_diagram, - :neonatal_tetanus_incidence_rate_control_diagram, - :neonatal_tetanus_death_rate_control_diagram, + :acute_flaccid_paralysis_incidence_rate_control_diagram, + :acute_flaccid_paralysis_death_rate_control_diagram, :plague_incidence_rate_control_diagram, :plague_death_rate_control_diagram, :polio_incidence_rate_control_diagram, :polio_death_rate_control_diagram, - :rabies_related_animals_disease_incidence_rate_control_diagram, - :rabies_related_animals_disease_death_rate_control_diagram, + :human_rabies_incidence_rate_control_diagram, + :human_rabies_death_rate_control_diagram, :rubella_incidence_rate_control_diagram, :rubella_death_rate_control_diagram, - :severe_work_accident_incidence_rate_control_diagram, - :severe_work_accident_death_rate_control_diagram, - :smallpox_incidence_rate_control_diagram, - :smallpox_death_rate_control_diagram, - :spotted_fever_incidence_rate_control_diagram, - :spotted_fever_death_rate_control_diagram, + :measle_incidence_rate_control_diagram, + :measle_death_rate_control_diagram, :suicide_incidence_rate_control_diagram, :suicide_death_rate_control_diagram, + :congenital_rubella_syndrome_incidence_rate_control_diagram, + :congenital_rubella_syndrome_death_rate_control_diagram, :tularemia_incidence_rate_control_diagram, :tularemia_death_rate_control_diagram, - :typhoid_fever_incidence_rate_control_diagram, - :typhoid_fever_death_rate_control_diagram, + :accidental_tetanus_incidence_rate_control_diagram, + :accidental_tetanus_death_rate_control_diagram, + :neonatal_tetanus_incidence_rate_control_diagram, + :neonatal_tetanus_death_rate_control_diagram, :varicella_incidence_rate_control_diagram, :varicella_death_rate_control_diagram, - :violence_incidence_rate_control_diagram, - :violence_death_rate_control_diagram, - :west_nile_fever_incidence_rate_control_diagram, - :west_nile_fever_death_rate_control_diagram, - :yellow_fever_incidence_rate_control_diagram, - :yellow_fever_death_rate_control_diagram, + :smallpox_incidence_rate_control_diagram, + :smallpox_death_rate_control_diagram, :zika_incidence_rate_control_diagram, - :zika_death_rate_control_diagram + :zika_death_rate_control_diagram, + :severe_work_accident_incidence_rate_control_diagram, + :severe_work_accident_death_rate_control_diagram, + :accident_by_venomous_animals_incidence_rate_control_diagram, + :accident_by_venomous_animals_death_rate_control_diagram, + :rabies_related_animals_disease_incidence_rate_control_diagram, + :rabies_related_animals_disease_death_rate_control_diagram, + :violence_incidence_rate_control_diagram, + :violence_death_rate_control_diagram ]}} /> @@ -154,36 +154,36 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard do :if={{ Map.has_key?(sections, :weekly_compulsory_analytic_control_diagrams) }} section={{ sections[:weekly_compulsory_analytic_control_diagrams] }} section_cards_ids={{[ - :amazon_malaria_death_rate_control_diagram, - :american_cutaneous_leishmaniasis_death_rate_control_diagram, - :bio_exposure_work_accident_death_rate_control_diagram, + :chronic_chagas_disease_incidence_rate_control_diagram, :chronic_chagas_disease_death_rate_control_diagram, - :congenital_pregnant_toxoplasmosis_death_rate_control_diagram, - :exogenous_intoxication_death_rate_control_diagram, + :schistosomiasis_incidence_rate_control_diagram, + :schistosomiasis_death_rate_control_diagram, + :hiv_incidence_rate_control_diagram, :hiv_death_rate_control_diagram, + :leprosy_incidence_rate_control_diagram, :leprosy_death_rate_control_diagram, - :maternal_death_death_rate_control_diagram, - :schistosomiasis_death_rate_control_diagram, - :syphilis_death_rate_control_diagram, - :transport_accident_death_rate_control_diagram, - :tuberculosis_death_rate_control_diagram, + :viral_hepatitis_incidence_rate_control_diagram, :viral_hepatitis_death_rate_control_diagram, + :exogenous_intoxication_incidence_rate_control_diagram, + :exogenous_intoxication_death_rate_control_diagram, + :american_cutaneous_leishmaniasis_incidence_rate_control_diagram, + :american_cutaneous_leishmaniasis_death_rate_control_diagram, + :visceral_leishmaniasis_incidence_rate_control_diagram, :visceral_leishmaniasis_death_rate_control_diagram, :amazon_malaria_incidence_rate_control_diagram, - :american_cutaneous_leishmaniasis_incidence_rate_control_diagram, - :bio_exposure_work_accident_incidence_rate_control_diagram, - :chronic_chagas_disease_incidence_rate_control_diagram, - :congenital_pregnant_toxoplasmosis_incidence_rate_control_diagram, - :exogenous_intoxication_incidence_rate_control_diagram, - :hiv_incidence_rate_control_diagram, - :leprosy_incidence_rate_control_diagram, - :maternal_death_incidence_rate_control_diagram, - :schistosomiasis_incidence_rate_control_diagram, + :amazon_malaria_death_rate_control_diagram, :syphilis_incidence_rate_control_diagram, - :transport_accident_incidence_rate_control_diagram, + :syphilis_death_rate_control_diagram, + :congenital_pregnant_toxoplasmosis_incidence_rate_control_diagram, + :congenital_pregnant_toxoplasmosis_death_rate_control_diagram, :tuberculosis_incidence_rate_control_diagram, - :viral_hepatitis_incidence_rate_control_diagram, - :visceral_leishmaniasis_incidence_rate_control_diagram + :tuberculosis_death_rate_control_diagram, + :bio_exposure_work_accident_incidence_rate_control_diagram, + :bio_exposure_work_accident_death_rate_control_diagram, + :transport_accident_incidence_rate_control_diagram, + :transport_accident_death_rate_control_diagram, + :maternal_death_incidence_rate_control_diagram, + :maternal_death_death_rate_control_diagram ]}} />