8#ifndef OPENFPM_DATA_SRC_PLOT_GOOGLECHART_HPP_ 
    9#define OPENFPM_DATA_SRC_PLOT_GOOGLECHART_HPP_ 
   12#include "Vector/map_vector.hpp" 
   15#define GGRAPH_COLUMS 1 
   16#define GGRAPH_POINTS 2 
   18#define GC_ZOOM std::string("explorer: {actions: ['dragToZoom', 'rightClickToReset'],axis: 'horizontal,vertical',keepInBounds: true, maxZoomIn: 128.0}")
 
   19#define GC_X_LOG std::string("hAxis: { logScale: true }")
 
   20#define GC_Y_LOG std::string("vAxis: { logScale: true }")
 
  123const std::string begin_data =
"<html>\n\ 
  125    <script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>\n\ 
  126    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js\"></script>\n\ 
  127    <script type=\"text/javascript\">\n\ 
  128      google.charts.load('current', {'packages':['corechart']});\n\ 
  129      google.charts.setOnLoadCallback(drawVisualization);\n\ 
  131function exportToSVG(i)\n\ 
  133var e = document.getElementById('chart_div'+i);\n\ 
  134var svg = e.getElementsByTagName('svg')[0].parentNode.innerHTML;\n\ 
  135var pos = svg.lastIndexOf(\"</svg>\");\n\ 
  137svg = svg.substring(0,4)  + \" xmlns='http://www.w3.org/2000/svg' xmlns:xlink= 'http://www.w3.org/1999/xlink' \" + svg.substring(4,pos);\n\ 
  138svgData = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);\n\ 
  139$(this).attr({'href': svgData,'target': '_blank'});\n\ 
  142      function drawVisualization() {\n";
 
  144const std::string end_data=
"]);\n\n";
 
  146const std::string begin_div = 
"}</script>\n\ 
  150const std::string div_end = 
"</body>\n\ 
  153const std::string saving_javascript = 
"function save(i)\n\ 
  154                                        var e = document.getElementById('chart_')\n\ 
  155                                        e.getElementsByTagName('svg')[0].parentNode.innerHTML";
 
  160    static bool check(
const T & n)
 
  169    static bool check(
const float & n)
 
  171        return std::isnan(n);
 
  178    static bool check(
const double & n)
 
  180        return std::isnan(n);
 
  217    template<
typename arg_0, 
typename ... args>
 
  220        typedef typename arg_0::value_type type;
 
  239    template<
typename X, 
typename ... Xs>
 
  244            typename X::value_type x;
 
  247            bool operator<(
const srt_xy & tmp)
 const 
  256        reord.resize(x.size());
 
  257        y_tmp.resize(x.size());
 
  259        for (
size_t i = 0 ; i < x.size() ; i++)
 
  261            reord.get(i).x = x.get(i);
 
  269        for (
size_t i = 0 ; i < x.size() ; i++)
 
  271            x.get(i) = reord.get(i).x;
 
  272            y_tmp.get(i) = y.get(reord.get(i).id);
 
  294    template<
typename X, 
typename ... Xs>
 
  295    bool isNext(
size_t * counters,X & x,X & y,Xs& ... xy)
 
  297        if (counters[0] < x.size())
 
  301        return isNext(&counters[1],xy ...);
 
  323    template<
typename T, 
typename X, 
typename ... Xs>
 
  324    T 
get_low(
size_t * counters,X & x,X & y,Xs& ... xy)
 
  326        if (
sizeof...(Xs) != 0)
 
  329            if (counters[0] >= x.size())
 
  330            {low1 = std::numeric_limits<typename X::value_type>::infinity();}
 
  332            {low1 = x.get(counters[0]);}
 
  334            T low2 = get_low<T>(&counters[1],xy ...);
 
  335            return (low1 < low2)?low1:low2;
 
  338        if (counters[0] >= x.size())
 
  339        {
return std::numeric_limits<typename X::value_type>::infinity();}
 
  340        return x.get(counters[0]);
 
  361    template<
typename X, 
typename ... Xs>
 
  363               typename X::value_type * point,
 
  369        if (counters[0] < x.size() && low == x.get(counters[0]))
 
  371            point[0] = y.get(counters[0]);
 
  376            point[0] = std::numeric_limits<typename X::value_type>::quiet_NaN();
 
  379        get_point(low,&point[1],&counters[1],xy...);
 
  404    template<
typename ... Xs>
 
  405    bool get_v(
typename get_value_type<Xs...>::type & x,
 
  406               typename get_value_type<Xs...>::type * point,
 
  411        if (
isNext(counters,xy...) == 
false)
 
  440        std::stringstream data;
 
  446        if (x.size() != y.size())
 
  447        {std::cerr << 
"Error: " << __FILE__ << 
":" << __LINE__ << 
" vector x and the vector y must have the same number of elements " << x.size() << 
"!=" << y.size() << 
"\n";}
 
  450        data << 
"var data" << i << 
" = new google.visualization.DataTable();\n";
 
  451        if (std::is_same<X,typename std::string>::value == 
true)
 
  452            data << 
"data" << i << 
".addColumn("  << 
"'string'" << 
"," << 
"'" << opt.
xAxis <<
"');\n";
 
  454            data << 
"data" << i << 
".addColumn("  << 
"'number'" << 
"," << 
"'" << opt.
xAxis <<
"');\n";
 
  456        for (
size_t j = 0 ; j < y.last().size() ; j++)
 
  458            if (yn.get(j) == std::string(
"interval"))
 
  460                data << 
"data" << i << 
".addColumn({id:'i" << interval/2 << 
"', type:'number', role:'interval'});\n";
 
  464                data << 
"data" << i << 
".addColumn("  << 
"'number'" << 
"," << 
"'" << yn.get(j) <<
"');\n";
 
  467        data << 
"data" << i << 
".addRows([\n";
 
  468        for (
size_t i = 0 ; i < y.size() && x.size() ; i++)
 
  471            for (
size_t j = 0 ; j < y.get(i).size()+1 ; j++)
 
  476                    if (std::is_same<X,typename std::string>::value == 
true)
 
  477                        data << 
"['"  << x.get(i) << 
"'";
 
  479                        data << 
"["  << x.get(i);
 
  485                        data << 
"," << y.get(i).get(j-1);
 
  490                        data << 
"," << 
"null";
 
  509        if (opt.
barWD == 
false)
 
  510            return std::string();
 
  512        std::stringstream str;
 
  514        str << 
"[0" << std::endl;
 
  516        for (
size_t i = 1 ; i < n_col ; i++)
 
  518            str << 
"," << i << 
",{ calc: \"stringify\"," << std::endl;
 
  519            str << 
"sourceColumn: " << i << 
"," << std::endl;
 
  520            str << 
"type: \"string\"," << std::endl;
 
  521            str << 
"role: \"annotation\" }"<< std::endl;
 
  524        str << 
"]" << std::endl;
 
  529    std::string get_colums_bar_option(
const GCoptions & opt)
 
  531        std::stringstream str;
 
  532        str << 
"title : '" << opt.
title << 
"'";
 
  533        str << 
",\nvAxis: {title: '" << opt.
yAxis <<  
"'}";
 
  534        str << 
",\nhAxis: {title: '" << opt.
xAxis << 
"'}";
 
  535        str << 
",\nseriesType: '" << opt.
stype << 
"'";
 
  537            str << 
",\nseries: " << opt.
stypeext;
 
  538        if (opt.
more.size() != 0)
 
  539            str << 
",\n" <<opt.
more;
 
  544    std::string get_points_plot_option(
const GCoptions & opt)
 
  546        std::stringstream str;
 
  547        str << 
"title : '" << opt.
title << 
"'";
 
  548        str << 
",\nvAxis: {title: '" << opt.
yAxis <<  
"'}";
 
  549        str << 
",\nhAxis: {title: '" << opt.
xAxis << 
"'}";
 
  550        str << 
",\ncurveType: '"<< opt.
curveType << 
"'";
 
  552        str << 
",\nlineWidth: " << opt.
lineWidth;
 
  556            str << 
",\nintervals: " << 
"{ 'style':'area' }";
 
  561        if (opt.
more.size() != 0)
 
  562            str << 
",\n" << opt.
more;
 
  574    void addData(std::ofstream & of, 
size_t i, 
const std::string & data)
 
  588    void addOption(std::ofstream & of, 
size_t i, 
const std::string & opt)
 
  594        {of << 
"interpolateNulls : true,\n";}
 
  606    void addView(std::ofstream & of, 
size_t i, std::string view)
 
  608        if (view.size() == 0)
 
  611        of << 
"var view" << i << 
" = new google.visualization.DataView(data" << i << 
");" << std::endl;
 
  612        of << 
"view"<< i << 
".setColumns(";
 
  613        of << view << 
");" << std::endl;
 
  623    void addDrawDiv(std::ofstream & of, 
size_t i, 
bool draw_view)
 
  625        of << 
"$(\"#export_svg" << i << 
"\").on(\"click\", function (event) {exportToSVG.apply(this,[" << i << 
"]);});\n";
 
  626        of << 
"var chart = new google.visualization.ComboChart(document.getElementById('chart_div";
 
  628        of << 
"'));" << std::endl;
 
  629        if (draw_view == 
true)
 
  631            of << 
"chart.draw(data";
 
  636            of << 
"chart.draw(view";
 
  653        of << 
"<a href=\"#\" download=\"graph1.svg\" id=\"export_svg" << i << 
"\"><button>Export data into svg</button></a>";
 
  654        of << 
"<div id=\"chart_div";
 
  656        of << 
"\" style=\"width: ";
 
  658        of << 
"px; height: ";
 
  660        of << 
"px;\"></div>\n";
 
  681        AddHistGraph<std::string,Y>(x,y);
 
  699            yn.resize(y.get(0).size());
 
  701        AddHistGraph<X,Y,std::string>(x,y,yn,opt);
 
  742            size_t sz = y.get(0).size();
 
  743            for (
size_t i = 0; i < y.size() ; i++)
 
  745                if (y.get(i).size() != sz)
 
  746                    std::cerr << __FILE__ << 
":" << __LINE__ << 
" error all the elements in the y vector must have the same numbers, element " << i << 
": " << y.get(i).size() << 
" " << 
" mismatch the numbers of elements at 0: " << sz << 
"/n";
 
  774        size_t counters[
sizeof...(X)];
 
  775        memset(&counters,0,
sizeof(counters));
 
  785        while (
get_v(xe,point,counters,xy...))
 
  790            for (
size_t i = 0 ; i < 
sizeof...(X)/2 ; i++)
 
  792                y.last().add(point[i]);
 
  825            std::cerr << 
"Error: " << __FILE__ << 
":" << __LINE__ << 
" vector y must be filled" << std::endl;
 
  829        for (
size_t i = 0 ; i < y.last().size() ; i++)
 
  830            yn.add(std::string(
"line") + std::to_string(i));
 
  836        size_t np = y.last().size();
 
  838        for (
size_t j = 0 ; j < y.size() ; j++)
 
  840            if (y.get(j).size() != np)
 
  841                std::cerr << __FILE__ << 
":" << __LINE__ << 
" Error all the graph must have the same number of points " << np << 
"!=" << y.get(j).size() << std::endl;
 
  851        for (
size_t i = 0 ; i < np ; i++)
 
  854            for (
size_t j = 0 ; j < y.size() ; j++)
 
  856                swap.last().add(y.get(j).get(i));
 
  892            std::cerr << 
"Error: " << __FILE__ << 
":" << __LINE__ << 
" vector y must be filled";
 
  896        for (
size_t i = 0 ; i < y.last().size() ; i++)
 
  897            yn.add(std::string(
"line") + std::to_string(i));
 
  919            std::cerr << 
"Error: " << __FILE__ << 
":" << __LINE__ << 
" vector y must be filled\n";
 
  930            size_t sz = y.get(0).size();
 
  931            for (
size_t i = 0; i < y.size() ; i++)
 
  933                if (y.get(i).size() != sz)
 
  934                    std::cerr << __FILE__ << 
":" << __LINE__ << 
" error all the elements in the y vector must have the same numbers of elements " << y.get(i).size() << 
" != " << sz << 
"\n";
 
  963        std::ofstream of(file);
 
  966        if (of.is_open() == 
false)
 
  967        {std::cerr << 
"Error cannot create the HTML file: " + file + 
"\n";}
 
Small class to produce graph with Google chart in HTML.
 
bool get_v(typename get_value_type< Xs... >::type &x, typename get_value_type< Xs... >::type *point, size_t *counters, Xs &... xy)
Recursively sort variadic template of vectors.
 
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const openfpm::vector< std::string > &yn, const GCoptions &opt)
Add a simple plot graph.
 
bool isNext(size_t *counters, X &x, X &y, Xs &... xy)
Recursively sort variadic template of vectors.
 
T get_low(size_t *counters, X &x, X &y, Xs &... xy)
Recursively sort variadic template of vectors.
 
void get_point(T low, T *point, size_t *counters)
Recursively sort variadic template of vectors.
 
void addView(std::ofstream &of, size_t i, std::string view)
Add a view data variable.
 
void write(std::string file)
It write the graphs on file in html format using Google charts.
 
void addDrawDiv(std::ofstream &of, size_t i, bool draw_view)
Add a draw div section.
 
void AddLines(const openfpm::vector< std::string > &yn, const GCoptions &opt, X ... xy)
Add lines graph.
 
void get_point(typename X::value_type low, typename X::value_type *point, size_t *counters, X &x, X &y, Xs &... xy)
Recursively sort variadic template of vectors.
 
void addDiv(std::ofstream &of, size_t i, const GCoptions &gc)
Add a div section.
 
std::string get_points_plot_data(const openfpm::vector< X > &x, const openfpm::vector< Y > &y, const openfpm::vector< std::string > &yn, const GCoptions &opt, size_t i)
Given X and Y vector return the string representing the data section of the Google Chart.
 
T get_low(size_t *counters)
Recursively sort variadic template of vectors.
 
bool isNext(size_t *counters)
Recursively sort variadic template of vectors.
 
void AddLinesGraphT(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add lines graph.
 
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add a simple lines graph.
 
void AddHistGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, openfpm::vector< Yn > &yn)
Add an histogram graph.
 
void recursive_sort()
terminator for recursive sort
 
openfpm::vector< std::string > injectHTML
set inject HTML;
 
openfpm::vector< GGraph > set_of_graphs
set of graphs
 
bool holes
Data has holes.
 
void recursive_sort(X &x, X &y, Xs &... xy)
Recursively sort variadic template of vectors.
 
void AddHistGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, openfpm::vector< Yn > &yn, const GCoptions &opt)
Add an histogram graph.
 
void AddHistGraph(openfpm::vector< Y > &y)
Add an histogram graph.
 
void AddHistGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y)
Add an histogram graph.
 
void addData(std::ofstream &of, size_t i, const std::string &data)
Add a graph data variable.
 
void addHTML(const std::string &html)
Add HTML text.
 
void addOption(std::ofstream &of, size_t i, const std::string &opt)
Add an option data variable.
 
std::string get_view_bar_option(const GCoptions &opt, size_t n_col)
Construct a view option.
 
Implementation of 1-D std::vector like structure.
 
size_t width
width of the graph in pixels
 
size_t heigh
height of the graph in pixels
 
std::string xAxis
X axis name.
 
size_t lineWidth
Width of the line.
 
GCoptions & operator=(const GCoptions &opt)
copy operator
 
std::string curveType
curve type
 
std::string title
Title of the chart.
 
std::string yAxis
Y axis name.
 
std::string view
view in case we need a view
 
GCoptions opt
Google chart option.