reports: add non-timeseries charts.
Add bar charts for non-timeseries data. For example, a bar chart of the top 10 uploaders overall in the last month, rather than a timeseries chart of the number of uploads per day for the last month.
This commit is contained in:
@@ -3,11 +3,123 @@
|
||||
class TimeSeriesComponent < ApplicationComponent
|
||||
delegate :current_page_path, :search_params, to: :helpers
|
||||
|
||||
attr_reader :dataframe, :group, :mode
|
||||
attr_reader :dataframe, :x_axis, :y_axis, :mode
|
||||
|
||||
def initialize(dataframe, group: nil, mode: :table)
|
||||
def initialize(dataframe, x_axis:, mode: :table)
|
||||
@dataframe = dataframe
|
||||
@group = group
|
||||
@x_axis = x_axis
|
||||
@y_axis = columns.without(x_axis)
|
||||
@mode = mode.to_sym
|
||||
end
|
||||
|
||||
def columns
|
||||
dataframe.types.keys
|
||||
end
|
||||
|
||||
def chart_height
|
||||
if x_axis != "date"
|
||||
dataframe[x_axis].size * 30
|
||||
end
|
||||
end
|
||||
|
||||
def chart_options
|
||||
if x_axis == "date"
|
||||
stacked_area_chart
|
||||
else
|
||||
horizontal_bar_chart
|
||||
end
|
||||
end
|
||||
|
||||
def base_options
|
||||
{
|
||||
dataset: {
|
||||
dimensions: columns,
|
||||
source: dataframe.each_row.map(&:values),
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "cross",
|
||||
label: {
|
||||
backgroundColor: "#6a7985"
|
||||
}
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
feature: {
|
||||
dataView: {},
|
||||
restore: {},
|
||||
saveAsImage: {}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: "1%",
|
||||
right: "1%",
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
data: y_axis.map(&:capitalize),
|
||||
type: "scroll",
|
||||
left: 0,
|
||||
padding: [8, 200, 0, 15],
|
||||
orient: "horizontal",
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
def stacked_area_chart
|
||||
base_options.deep_merge(
|
||||
toolbox: {
|
||||
feature: {
|
||||
dataZoom: {
|
||||
yAxisIndex: "none"
|
||||
},
|
||||
magicType: {
|
||||
type: ["line", "bar"],
|
||||
},
|
||||
}
|
||||
},
|
||||
dataZoom: [
|
||||
{ type: "inside" },
|
||||
{ type: "slider" }
|
||||
],
|
||||
xAxis: { type: "time" },
|
||||
yAxis: [type: "value"] * y_axis.size,
|
||||
series: y_axis.map do |name|
|
||||
{
|
||||
name: name.capitalize,
|
||||
type: "line",
|
||||
areaStyle: {},
|
||||
stack: "all",
|
||||
emphasis: {
|
||||
focus: "series"
|
||||
},
|
||||
encode: {
|
||||
x: x_axis,
|
||||
y: name
|
||||
}
|
||||
}
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
def horizontal_bar_chart
|
||||
base_options.deep_merge(
|
||||
xAxis: { type: "value" },
|
||||
yAxis: [type: "category", inverse: true] * y_axis.size,
|
||||
series: y_axis.map do |name|
|
||||
{
|
||||
name: name.capitalize,
|
||||
type: "bar",
|
||||
emphasis: {
|
||||
focus: "series"
|
||||
},
|
||||
encode: {
|
||||
x: name,
|
||||
y: x_axis,
|
||||
}
|
||||
}
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,16 @@
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if mode == :table %>
|
||||
<% if mode == :chart && x_axis.present? %>
|
||||
<div class="line-chart" style="width: 100%; height: max(90vh, <%= chart_height.to_i %>px);"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var chart = new Danbooru.TimeSeriesComponent({
|
||||
container: $(".line-chart").get(0),
|
||||
options: <%= raw chart_options.to_json %>,
|
||||
});
|
||||
</script>
|
||||
<% else %>
|
||||
<table class="striped autofit" width="100%">
|
||||
<thead>
|
||||
<% dataframe.types.keys.each do |column| %>
|
||||
@@ -26,16 +35,4 @@
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% elsif mode == :chart %>
|
||||
<div class="line-chart" style="width: 100%; height: 80vh;"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var data = <%= raw dataframe.each_row.map(&:values).to_json %>;
|
||||
var columns = <%= raw dataframe.types.keys.without("date").to_json %>;
|
||||
var chart = new Danbooru.TimeSeriesComponent({
|
||||
container: $(".line-chart").get(0),
|
||||
data: data,
|
||||
columns: columns,
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
Reference in New Issue
Block a user