Packages
Nitrogen Web Framework Core Library
Current section
Files
Jump to
Current section
Files
src/elements/other/element_google_chart.erl
% vim: sw=4 ts=4 et ft=erlang
% Nitrogen Web Framework for Erlang
% Copyright (c) 2008-2010 Rusty Klophaus
% See MIT-LICENSE for licensing information.
-module (element_google_chart).
-include("wf.hrl").
-export([
reflect/0,
render_element/1
]).
-spec reflect() -> [atom()].
reflect() -> record_info(fields, google_chart).
-spec render_element(#google_chart{}) -> body().
render_element(Record) ->
% Path...
Path = "//chart.googleapis.com/chart?",
% Chart Type...
Type = [
"&cht=",
case Record#google_chart.type of
line -> "lc";
sparkline -> "ls";
stacked_horizontal_bar -> "bhs";
stacked_vertical_bar -> "bvs";
grouped_horizontal_bar -> "bhg";
grouped_vertical_bar -> "bvg";
pie -> "p";
pie3d -> "p3"
end
],
% Title...
Title = case Record#google_chart.title of
undefined -> [];
[] -> [];
OtherTitle -> ["&chtt=", wf:url_encode(OtherTitle)]
end,
% Title Color and Font Size...
TitleStyle = wf:f("&chts=~s,~b", [wf:to_list(Record#google_chart.color), Record#google_chart.font_size]),
% Size...
Size = wf:f("&chs=~bx~b", [Record#google_chart.width, Record#google_chart.height]),
% Grid...
Grid = wf:f("&chg=~s,~s,~b,~b", [
wf:to_list(wf:coalesce([Record#google_chart.grid_x, 0])),
wf:to_list(wf:coalesce([Record#google_chart.grid_y, 0])),
Record#google_chart.grid_line_length,
Record#google_chart.grid_blank_length
]),
% Background Colors...
BGColors = wf:f("&chf=bg,s,~s|c,s,~s", [
wf:to_list(Record#google_chart.background_color),
wf:to_list(Record#google_chart.chart_color)
]),
% Legend Location...
LegendLocation = "&chdlp=" ++ case Record#google_chart.legend_location of
top -> "t";
left -> "l";
bottom -> "b";
right -> "r"
end,
% Axes...
Axes = case Record#google_chart.axes of
undefined -> [];
[] -> [];
AxesRecords ->
ProcessedAxes = [process_axis(N - 1, lists:nth(N, AxesRecords)) || N <- lists:seq(1, length(AxesRecords))],
AxesPositions = "&chxt=" ++ string:join([X || [X, _, _] <- ProcessedAxes], ","),
AxesLabels = "&chxl=" ++ string:join([X || [_, X, _] <- ProcessedAxes], "|"),
AxesColors = "&chxs=" ++ string:join([X || [_, _, X] <- ProcessedAxes], "|"),
AxesPositions ++ AxesLabels ++ AxesColors
end,
% Data...
Data = case Record#google_chart.data of
undefined -> MaxValueLength=0, [];
[] -> MaxValueLength=0, [];
DataRecords ->
ProcessedData = [process_data(N -1, lists:nth(N, DataRecords)) || N <- lists:seq(1, length(DataRecords))],
DataColors = "&chco=" ++ string:join([X || [X, _, _, _, _, _] <- ProcessedData], ","),
DataLegends = "&chdl=" ++ string:join([X || [_, X, _, _, _, _] <- ProcessedData], "|"),
DataScales = "&chds=" ++ string:join([X || [_, _, X, _, _, _] <- ProcessedData], ","),
DataStyles = "&chls=" ++ string:join([X || [_, _, _, X, _, _] <- ProcessedData], "|"),
DataValues = "&chd=t:" ++ string:join([X || [_, _, _, _, X, _] <- ProcessedData], "|"),
MaxValueLength = lists:max([X || [_, _, _, _, _, X] <- ProcessedData]),
DataLegends1 = case string:strip(DataLegends, both, $|) of
"&chdl=" -> [];
_ -> DataLegends
end,
DataColors ++ DataLegends1 ++ DataScales ++ DataValues ++ DataStyles
end,
% Calculate bar size...
BarSize = case MaxValueLength of
0 -> [];
_ ->
DataGroupsLength = length(Record#google_chart.data),
BarGroupSpace = Record#google_chart.bar_group_space,
BarSpace = Record#google_chart.bar_space,
GroupSpacerPixels = MaxValueLength * BarGroupSpace,
BarSpacerPixels = MaxValueLength * (DataGroupsLength * BarSpace),
AvailablePixels = case Record#google_chart.type of
stacked_horizontal_bar -> Record#google_chart.height;
grouped_horizontal_bar -> Record#google_chart.height;
stacked_vertical_bar -> Record#google_chart.width;
grouped_vertical_bar -> Record#google_chart.width;
_ -> 0
end,
IndividualBarSize = (AvailablePixels - GroupSpacerPixels - BarSpacerPixels) / (DataGroupsLength * MaxValueLength),
wf:f("&chbh=~b,~b,~b", [trunc(IndividualBarSize), BarSpace, BarGroupSpace])
end,
% Render the image tag...
Image = #image {
html_id=Record#google_chart.html_id,
id=Record#google_chart.id,
anchor=Record#google_chart.anchor,
class=[google_chart, Record#google_chart.class],
style = Record#google_chart.style,
data_fields = Record#google_chart.data_fields,
image = lists:flatten([Path, Type, Title, TitleStyle, Size, Grid, BGColors, LegendLocation, BarSize, Axes, Data])
},
element_image:render_element(Image).
process_axis(N, Axis) ->
Position = case Axis#chart_axis.position of
top -> "t";
right -> "r";
bottom -> "x";
left -> "y"
%OtherPosition -> erlang:error({unknown_axis_position, OtherPosition})
end,
StringLabels = [wf:to_list(X) || X <- Axis#chart_axis.labels],
Labels = integer_to_list(N) ++ ":|" ++ string:join(StringLabels, "|"),
Style = wf:f("~b,~s,~b", [N, wf:to_list(Axis#chart_axis.color), Axis#chart_axis.font_size]),
[Position, Labels, Style].
process_data(_N, Data) ->
Color = wf:to_list(Data#chart_data.color),
Legend = wf:to_list(Data#chart_data.legend),
Scale = wf:f("~b,~b", [Data#chart_data.min_value, Data#chart_data.max_value]),
StringValues = [wf:to_list(X) || X <- Data#chart_data.values],
Values = string:join(StringValues, ","),
Styles = wf:f("~b,~b,~b", [Data#chart_data.line_width, Data#chart_data.line_length, Data#chart_data.blank_length]),
[Color, Legend, Scale, Styles, Values, length(StringValues)].