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.
126 lines
2.4 KiB
Ruby
126 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class TimeSeriesComponent < ApplicationComponent
|
|
delegate :current_page_path, :search_params, to: :helpers
|
|
|
|
attr_reader :dataframe, :x_axis, :y_axis, :mode
|
|
|
|
def initialize(dataframe, x_axis:, mode: :table)
|
|
@dataframe = dataframe
|
|
@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
|