Skip to content

Instantly share code, notes, and snippets.

@angrycub
Last active February 20, 2018 11:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save angrycub/8fe2498a42db12031509 to your computer and use it in GitHub Desktop.
Save angrycub/8fe2498a42db12031509 to your computer and use it in GitHub Desktop.
Escript to Graph a Riak Ring using HTML5 and Graph.JS
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname graph_ring -mnesia debug verbose
main([RingFile, OutFile]) ->
{ok, Binary} = file:read_file(RingFile),
Ring = binary_to_term(Binary),
OwnerList = element(2,element(4,Ring)),
%io:format("~s~n", [lists:flatten(header(body(footer([]),OwnerList)))]);
OutString = lists:flatten(header(body(footer([]),OwnerList))),
try
file:write_file(OutFile, io_lib:format("~s~n", [OutString])),
io:format("Saved ~p to ~p.~n", [RingFile, OutFile])
catch
A:B ->
io:format("Exception ~p:~p~n",[A,B])
end;
main([RingFile]) ->
main([RingFile, lists:append(RingFile,".html")]);
main(_) ->
usage().
usage() ->
io:format("usage: graph_ring RingFile [OutputFile]\n"),
halt(1).
header(IOList) ->
Header = "
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Ring Graph</title>
<script type=\"text/javascript\" src=\"https://raw.githubusercontent.com/nnnick/Chart.js/master/Chart.min.js\"></script>
</head>
<body>",
Chart = "<canvas style=\"float:left\" id=\"myChart\" width=\"800\" height=\"800\"></canvas>",
[Header, Chart,IOList].
body(IOList,OwnerList) ->
BodyBegin = "
<script>
",
BodyEnd = "
var ctx = document.getElementById(\"myChart\").getContext(\"2d\");
var myNewChart = new Chart(ctx).Doughnut(data,options);
new Chart(ctx).Doughnut(data,options);
</script>",
[BodyBegin, data(OwnerList), options(), BodyEnd, legend(OwnerList), IOList].
footer(IOList) ->
Footer = "
</body>
</html>
",
[Footer,IOList].
data(OwnerList) ->
% {Modulo,_} = lists:nth(2,OwnerList),
DataList = lists:map(
fun({_Partition,Node}) ->
<<R:8, G:8, B:8, _/binary>> = erlang:md5(atom_to_list(Node)),
["{value:",integer_to_list(1),",color:\"rgb(",integer_to_list(R),",",integer_to_list(G),",",integer_to_list(B),")\"},\n"]
end, OwnerList),
["var data = [",DataList,"];\n"].
options() ->
["
var options = {
segmentShowStroke : true,
segmentStrokeWidth : 1,
percentageInnerCutout : 95,
animation : false }
"].
legend(OwnerList) ->
["<table style=\"float:right\">",legendRows(OwnerList),"</table>"].
legendRows(OwnerList) ->
NodeList=lists:usort(element(2,lists:unzip(OwnerList))),
NodeHtml = lists:map(
fun(Node) ->
<<R:8, G:8, B:8, _/binary>> = erlang:md5(atom_to_list(Node)),
["<tr><td style=\"font-family: Helvetica, Arial, sans; font-size: .8em; height: 2.5em; color:",textColor([R,G,B]),"; background-color:rgb(",integer_to_list(R),",",integer_to_list(G),",",integer_to_list(B),")\">",atom_to_list(Node),"</tr>"]
end, NodeList),
NodeHtml.
textColor(Colors) ->
case (lists:max(Colors) + lists:min(Colors)) / 2.0 < 128 of
true ->
"white";
_ ->
"black"
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment