axis_tag.cpp 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #include "axis_tag.h"
  2. AxisTag::AxisTag(QCPAxis *parentAxis) : QObject(parentAxis), mAxis(parentAxis)
  3. {
  4. // The dummy tracer serves here as an invisible anchor which always sticks to the right side of
  5. // the axis rect
  6. mDummyTracer = new QCPItemTracer(mAxis->parentPlot());
  7. mDummyTracer->setVisible(false);
  8. mDummyTracer->position->setTypeX(QCPItemPosition::ptAxisRectRatio);
  9. mDummyTracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
  10. mDummyTracer->position->setAxisRect(mAxis->axisRect());
  11. mDummyTracer->position->setAxes(0, mAxis);
  12. mDummyTracer->position->setCoords(1, 0);
  13. // the arrow end (head) is set to move along with the dummy tracer by setting it as its parent
  14. // anchor. Its coordinate system (setCoords) is thus pixels, and this is how the needed horizontal
  15. // offset for the tag of the second y axis is achieved. This horizontal offset gets dynamically
  16. // updated in AxisTag::updatePosition. the arrow "start" is simply set to have the "end" as parent
  17. // anchor. It is given a horizontal offset to the right, which results in a 15 pixel long arrow.
  18. mArrow = new QCPItemLine(mAxis->parentPlot());
  19. mArrow->setLayer("overlay");
  20. mArrow->setClipToAxisRect(false);
  21. mArrow->setHead(QCPLineEnding::esSpikeArrow);
  22. mArrow->end->setParentAnchor(mDummyTracer->position);
  23. mArrow->start->setParentAnchor(mArrow->end);
  24. mArrow->start->setCoords(15, 0);
  25. // The text label is anchored at the arrow start (tail) and has its "position" aligned at the
  26. // left, and vertically centered to the text label box.
  27. mLabel = new QCPItemText(mAxis->parentPlot());
  28. mLabel->setLayer("overlay");
  29. mLabel->setClipToAxisRect(false);
  30. mLabel->setPadding(QMargins(3, 0, 3, 0));
  31. mLabel->setBrush(QBrush(Qt::white));
  32. mLabel->setPen(QPen(Qt::blue));
  33. mLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignVCenter);
  34. mLabel->position->setParentAnchor(mArrow->start);
  35. }
  36. AxisTag::~AxisTag()
  37. {
  38. if (mDummyTracer)
  39. mDummyTracer->parentPlot()->removeItem(mDummyTracer);
  40. if (mArrow)
  41. mArrow->parentPlot()->removeItem(mArrow);
  42. if (mLabel)
  43. mLabel->parentPlot()->removeItem(mLabel);
  44. }
  45. void AxisTag::setPen(const QPen &pen)
  46. {
  47. mArrow->setPen(pen);
  48. mLabel->setPen(pen);
  49. }
  50. void AxisTag::setBrush(const QBrush &brush)
  51. {
  52. mLabel->setBrush(brush);
  53. }
  54. void AxisTag::setText(const QString &text)
  55. {
  56. mLabel->setText(text);
  57. }
  58. void AxisTag::updatePosition(double value)
  59. {
  60. // since both the arrow and the text label are chained to the dummy tracer (via anchor
  61. // parent-child relationships) it is sufficient to update the dummy tracer coordinates. The
  62. // Horizontal coordinate type was set to ptAxisRectRatio so to keep it aligned at the right side
  63. // of the axis rect, it is always kept at 1. The vertical coordinate type was set to
  64. // ptPlotCoordinates of the passed parent axis, so the vertical coordinate is set to the new
  65. // value.
  66. mDummyTracer->position->setCoords(1, value);
  67. // We want the arrow head to be at the same horizontal position as the axis backbone, even if
  68. // the axis has a certain offset from the axis rect border (like the added second y axis). Thus we
  69. // set the horizontal pixel position of the arrow end (head) to the axis offset (the pixel
  70. // distance to the axis rect border). This works because the parent anchor of the arrow end is
  71. // the dummy tracer, which, as described earlier, is tied to the right axis rect border.
  72. mArrow->end->setCoords(mAxis->offset(), 0);
  73. }