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.