2019-07-14 11:47:06 +00:00
|
|
|
defmodule BackendWeb.GraphView do
|
|
|
|
use BackendWeb, :view
|
|
|
|
alias BackendWeb.GraphView
|
|
|
|
|
|
|
|
def render("index.json", %{nodes: nodes, edges: edges}) do
|
2019-07-27 17:58:40 +00:00
|
|
|
statuses_per_day =
|
|
|
|
nodes
|
|
|
|
|> Enum.map(fn %{statuses_per_day: statuses_per_day} -> statuses_per_day end)
|
|
|
|
|> Enum.filter(fn s -> s != nil end)
|
|
|
|
|
2019-08-02 16:37:26 +00:00
|
|
|
statuses_per_user_per_day =
|
|
|
|
nodes
|
|
|
|
|> Enum.filter(fn %{statuses_per_day: statuses_per_day, user_count: user_count} ->
|
|
|
|
statuses_per_day != nil and user_count != nil and user_count > 0
|
|
|
|
end)
|
|
|
|
|> Enum.map(fn %{statuses_per_day: statuses_per_day, user_count: user_count} ->
|
|
|
|
statuses_per_day / user_count
|
|
|
|
end)
|
|
|
|
|
2019-07-14 11:47:06 +00:00
|
|
|
%{
|
2019-07-27 17:58:40 +00:00
|
|
|
graph: %{
|
|
|
|
nodes: render_many(nodes, GraphView, "node.json", as: :node),
|
|
|
|
edges: render_many(edges, GraphView, "edge.json", as: :edge)
|
|
|
|
},
|
|
|
|
metadata: %{
|
|
|
|
ranges: %{
|
2019-08-02 16:37:26 +00:00
|
|
|
# Make sure that these keys match what's in the "node.json" render function.
|
2019-07-27 17:58:40 +00:00
|
|
|
statusesPerDay: [
|
2019-08-02 19:49:47 +00:00
|
|
|
Enum.min(statuses_per_day, fn -> nil end),
|
|
|
|
Enum.max(statuses_per_day, fn -> nil end)
|
2019-08-02 16:37:26 +00:00
|
|
|
],
|
|
|
|
statusesPerUserPerDay: [
|
2019-08-02 19:49:47 +00:00
|
|
|
Enum.min(statuses_per_user_per_day, fn -> nil end),
|
|
|
|
Enum.max(statuses_per_user_per_day, fn -> nil end)
|
2019-07-27 17:58:40 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
2019-07-14 11:47:06 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-07-24 15:51:44 +00:00
|
|
|
def render("node.json", %{node: node}) do
|
2019-07-14 11:47:06 +00:00
|
|
|
size =
|
|
|
|
case node.user_count > 1 do
|
|
|
|
true -> :math.log(node.user_count)
|
|
|
|
false -> 1
|
|
|
|
end
|
|
|
|
|
2019-08-02 16:37:26 +00:00
|
|
|
statuses_per_user_per_day =
|
|
|
|
if node.statuses_per_day != nil and node.user_count != nil and node.user_count > 0 do
|
|
|
|
node.statuses_per_day / node.user_count
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
2019-07-18 10:21:12 +00:00
|
|
|
# This is the format that cytoscape.js expects.
|
2019-07-14 11:47:06 +00:00
|
|
|
%{
|
2019-07-18 10:21:12 +00:00
|
|
|
data: %{
|
|
|
|
id: node.domain,
|
|
|
|
label: node.domain,
|
2019-07-24 15:51:44 +00:00
|
|
|
size: size,
|
2019-07-27 17:58:40 +00:00
|
|
|
type: node.type,
|
2019-08-02 16:37:26 +00:00
|
|
|
statusesPerDay: node.statuses_per_day,
|
|
|
|
statusesPerUserPerDay: statuses_per_user_per_day
|
2019-07-18 10:21:12 +00:00
|
|
|
},
|
|
|
|
position: %{
|
|
|
|
x: node.x,
|
|
|
|
y: node.y
|
|
|
|
}
|
2019-07-14 11:47:06 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-07-24 15:51:44 +00:00
|
|
|
def render("edge.json", %{edge: edge}) do
|
2019-07-14 11:47:06 +00:00
|
|
|
%{
|
2019-07-18 10:21:12 +00:00
|
|
|
data: %{
|
|
|
|
id: edge.id,
|
|
|
|
source: edge.source_domain,
|
|
|
|
target: edge.target_domain,
|
|
|
|
weight: edge.weight
|
|
|
|
}
|
2019-07-14 11:47:06 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|