16#ifndef MiL_SVG_ELEMENTS_H
17#define MiL_SVG_ELEMENTS_H 1
75 _M_sstream <<
"url(#" <<
id <<
")" << k::quote;
83 _M_sstream <<
"url(#" <<
id <<
")" << k::quote;
102 std::ostringstream oss;
103 oss << k::space <<
"transform=" << k::quote << s << k::quote;
145 {
return string(
"</g>") + k::newline; }
165 _M_sstream <<
"<g id=" << k::quote << name << k::quote << k::space;
174 _M_sstream <<
"<g id=" << k::quote << name << k::quote;
211 {
return "</defs>"; }
255 _M_sstream <<
"href=" << k::quote << url << k::quote;
265 add_data(
const string& url,
const string relt,
const string ast,
266 const string cors =
"anonymous")
268 _M_sstream <<
"rel=" << k::quote << relt << k::quote << k::space;
269 _M_sstream <<
"href=" << k::quote << url << k::quote << k::space;
270 _M_sstream <<
"as=" << k::quote << ast << k::quote << k::space;
271 _M_sstream <<
"crossorigin=" << k::quote << cors << k::quote << k::space;
272 _M_sstream <<
"referrerpolicy=" << k::quote <<
"no-referrer" << k::quote;
312 _M_sstream <<
"<filter id=" << k::quote <<
id << k::quote <<
">"
321 auto [ width, height ] = blur_area;
323 _M_sstream <<
"<filter id=" << k::quote <<
id << k::quote << k::space
324 <<
"x=" << k::quote <<
x << k::quote << k::space
325 <<
"y=" << k::quote << y << k::quote << k::space
326 <<
"width=" << k::quote << width << k::quote << k::space
327 <<
"height=" << k::quote << height << k::quote
347 stream <<
"<feGaussianBlur in=";
348 stream << k::quote <<
in << k::quote << k::space;
349 stream <<
"stdDeviation=" << k::quote << dev << k::quote << k::space;
395 stop(
const string off,
const color& klr,
const double opacity = 1.0)
397 _M_sstream <<
"<stop offset=" << k::quote << off << k::quote << k::space
398 <<
"stop-color=" << k::quote <<
to_string(klr) << k::quote;
402 <<
"stop-opacity=" << k::quote << opacity << k::quote;
412 const double ratio =
static_cast<double>(numer)/
static_cast<double>(denom);
414 return std::to_string(perc) +
"%";
431 _M_sstream <<
"<radialGradient id=" << k::quote <<
"default" << k::quote;
442 _M_sstream <<
"<radialGradient id=" << k::quote <<
id << k::quote;
445 _M_sstream << k::space <<
"r=" << k::quote << radius << k::quote;
446 _M_sstream << k::space <<
"cx=" << k::quote << cx << k::quote;
447 _M_sstream << k::space <<
"cy=" << k::quote << cy << k::quote;
461 _M_sstream <<
"<radialGradient id=" << k::quote <<
id << k::quote
462 << k::space <<
"r=" << k::quote << radius << k::quote;
463 _M_sstream << k::space <<
"cx=" << k::quote << cx << k::quote;
464 _M_sstream << k::space <<
"cy=" << k::quote << cy << k::quote;
467 _M_sstream << k::space <<
"fx=" << k::quote << fx << k::quote;
468 _M_sstream << k::space <<
"fy=" << k::quote << fy << k::quote;
469 _M_sstream << k::space <<
"fr=" << k::quote << fr << k::quote;
481 _M_sstream <<
"</radialGradient>" << k::newline;
494 _M_sstream <<
"<linearGradient id=" << k::quote <<
"default" << k::quote;
505 _M_sstream <<
"</linearGradient>" << k::newline;
533 _M_sstream <<
"<marker id=" << k::quote <<
id << k::quote << k::space
534 <<
"markerWidth=" << k::quote << w << k::quote << k::space
535 <<
"markerHeight=" << k::quote << h << k::quote << k::space
536 <<
"refX=" << k::quote <<
x << k::quote << k::space
537 <<
"refY=" << k::quote << y << k::quote <<
" >"
597 {
_M_sstream <<
"<desc>" << k::newline << dsc << k::newline; }
633 const string x(
"__x");
634 const string y(
"__y");
635 const string attr(
"__attr");
636 const string style(
"__style");
638 string strip = R
"_delimiter_(x="__x" y="__y" __attr __style)_delimiter_";
666 const string x(
"__x");
667 const string dys(
"__dy");
668 string strip = R
"_delimiter_(<tspan x="__x" dy="__dy">)_delimiter_";
684 const string x(
"__x");
685 const string dxs(
"__dx");
686 string strip = R
"_delimiter_(<tspan x="__x" dx="__dx">)_delimiter_";
698 {
return "</tspan>"; }
712 for (
uint i = 0; i < s.size(); ++i)
720 if (i < s.size() - 1)
758 const string x(
"__x");
759 const string y(
"__y");
760 const string w(
"__w");
761 const string h(
"__h");
763 string strip = R
"_delimiter_(x="__x" y="__y" width="__w" height="__h"
814 const string x(
"__x");
815 const string y(
"__y");
816 const string r(
"__r");
818 string strip = R
"_delimiter_(cx="__x" cy="__y" r="__r")_delimiter_";
866 for (
const auto& [
x, y ]: points)
905 const string x1(
"__x1");
906 const string x2(
"__x2");
907 const string y1(
"__y1");
908 const string y2(
"__y2");
909 const string dash(
"__darray");
911 const bool dashp = !dasharray.empty();
913 R
"_delimiter_(x1="__x1" y1="__y1" x2="__x2" y2="__y2")_delimiter_";
915 R
"_delimiter_(x1="__x1" y1="__y1" x2="__x2" y2="__y2" stroke-dasharray="__darray")_delimiter_";
917 string strip = dashp ? stript : stripf;
934 {
_M_sstream <<
"<line id=" << k::quote << name << k::quote << k::space; }
980 _M_sstream <<
"stroke-dasharray=" << k::quote;
985 _M_sstream <<
"stroke-dashoffset=" << k::quote;
1003 _M_sstream <<
"marker-mid=" << mkr << k::space;
1004 _M_sstream <<
"marker-end=" << mkr << k::space;
1015 {
_M_sstream <<
"<polyline id=" << k::quote << name << k::quote << k::space; }
1054 const string pathd(
"__d");
1055 const string len(
"__l");
1057 string strip = R
"_delimiter_(d="__d")_delimiter_";
1070 {
_M_sstream <<
"<path id=" << k::quote << name << k::quote << k::space; }
1100 const string off =
"",
const string whichside =
"")
1108 << k::quote <<
'#' <<
path_name << k::quote;
1111 << k::quote <<
offset << k::quote;
1114 << k::quote <<
side << k::quote;
1150 const string simg =
"<image";
1153 _M_sstream <<
"id=" << k::quote <<
id << k::quote << k::space;
1168 const string x(
"__x");
1169 const string y(
"__y");
1170 const string w(
"__w");
1171 const string h(
"__h");
1172 const string ref(
"__ref");
1174 string strip = R
"_delimiter_(href="__ref" x="__x" y="__y" width="__w" height="__h")_delimiter_";
1191 const string display =
"")
1196 _M_sstream <<
"crossorigin=" << k::quote << cors << k::quote << k::space;
1198 _M_sstream <<
"visibility=" << k::quote << vattr << k::quote << k::space;
1199 if (!display.empty())
1200 _M_sstream <<
"display=" << k::quote << display << k::quote << k::space;
1253 const auto [ scalex, scaley ] =
scale;
1254 const auto [ ox, oy ] = origin;
1260 const auto [ vwidth, vheight ] = av;
1275 string strip = R
"(<foreignObject x="XXX" y="YYY" width="WWW" height="HHH">)";
1289{
_M_sstream <<
" </foreignObject></g></g>" << k::newline; }
1303 const string svideo = R
"(<video xmlns="http://www.w3.org/1999/xhtml" )";
1306 _M_sstream <<
"id=" << k::quote <<
id << k::quote << k::space;
1326 const string attr = R
"(autoplay="true" loop="true" muted="true")")
1328 string strip = R
"(width="WWW" height="HHH" )";
1336 _M_sstream <<
"<source src=" << k::quote << src << k::quote << k::space;
1337 _M_sstream <<
"type=" << k::quote << mtype << k::quote;
1361 const string siframe = R
"(<iframe xmlns="http://www.w3.org/1999/xhtml" )";
1364 _M_sstream <<
"id=" << k::quote <<
id << k::quote << k::space;
1377 const string attr = R
"(sandbox="allow-scripts allow-same-origin")")
1379 string strip = R
"(width="WWW" height="HHH" )";
1389 _M_sstream <<
"<source src=" << k::quote << src << k::quote << k::space;
1390 _M_sstream <<
"type=" << k::quote << mtype << k::quote << k::space;
1415 const string sobject = R
"(<object xmlns="http://www.w3.org/1999/xhtml" )";
1418 _M_sstream <<
"id=" << k::quote <<
id << k::quote << k::space;
1432 const string attr = R
"(sandbox="allow-scripts allow-same-origin")")
1434 string strip = R
"(width="WWW" height="HHH" )";
1439 _M_sstream <<
"data=" << k::quote << src << k::quote << k::space;
1440 _M_sstream <<
"type=" << k::quote << mtype << k::quote << k::space;
1475 const string shead = R
"(<script type="text/javascript" crossorigin="anonymous")";
1478 _M_sstream <<
"id=" << k::quote <<
id << k::quote << k::space;
1489 static const string&
1492 static string js_show_element = R
"(
1493 function showTooltip(event, tooltipId) {
1494 const tooltipimg = document.getElementById(tooltipId);
1496 const ge = tooltipimg.parentElement;
1497 const svge = ge.parentElement;
1498 const brect = ge.getBoundingClientRect();
1499 const bx = brect.left;
1500 const by = brect.top;
1502 tooltipimg.setAttribute('x', event.x + bx);
1503 tooltipimg.setAttribute('y', event.y + by);
1505 tooltipimg.setAttribute('visibility', 'visible');
1507 console.error(`Element with ID "${tooltipId}" not found.`);
1511 static string js_show_document = R
"(
1512 function showTooltip(event, tooltipId) {
1513 const tooltipimg = document.getElementById(tooltipId);
1515 //tooltipimg.onload = function() {
1516 const ge = tooltipimg.parentElement;
1517 const svge = ge.parentElement;
1518 const brect = ge.getBoundingClientRect();
1519 const bx = brect.left;
1520 const by = brect.top;
1522 //const iheight = 150;
1523 const iheight = tooltipimg.offsetHeight; //!isNaN(iheight)
1524 tooltipimg.setAttribute('x', event.pageX - bx);
1525 tooltipimg.setAttribute('y', event.pageY - by - iheight);
1526 tooltipimg.setAttribute('visibility', 'visible');
1527 //tooltipimg.setAttribute('display', 'inline');
1529 console.error(`Element with ID "${tooltipId}" not found.`);
1533 static string js_hide = R
"(
1534 function hideTooltip(tooltipId) {
1535 const tooltipimg = document.getElementById(tooltipId);
1536 tooltipimg.setAttribute('visibility', 'hidden');
1537 //tooltipimg.setAttribute('display', 'none');
1542 js = js_show_element + k::newline + js_hide;
1544 js = js_show_document + k::newline + js_hide;
1552 const string toolr(
"__toolt");
1553 string strip1 = R
"_delimiter_(onmouseover="showTooltip(event, '__toolt')" )_delimiter_";
1554 string strip2 = R
"_delimiter_(onmouseout="hideTooltip('__toolt')" )_delimiter_";
1557 return k::space + strip1 + k::space + strip2;
1561 static const script_element
1564 script_element scrpt;
1567 scrpt.finish_element();
1607 const bool lifetime =
true,
1618 const bool lifetime =
true)
1640 {
return _M_area.center_point(); }
1647 const style& sty = k::no_style);
void start_element(const string dsc)
static string start_tspan_x(uint xpos, uint dx)
static constexpr const char * pair_finish_tag
void add_data(const string &url)
void start_element(string name, const string ts, const style &sty=k::no_style)
void add_data(const stroke_style &sstyl)
string gaussian_blur(string in, string dev)
static constexpr const char * pair_open_tag
void add_filter(const string id)
void start_element(const string id, const ssize_type radius=0, const ssize_type cx=0, const ssize_type cy=0)
void add_data(const data &d)
Either serialize immediately (as below), or create data structure that adds data to data_vec and then...
stream_type _M_sstream
Virtual, only one buffer.
void start_element(const string &id)
void start_element(const string id, const ssize_type radius, const ssize_type cx, const ssize_type cy, const ssize_type fr, const ssize_type fx, const ssize_type fy)
static const script_element tooltip_script(const scope context)
void add_style(const style &sty)
virtual void add_text(string txt)
void str(const string &s)
void start_element(const string id)
void add_data(const data &d, const string dasharray="")
svg_element(const string __title, const area &__cv, const bool lifetime=true, const unit u=svg::unit::pixel, const typography &__typo=k::smono_typo)
void finish_element()
SVG element end boilerplate.
void add_data(const string fltr)
void add_data(const area<> a, const string src, const string mtype="image/jpeg", const string attr=R"(sandbox="allow-scripts allow-same-origin")")
iframe. a is width and height of video as embedded in page r is the foreign object,...
const string offset_percentage(const ssize_type numer, const ssize_type denom)
void start_element(const string id, const area<> blur_area, const point_2t p)
static const string & tooltip_javascript(const scope context)
showTooltip(id) hideTooltip(id) event.x vs. event.pageX, event.y vs. event.pageY
void start_element(const point_2t origin, const area<> av, const area<>, const point_2t scale=std::make_tuple(1.0, 1.0))
void add_desc(const string desc)
text_path_element(const string name, const string off="", const string whichside="")
void add_data(const area<> a, const string src, const string mtype="image/jpeg", const string attr=R"(sandbox="allow-scripts allow-same-origin")")
Add resource to object.
static string finish_tspan()
void start_element(const string &id)
void add_data(const data &d, string trans="")
void add_transform(const string s)
static constexpr const char * pair_open_tag
void start_element()
For groups of elements that have the same name.
void start_element(string name)
static string finish_defs()
static constexpr const char * pair_finish_tag
void add_data(const vrange &points)
static string finish_group()
const point_2t center_point()
void add_data(const area<> a, const string src, const string mtype="video/mp4", const string attr=R"(autoplay="true" loop="true" muted="true")")
Video. a is width and height of video as embedded in page r is the foreign object,...
static constexpr const char * self_finish_tag
void add_data(const string scriptstr)
Add string with script source.
void add_title(const string &t)
void add_data(const data &d)
Either serialize immediately (as below), or create data structure that adds data to data_vec and then...
void start_element(string name, const style &sty)
void start_element()
SVG element beginning boilerplate for outermost (containing) svg_element. Variable: unit,...
void stop(const string off, const color &klr, const double opacity=1.0)
static string start_defs()
string gaussian_blur(string dev)
static const string tooltip_attribute(const string &id)
static constexpr const char * finish_tag
static string start_tspan_y(uint xpos, string dy)
For text list output, use tspan for line breaks. This span creates a new horizontal line for every ts...
void add_data(const data &d, const string trans="", const unit utype=svg::unit::point)
Either serialize immediately (as below), or create data structure that adds data to data_vec and then...
static string start_tspan_y(uint xpos, uint dy)
static constexpr const char * pair_finish_tag
virtual void start_element()=0
void start_element(const string &id)
svg_element(const string __title, const string desc, const area &__cv, const bool lifetime=true)
static string start_group(const string name)
void start_element(string name)
void add_data(const data &d, const string cors, const string vattr, const string display="")
Visibility and other HTML/img attributes.
static string start_tspan_x(uint xpos, string dx)
For text list output, use tspan for line breaks. This span creates a new vertical line space for ever...
std::ostringstream stream_type
static constexpr const char * pair_finish_tag
void add_data(const data &d)
Either serialize immediately (as below), or create data structure that adds data to data_vec and then...
void start_element(const string &id)
@ feOffset
Offset, dx="0", dy="0".
@ feGaussianBlur
Gaussian Blur.
const typography & _M_typo
void add_raw(const string &raw)
void start_element(const string name)
scope
Where is the script element placed? On/within the element itself, or at the document (global)?...
@ none
Script scope removed.
@ element
Scripts scoped to element.
@ parent
Scripts scoped to parent.
@ document
Scripts scoped to toplevel document.
virtual void finish_element()=0
bool empty()
Empty when the output buffer is.
static constexpr const char * pair_open_tag
void add_fill(const string id)
void start_element(const string id, const area<> a, const point_2t p)
void add_data(const string &url, const string relt, const string ast, const string cors="anonymous")
Overload for rel=x form. https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/p...
void start(const string &desc="")
void add_element(const element_base &e)
void start_element(const string t)
string make_transform_attribute(const string s)
Common transforms include rotate(180)
void finish(const bool writep=true)
static constexpr const char * pair_open_tag
void start_element(const string &id)
static constexpr string finish_tag_hard
polyline_element(const vrange &points)
svg_element(const svg_element &other)
void start_element(string name)
string make_tspan_y_from_string_by_token(string s, uint xpos, const char token=' ')
Make text span.
void store_element(const element_base &e)
Abstract base class for all SVG Elements.
iframe HTML object embedded in SVG container. NB: HTML elements video/audio/iframe/canvas can be used...
Linear gradients https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient.
HTML object embedded in SVG container. Unlike image_elements, object_elements are not locked down for...
Circular gradients https://developer.mozilla.org/en-US/docs/Web/SVG/Element/radialGradient.
video HTML object embedded in SVG container. NB: HTML elements video/audio/iframe/canvas can be used ...
color
Color enumerated as types.
unit
Measurement abstraction for absolute (not relative) measurements.
@ pt
Point where 1 pixel x 1/72 dpi x 96 PPI = .26 mm.
const string to_string(const unit e)
void string_replace(std::string &target, const std::string &match, const std::string &replace)
double space_type
Base floating point type.
std::vector< point_2t > vrange
std::tuple< space_type, space_type > point_2t
Point (x,y) in 2D space, space_type defaults to double.
Color quantified as integral RGB components in the range [0,255]. aka like Scalar in OpenCV.
Additional path/line/polyline stroke styles. NB: https://yuanchuan.dev/fun-with-stroke-dasharray.
string dashoffset
Starting offset for line dashes. https://developer.mozilla.org/en-US/docs/Web/CSS/stroke-dashoffset.
string dasharray
Line dash vs. space configuration. Options are single value, like 2, meaning 2 sized dash 2 sized spa...
string linecap
Shape of end of line segments in line dashes. SVG Values are: butt, round, square....
string marker_defs
Marker string pointing to definitions elements. For graph_mode 1, this means the SVG equivalent of CS...
Datum consolidating style preferences.
const std::string add_attribute(const svg::unit utype=svg::unit::pixel) const