#!/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.