8#include <tracking/trackFindingCDC/display/SVGPrimitivePlotter.h> 
   10#include <framework/logging/Logger.h> 
   15using namespace TrackFindingCDC;
 
   22  , m_svgContentStream()
 
   23  , m_nIndentationSpaces(s_defaultNIndentationSpaces)
 
   30  , m_svgContentStream()
 
   31  , m_nIndentationSpaces(s_defaultNIndentationSpaces)
 
   32  , m_svgAttributes(svgAttributes)
 
   38  , m_svgContentStream(plotter.m_svgContentStream.str(), 
std::ostringstream::ate)
 
   39  , m_nIndentationSpaces(plotter.m_nIndentationSpaces)
 
   40  , m_svgAttributes(plotter.m_svgAttributes)
 
   46  return std::make_unique<SVGPrimitivePlotter>(*
this);
 
   58    {
"x1", std::to_string(startX)},
 
   59    {
"x2", std::to_string(endX)},
 
   60    {
"y1", std::to_string(startY)},
 
   61    {
"y2", std::to_string(endY)}
 
   78    {
"x1", std::to_string(startX)},
 
   79    {
"x2", std::to_string(endX)},
 
   80    {
"y1", std::to_string(startY)},
 
   81    {
"y2", std::to_string(endY)},
 
   82    {
"marker-end", 
"url(#endArrow)"}
 
   97    {
"cx", std::to_string(centerX)},
 
   98    {
"cy", std::to_string(centerY)},
 
   99    {
"r", std::to_string(std::fabs(radius))}
 
  129  const float radiusX = std::fabs(radius);
 
  130  const float radiusY = std::fabs(radius);
 
  131  const float rotationAngle = 0;
 
  133  std::ostringstream pathStream;
 
  135  pathStream << 
"M" << 
' ';
 
  136  pathStream << std::to_string(startX) << 
' ';
 
  137  pathStream << std::to_string(startY) << 
' ';
 
  138  pathStream << 
"A" << 
' ';
 
  139  pathStream << std::to_string(radiusX) << 
' ';
 
  140  pathStream << std::to_string(radiusY) << 
' ';
 
  141  pathStream << std::to_string(rotationAngle) << 
' ';
 
  142  pathStream << std::to_string(longArc) << 
' ';
 
  143  pathStream << std::to_string(sweepFlag) << 
' ';
 
  144  pathStream << std::to_string(endX) << 
' ';
 
  145  pathStream << std::to_string(endY);
 
  147  AttributeMap geometryAttributeMap{{
"d", pathStream.str()}};
 
  153                                    const std::vector<std::array<float, 2>>& tangents,
 
  157  static const double k = 4.0 / 3.0 * (std::sqrt(2.0) - 1.0);
 
  159  B2ASSERT(
"Expect number of points and tangents to be the same", points.size() == tangents.size());
 
  160  if (points.size() < 2) 
return;
 
  164  std::ostringstream pathStream;
 
  167  float startX = std::get<0>(points[0]);
 
  168  float startY = std::get<1>(points[0]);
 
  171  pathStream << 
' ' << std::to_string(startX);
 
  172  pathStream << 
' ' << std::to_string(startY);
 
  174  for (
size_t iCurrent = 0, iNext = 1; iNext < points.size(); iCurrent = iNext, ++iNext) {
 
  176    float currentTX = std::get<0>(tangents[iCurrent]);
 
  177    float currentTY = std::get<1>(tangents[iCurrent]);
 
  179    float nextTX = std::get<0>(tangents[iNext]);
 
  180    float nextTY = std::get<1>(tangents[iNext]);
 
  182    float currentT = std::hypot(currentTX, currentTY);
 
  183    float nextT = std::hypot(nextTX, nextTY);
 
  185    currentTX /= currentT;
 
  186    currentTY /= currentT;
 
  190    float currentX = std::get<0>(points[iCurrent]);
 
  191    float currentY = std::get<1>(points[iCurrent]);
 
  193    float nextX = std::get<0>(points[iNext]);
 
  194    float nextY = std::get<1>(points[iNext]);
 
  197    float alpha = std::atan2(currentTX * nextTY - currentTY * nextTX,
 
  198                             currentTX * nextTX + currentTY * nextTY);
 
  200    float distance = std::hypot(currentX - nextX, currentY - nextY);
 
  201    float controlLength = k * distance / 2 / std::cos(alpha / 2);
 
  203    float currentControlX = currentX + currentTX * controlLength;
 
  204    float currentControlY = currentY + currentTY * controlLength;
 
  206    float nextControlX = nextX - nextTX * controlLength;
 
  207    float nextControlY = nextY - nextTY * controlLength;
 
  209    pathStream << 
' ' << 
"C";
 
  211    pathStream << 
' ' << std::to_string(currentControlX);
 
  212    pathStream << 
' ' << std::to_string(currentControlY);
 
  214    pathStream << 
' ' << std::to_string(nextControlX);
 
  215    pathStream << 
' ' << std::to_string(nextControlY);
 
  217    pathStream << 
' ' << std::to_string(nextX);
 
  218    pathStream << 
' ' << std::to_string(nextY);
 
  221  AttributeMap geometryAttributeMap{{
"d", pathStream.str()}};
 
  240    B2WARNING(
"Mismatching calls to startGroup and endGroup detected. " 
  241              << 
"Proceeding to write the illforamed result.");
 
  247  std::ofstream outputFileStream;
 
  248  outputFileStream.open(fileName);
 
  253    {
"baseProfile", 
"full"},
 
  254    {
"ev", 
"http://www.w3.org/2001/xml-events"},
 
  256    {
"xlink", 
"http://www.w3.org/1999/xlink"},
 
  257    {
"xmlns", 
"http://www.w3.org/2000/svg"}
 
  263  std::ostringstream viewBoxStringStream;
 
  266  viewBoxStringStream << 
" ";
 
  268  viewBoxStringStream << 
" ";
 
  270  viewBoxStringStream << 
" ";
 
  276    {
"viewBox", viewBoxStringStream.str()},
 
  281  writeOpeningTag(outputFileStream, 
"svg", standardAttributeMap, variableAttributeMap);
 
  290  outputFileStream.close();
 
  315  outputStream << 
"<?xml version=\"1.0\" ?>" << std::endl;
 
  316  outputStream << 
"<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>" << std::endl;
 
  325    { 
"viewBox", 
"0 0 10 10"},
 
  328    { 
"markerUnits", 
"strokeWidth"},
 
  329    { 
"markerWidth", 
"4"},
 
  330    { 
"markerHeight", 
"3"},
 
  338    {
"points", 
"0,0 10,5 0,10 1,5"},
 
  349                                          const std::string& tagName,
 
  360  writeTagIntern(outputStream, tagName, geometryAttributeMap, styleAttributeMap);
 
  366  outputStream << std::endl;
 
  370  if (geometryAttributeMap.count(
"_showAt") + styleAttributeMap.count(
"_showAt")) {
 
  371    const std::string showAt = geometryAttributeMap.count(
"_showAt")
 
  372                               ? geometryAttributeMap.at(
"_showAt")
 
  373                               : styleAttributeMap.at(
"_showAt");
 
  376      {
"attributeName", 
"visibility"},
 
  387                                             const std::string& tagName,
 
  392  if (geometryAttributeMap.count(
"_showAt") + styleAttributeMap.count(
"_showAt")) {
 
  393    writeOpeningTag(outputStream, tagName, geometryAttributeMap, styleAttributeMap);
 
  404    writeTagIntern(outputStream, tagName, geometryAttributeMap, styleAttributeMap);
 
  407    outputStream << 
'/' << 
'>';
 
  410    outputStream << std::endl;
 
  415                                         const std::string& tagName,
 
  420  outputStream << tagName;
 
  423  if (not geometryAttributeMap.empty()) {
 
  429  if (not styleAttributeMap.empty()) {
 
  439  for (
const std::pair<std::string, std::string> attribute : attributeMap) {
 
  441    const std::string& key = attribute.first;
 
  442    const std::string& value = attribute.second;
 
  457    outputStream << 
'=' << 
'"';
 
  458    outputStream << value;
 
  471  outputStream << 
'<' << 
'/';
 
  474  outputStream << tagName;
 
  480  outputStream << std::endl;
 
float getBottom() const
Getter for the location of the bottom of the bounding box rectangle (lower y bound)....
float getWidth() const
Getter for the width of the bounding box rectangle.
float getLeft() const
Getter for the location of the left of the bounding box rectangle (lower x bound)....
float getHeight() const
Getter for the height of the bounding box rectangle.
A base class for plots of primitive objects.
float getCanvasWidth()
Getter for the canvas width in pixels.
virtual void drawCurve(const std::vector< std::array< float, 2 > > &points, const std::vector< std::array< float, 2 > > &tangents, const AttributeMap &attributeMap=AttributeMap())
Adds a smooth curve to the plot.
const BoundingBox & getBoundingBox() const
Getter for the bounding box of all drawed objects.
virtual void drawCircleArc(float startX, float startY, float endX, float endY, float radius, bool longArc, bool sweepFlag, const AttributeMap &attributeMap=AttributeMap())
Adds a circle arc to the plot.
virtual void drawArrow(float startX, float startY, float endX, float endY, const AttributeMap &attributeMap=AttributeMap())
Adds an arrow to the plot.
Belle2::TrackFindingCDC::AttributeMap AttributeMap
A map type for attributes names to values for additional drawing information.
float getCanvasHeight()
Getter for the canvas height in pixels.
virtual void clear()
Clears all drawed elements from the plotter.
virtual void drawLine(float startX, float startY, float endX, float endY, const AttributeMap &attributeMap=AttributeMap())
Adds a line to the plot.
virtual void drawCircle(float centerX, float centerY, float radius, const AttributeMap &attributeMap=AttributeMap())
Adds a circle to the plot.
A concrete plotter that can draw primitive objects to standalone SVG files.
void startGroup(const AttributeMap &attributeMap=AttributeMap()) override
Indicates the start of a group of drawn elements.
std::unique_ptr< PrimitivePlotter > clone() const override
Returns a newly created plotter instance containing all information of this.
void indent()
Increases the current indention by one.
void writeAttributes(std::ostream &outputStream, const AttributeMap &attributeMap)
Writes attribute specification that belongs between the <, > brakets after the tag name.
void drawCurve(const std::vector< std::array< float, 2 > > &points, const std::vector< std::array< float, 2 > > &tangents, const AttributeMap &attributeMap=AttributeMap()) override
Adds a smooth curve to the plot.
void writeStandAloneTag(std::ostream &outputStream, const std::string &tagName, const AttributeMap &geometryAttributeMap=AttributeMap(), const AttributeMap &styleAttributeMap=AttributeMap())
Writes a stand alone xml tag to the given output stream taking attributes from two sources.
std::ostringstream m_svgContentStream
Memory for the plotted elements. This contains only the fragment that is inbetween the svg tags and c...
int m_nIndentationSpaces
Memory for the number of spaces that shall be prepended to each line.
void writeSVGDefs(std::ostream &outputStream)
Writes a preamble of definitions that define an arrow cap which can be referenced by lines.
static const int s_defaultNIndentationSpaces
Constant for the number of indention space to be used within the svg block.
AttributeMap m_svgAttributes
Memory for additional attributes to the toplevel svg element.
void drawCircleArc(float startX, float startY, float endX, float endY, float radius, bool longArc, bool sweepFlag, const AttributeMap &attributeMap=AttributeMap()) override
Adds a circle arc to the plot.
void drawCircle(float centerX, float centerY, float radius, const AttributeMap &attributeMap=AttributeMap()) override
Adds a circle to the plot.
SVGPrimitivePlotter()
Default constructor for ROOT compatibility.
void writeSVGHeader(std::ostream &outputStream)
Writes the xml header that indicates that this document will be a SVG document to the given output st...
void drawLine(float startX, float startY, float endX, float endY, const AttributeMap &attributeMap=AttributeMap()) override
Adds a line to the plot.
void drawArrow(float startX, float startY, float endX, float endY, const AttributeMap &attributeMap=AttributeMap()) override
Adds an arrow to the plot.
void writeOpeningTag(std::ostream &outputStream, const std::string &tagName, const AttributeMap &geometryAttributeMap=AttributeMap(), const AttributeMap &styleAttributeMap=AttributeMap())
Writes an opening xml tag to the given output stream taking attributes from two sources.
void dedent()
Decreases the current indention by one.
void clear() override
Clears all drawed elements from the plotter.
static const int s_addtionalNIndentationSpaces
Constant for the additional number of space to be prepended with each open tag group.
const std::string save(const std::string &fileName) override
Saves the current plot state to a file.
void writeTagIntern(std::ostream &outputStream, const std::string &tagName, const AttributeMap &geometryAttributeMap=AttributeMap(), const AttributeMap &styleAttributeMap=AttributeMap())
Writes part that belongs between the <, > brakets.
void endGroup() override
Indicates the end of a group of drawn elements.
void writeClosingTag(std::ostream &outputStream, const std::string &tagName)
Writes a closing xml tag to the given output stream.
Abstract base class for different kinds of events.