add color-coding by activity per person
This commit is contained in:
parent
09708e74ab
commit
4c1960c3b2
|
@ -115,7 +115,8 @@ defmodule Backend.Scheduler do
|
|||
} ->
|
||||
time_diff_days = NaiveDateTime.diff(now, oldest_timestamp, :second) / (3600 * 24)
|
||||
|
||||
# (we're actually only ever updating, not inserting, so inserted_at will always be ignored...)
|
||||
# (we're actually only ever updating, not inserting, so inserted_at will always be ignored... but ecto
|
||||
# requires it)
|
||||
%{
|
||||
domain: domain,
|
||||
statuses_per_day: status_count / time_diff_days,
|
||||
|
|
|
@ -8,6 +8,15 @@ defmodule BackendWeb.GraphView do
|
|||
|> Enum.map(fn %{statuses_per_day: statuses_per_day} -> statuses_per_day end)
|
||||
|> Enum.filter(fn s -> s != nil end)
|
||||
|
||||
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)
|
||||
|
||||
%{
|
||||
graph: %{
|
||||
nodes: render_many(nodes, GraphView, "node.json", as: :node),
|
||||
|
@ -15,9 +24,14 @@ defmodule BackendWeb.GraphView do
|
|||
},
|
||||
metadata: %{
|
||||
ranges: %{
|
||||
# Make sure that these keys match what's in the "node.json" render function.
|
||||
statusesPerDay: [
|
||||
Enum.min(statuses_per_day),
|
||||
Enum.max(statuses_per_day)
|
||||
],
|
||||
statusesPerUserPerDay: [
|
||||
Enum.min(statuses_per_user_per_day),
|
||||
Enum.max(statuses_per_user_per_day)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +45,13 @@ defmodule BackendWeb.GraphView do
|
|||
false -> 1
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
# This is the format that cytoscape.js expects.
|
||||
%{
|
||||
data: %{
|
||||
|
@ -38,7 +59,8 @@ defmodule BackendWeb.GraphView do
|
|||
label: node.domain,
|
||||
size: size,
|
||||
type: node.type,
|
||||
statusesPerDay: node.statuses_per_day
|
||||
statusesPerDay: node.statuses_per_day,
|
||||
statusesPerUserPerDay: statuses_per_user_per_day
|
||||
},
|
||||
position: %{
|
||||
x: node.x,
|
||||
|
|
|
@ -2,7 +2,6 @@ defmodule BackendWeb.InstanceView do
|
|||
use BackendWeb, :view
|
||||
alias BackendWeb.InstanceView
|
||||
import Backend.Util
|
||||
require Logger
|
||||
|
||||
def render("show.json", %{instance: instance, crawl: crawl}) do
|
||||
user_threshold = get_config(:personal_instance_threshold)
|
||||
|
@ -31,6 +30,14 @@ defmodule BackendWeb.InstanceView do
|
|||
instance.peers
|
||||
|> Enum.filter(fn peer -> not peer.opt_out end)
|
||||
|
||||
statuses_per_user_per_day =
|
||||
if instance.statuses_per_day != nil and instance.user_count != nil and
|
||||
instance.user_count > 0 do
|
||||
instance.statuses_per_day / instance.user_count
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
%{
|
||||
name: instance.domain,
|
||||
description: instance.description,
|
||||
|
@ -43,7 +50,8 @@ defmodule BackendWeb.InstanceView do
|
|||
lastUpdated: last_updated,
|
||||
status: status,
|
||||
type: instance.type,
|
||||
statusesPerDay: instance.statuses_per_day
|
||||
statusesPerDay: instance.statuses_per_day,
|
||||
statusesPerUserPerDay: statuses_per_user_per_day
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -111,7 +111,7 @@ const renderQuantitativeKey = (range: number[]) => {
|
|||
<ColorKeyContainer>
|
||||
<ColorBarContainer>
|
||||
{QUANTITATIVE_COLOR_SCHEME.map((color, idx) => (
|
||||
<ColorBar color={color} />
|
||||
<ColorBar color={color} key={color} />
|
||||
))}
|
||||
</ColorBarContainer>
|
||||
<TextContainer>
|
||||
|
|
|
@ -267,7 +267,8 @@ class InstanceScreenImpl extends React.PureComponent<IInstanceScreenProps, IInst
|
|||
lastUpdated,
|
||||
insularity,
|
||||
type,
|
||||
statusesPerDay
|
||||
statusesPerDay,
|
||||
statusesPerUserPerDay
|
||||
} = this.props.instanceDetails;
|
||||
return (
|
||||
<StyledHTMLTable small={true} striped={true}>
|
||||
|
@ -313,7 +314,7 @@ class InstanceScreenImpl extends React.PureComponent<IInstanceScreenProps, IInst
|
|||
<Tooltip
|
||||
content={
|
||||
<span>
|
||||
The average number of statuses per day
|
||||
The average number of statuses written each day on this instance,
|
||||
<br />
|
||||
over the last month.
|
||||
</span>
|
||||
|
@ -326,6 +327,25 @@ class InstanceScreenImpl extends React.PureComponent<IInstanceScreenProps, IInst
|
|||
</td>
|
||||
<td>{(statusesPerDay && numeral.default(statusesPerDay).format("0.0")) || "Unknown"}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Statuses / person / day{" "}
|
||||
<Tooltip
|
||||
content={
|
||||
<span>
|
||||
The average number of statuses written per person each day,
|
||||
<br />
|
||||
over the last month.
|
||||
</span>
|
||||
}
|
||||
position={Position.TOP}
|
||||
className={Classes.DARK}
|
||||
>
|
||||
<Icon icon={IconNames.HELP} iconSize={Icon.SIZE_STANDARD} />
|
||||
</Tooltip>
|
||||
</td>
|
||||
<td>{(statusesPerUserPerDay && numeral.default(statusesPerUserPerDay).format("0.000")) || "Unknown"}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Known peers</td>
|
||||
<td>{(domainCount && numeral.default(domainCount).format("0,0")) || "Unknown"}</td>
|
||||
|
|
|
@ -49,6 +49,7 @@ export interface IInstanceDetails {
|
|||
status: string;
|
||||
type?: string;
|
||||
statusesPerDay?: number;
|
||||
statusesPerUserPerDay?: number;
|
||||
}
|
||||
|
||||
interface IGraphNode {
|
||||
|
|
|
@ -28,10 +28,17 @@ export const typeColorScheme: IQualitativeColorScheme = {
|
|||
};
|
||||
export const activityColorScheme: IQuantitativeColorScheme = {
|
||||
cytoscapeDataKey: "statusesPerDay",
|
||||
description: "The average number of statuses posted per day.",
|
||||
description: "The average number of statuses posted per day. Note that this is colored by an exponential scale.",
|
||||
exponential: true,
|
||||
name: "Activity",
|
||||
name: "Activity (total)",
|
||||
type: "quantitative"
|
||||
};
|
||||
export const activityPerUserColorScheme: IQuantitativeColorScheme = {
|
||||
cytoscapeDataKey: "statusesPerUserPerDay",
|
||||
description: "The average number of statuses posted per person per day.",
|
||||
exponential: false,
|
||||
name: "Activity (per person)",
|
||||
type: "quantitative"
|
||||
};
|
||||
|
||||
export const colorSchemes: IColorScheme[] = [typeColorScheme, activityColorScheme];
|
||||
export const colorSchemes: IColorScheme[] = [typeColorScheme, activityColorScheme, activityPerUserColorScheme];
|
||||
|
|
|
@ -64,7 +64,7 @@ export const getBuckets = (min: number, max: number, steps: number, exponential:
|
|||
return logSpace.map(i => (i + translation) * scalingFactor);
|
||||
} else {
|
||||
// Linear
|
||||
const bucketSize = Math.ceil((max - min) / steps);
|
||||
const bucketSize = (max - min) / steps;
|
||||
return range(min, max, bucketSize);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue