diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/card_data/incidence/incidence_rate/incidence_rate_control_diagram.ex b/lib/health_board_web/live/live_views/dashboard_live/data/card_data/incidence/incidence_rate/incidence_rate_control_diagram.ex
index 7319661..f828829 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/card_data/incidence/incidence_rate/incidence_rate_control_diagram.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/card_data/incidence/incidence_rate/incidence_rate_control_diagram.ex
@@ -1,6 +1,169 @@
defmodule HealthBoardWeb.DashboardLive.CardData.IncidenceRateControlDiagram 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_morbidities: 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!(:morbidity)
+
+ 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/data/dashboard_data.ex b/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data.ex
index 63221a0..8546566 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data.ex
@@ -7,8 +7,10 @@ defmodule HealthBoardWeb.DashboardLive.DashboardData do
@spec assign(map) :: map
def assign(%{dashboard: dashboard, data: data, filters: filters, root_pid: root_pid}) do
dashboard.sections
- |> Task.async_stream(&fetch_section_data(&1, data, filters, root_pid), timeout: 10_000)
+ |> Task.async_stream(&fetch_section_data(&1, data, filters, root_pid), timeout: 60_000)
|> Enum.reduce(%{}, fn {:ok, {k, v}}, map -> Map.put(map, k, v) end)
+ rescue
+ _error -> []
end
defp fetch_section_data(dashboard_section, data, filters, root_pid) do
diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data/analytic.ex b/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data/analytic.ex
index 47ec2bb..6e282f5 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data/analytic.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/dashboard_data/analytic.ex
@@ -117,7 +117,7 @@ defmodule HealthBoardWeb.DashboardLive.DashboardData.Analytic do
order_by: [asc: :context, asc: :year, asc: :week]
]
|> WeeklyDeaths.list_by()
- |> Enum.map(&Map.take(&1, [:context, :location_id, :year, :total]))
+ |> Enum.map(&Map.take(&1, [:context, :location_id, :year, :week, :total]))
|> Enum.group_by(& &1.context)
end
@@ -131,7 +131,7 @@ defmodule HealthBoardWeb.DashboardLive.DashboardData.Analytic do
order_by: [asc: :context, asc: :year, asc: :week]
]
|> WeeklyMorbidities.list_by()
- |> Enum.map(&Map.take(&1, [:context, :location_id, :year, :total]))
+ |> Enum.map(&Map.take(&1, [:context, :location_id, :year, :week, :total]))
|> Enum.group_by(& &1.context)
end
diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/event_data.ex b/lib/health_board_web/live/live_views/dashboard_live/data/event_data.ex
index 50e761e..29b0331 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/event_data.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/event_data.ex
@@ -11,7 +11,7 @@ defmodule HealthBoardWeb.DashboardLive.EventData do
defp build_chart_data(data, sub_type) do
case sub_type do
- :combo -> %{}
+ :combo -> combo_chart_data(data)
:horizontal_bar -> %{}
:line -> %{}
:multiline -> multiline_chart_data(data)
@@ -20,6 +20,32 @@ defmodule HealthBoardWeb.DashboardLive.EventData do
end
end
+ defp combo_chart_data(%{id: id, datasets: datasets, labels: labels, labelString: label_string}) do
+ %{
+ id: id,
+ data: %{
+ type: "line",
+ data: %{
+ labels: labels,
+ datasets: datasets
+ },
+ options: %{
+ maintainAspectRatio: false,
+ scales: %{
+ xAxes: [
+ %{
+ scaleLabel: %{
+ display: true,
+ labelString: label_string
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ end
+
defp multiline_chart_data(%{id: id, datasets: datasets, labels: labels}) do
datasets =
datasets
diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/section_data.ex b/lib/health_board_web/live/live_views/dashboard_live/data/section_data.ex
index 06cb7ca..caedee8 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/section_data.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/section_data.ex
@@ -18,8 +18,10 @@ defmodule HealthBoardWeb.DashboardLive.SectionData do
@spec assign(map) :: map
def assign(%{section: %{cards: section_cards}, data: data, filters: filters, root_pid: root_pid}) do
section_cards
- |> Task.async_stream(&fetch_card_data(&1, data, filters, root_pid), timeout: 10_000)
+ |> Task.async_stream(&fetch_card_data(&1, data, filters, root_pid), timeout: 60_000)
|> Enum.reduce(%{}, fn {:ok, {k, v}}, map -> Map.put(map, k, v) end)
+ rescue
+ _error -> []
end
defp fetch_card_data(section_card, data, filters, root_pid) do
diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/immediate/immediate_compulsory_analytic_control_diagrams.ex b/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/immediate/immediate_compulsory_analytic_control_diagrams.ex
index f296b1f..4e82b12 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/immediate/immediate_compulsory_analytic_control_diagrams.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/immediate/immediate_compulsory_analytic_control_diagrams.ex
@@ -1,6 +1,6 @@
defmodule HealthBoardWeb.DashboardLive.SectionData.ImmediateCompulsoryAnalyticControlDiagrams do
- @data_keys ~w[data_periods weekly_deaths weekly_morbidities weekly_populations]a
- @filter_keys ~w[morbidity_context]a
+ @data_keys ~w[data_periods weekly_deaths weekly_morbidities yearly_populations]a
+ @filter_keys ~w[from_year morbidity_context to_year]a
@spec fetch(map()) :: map()
def fetch(%{data: data, filters: filters} = section_data) do
diff --git a/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/weekly/weekly_compulsory_analytic_control_diagrams.ex b/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/weekly/weekly_compulsory_analytic_control_diagrams.ex
index 16c4aef..5b42a58 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/weekly/weekly_compulsory_analytic_control_diagrams.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/data/section_data/analytic/weekly/weekly_compulsory_analytic_control_diagrams.ex
@@ -1,6 +1,6 @@
defmodule HealthBoardWeb.DashboardLive.SectionData.WeeklyCompulsoryAnalyticControlDiagrams do
- @data_keys ~w[data_periods weekly_deaths weekly_morbidities weekly_populations]a
- @filter_keys ~w[morbidity_context]a
+ @data_keys ~w[data_periods weekly_deaths weekly_morbidities yearly_populations]a
+ @filter_keys ~w[from_year morbidity_context to_year]a
@spec fetch(map()) :: map()
def fetch(%{data: data, filters: filters} = section_data) do
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 90565ec..a8fa19f 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
@@ -1,7 +1,7 @@
defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard do
use Surface.Component
- alias HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard.{History, Region, Summary}
+ alias HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard.{ControlDiagrams, History, Region, Summary}
alias HealthBoardWeb.LiveComponents.{Card, Grid, Section, SectionHeader}
alias Phoenix.LiveView
@@ -64,6 +64,128 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard do
:weekly_compulsory_death_rate_table
]}}
/>
+
+
+
+
"""
else
@@ -86,126 +208,4 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard do
"""
end
end
-
- #
-
- #
end
diff --git a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagram.ex b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagram.ex
index e3da8ca..a12bc66 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagram.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagram.ex
@@ -1,20 +1,26 @@
defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard.ControlDiagram do
use Surface.Component
- alias HealthBoardWeb.LiveComponents.{Card, CardBodyCanvas}
+ alias HealthBoardWeb.LiveComponents.{Card, CardBodyCanvas, CardHeaderMenu, CardOffcanvasMenu}
alias Phoenix.LiveView
- prop id, :atom, required: true
+ prop card_id, :atom, required: true
prop card, :map, required: true
@spec render(map()) :: LiveView.Rendered.t()
def render(assigns) do
~H"""
-
+
+
+
+
+
-
+
+
+
"""
end
diff --git a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagrams.ex b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagrams.ex
index bb64183..139d043 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagrams.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/control_diagrams.ex
@@ -20,8 +20,7 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard.ControlDiagra
diff --git a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/history_chart.ex b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/history_chart.ex
index 6f5072d..3c04162 100644
--- a/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/history_chart.ex
+++ b/lib/health_board_web/live/live_views/dashboard_live/fragments/analytic_dashboard/history_chart.ex
@@ -11,7 +11,7 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard.HistoryChart
@spec render(map()) :: LiveView.Rendered.t()
def render(assigns) do
~H"""
-
+
@@ -20,7 +20,7 @@ defmodule HealthBoardWeb.DashboardLive.Fragments.AnalyticDashboard.HistoryChart
-
+
"""
end