summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2016-09-21 14:45:41 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2016-09-23 09:55:41 +0000
commit3cb2c5e7572a75a4fae8883c9c0f3141cdf207b9 (patch)
tree1fa529e85c919755d9d4048b8240a6876d34199a
parent06c412094b60517af015637322798da6224e34c2 (diff)
Add a possibility to change legend marker shape
It is now possible to choose between rectangular, circular, and "from series" shapes for legend markers. The "from series" shape uses scatter dot items as legend markers in case of scatter series and a line segment for line and spline series. Task-number: QTBUG-50682 Change-Id: I58977ead88e1274e1f163516d32c4d290f4410f9 Reviewed-by: Andy Shaw <andy.shaw@qt.io>
-rw-r--r--examples/charts/scatterchart/chartview.cpp11
-rw-r--r--src/charts/doc/images/examples_scatterchart.pngbin30702 -> 25298 bytes
-rw-r--r--src/charts/doc/src/examples-scatterchart.qdoc3
-rw-r--r--src/charts/legend/legendmarkeritem.cpp198
-rw-r--r--src/charts/legend/legendmarkeritem_p.h32
-rw-r--r--src/charts/legend/qlegend.cpp72
-rw-r--r--src/charts/legend/qlegend.h14
-rw-r--r--src/charts/legend/qlegend_p.h2
-rw-r--r--src/charts/legend/qlegendmarker.cpp38
-rw-r--r--src/charts/legend/qlegendmarker.h6
-rw-r--r--src/charts/legend/qlegendmarker_p.h2
-rw-r--r--src/charts/legend/qxylegendmarker.cpp16
-rw-r--r--tests/manual/qmlchartproperties/qml/qmlchartproperties/ChartEditorLegend.qml12
13 files changed, 368 insertions, 38 deletions
diff --git a/examples/charts/scatterchart/chartview.cpp b/examples/charts/scatterchart/chartview.cpp
index 3a6c9240..c2f099c1 100644
--- a/examples/charts/scatterchart/chartview.cpp
+++ b/examples/charts/scatterchart/chartview.cpp
@@ -69,10 +69,10 @@ ChartView::ChartView(QWidget *parent) :
//![3]
QPainterPath starPath;
- starPath.moveTo(30, 15);
+ starPath.moveTo(28, 15);
for (int i = 1; i < 5; ++i) {
- starPath.lineTo(15 + 15 * qCos(0.8 * i * Pi),
- 15 + 15 * qSin(0.8 * i * Pi));
+ starPath.lineTo(14 + 14 * qCos(0.8 * i * Pi),
+ 15 + 14 * qSin(0.8 * i * Pi));
}
starPath.closeSubpath();
@@ -86,6 +86,7 @@ ChartView::ChartView(QWidget *parent) :
painter.drawPath(starPath);
series2->setBrush(star);
+ series2->setPen(QColor(Qt::transparent));
//![3]
//![4]
@@ -100,8 +101,6 @@ ChartView::ChartView(QWidget *parent) :
//![4]
//![5]
- QList<QLegendMarker *> markers = chart()->legend()->markers(series2);
- for (int i = 0; i < markers.count(); i++)
- markers.at(i)->setBrush(painter.pen().color());
+ chart()->legend()->setMarkerShape(QLegend::MarkerShapeFromSeries);
//![5]
}
diff --git a/src/charts/doc/images/examples_scatterchart.png b/src/charts/doc/images/examples_scatterchart.png
index 41900f66..6ffaed35 100644
--- a/src/charts/doc/images/examples_scatterchart.png
+++ b/src/charts/doc/images/examples_scatterchart.png
Binary files differ
diff --git a/src/charts/doc/src/examples-scatterchart.qdoc b/src/charts/doc/src/examples-scatterchart.qdoc
index 938a61f9..1aaa16a2 100644
--- a/src/charts/doc/src/examples-scatterchart.qdoc
+++ b/src/charts/doc/src/examples-scatterchart.qdoc
@@ -56,8 +56,7 @@
\snippet scatterchart/chartview.cpp 4
- The image used as a brush for the scatter series may contain several colors. Therefore we need
- to set the desired color explicitly by setting the brush for the legend marker items.
+ We can also use the scatter points as legend markers.
\snippet scatterchart/chartview.cpp 5
diff --git a/src/charts/legend/legendmarkeritem.cpp b/src/charts/legend/legendmarkeritem.cpp
index 1c0b5901..ec75659f 100644
--- a/src/charts/legend/legendmarkeritem.cpp
+++ b/src/charts/legend/legendmarkeritem.cpp
@@ -30,9 +30,16 @@
#include <QtGui/QPainter>
#include <QtWidgets/QGraphicsSceneEvent>
#include <QtWidgets/QGraphicsTextItem>
+#include <QtWidgets/QGraphicsEllipseItem>
+#include <QtWidgets/QGraphicsRectItem>
+#include <QtWidgets/QGraphicsLineItem>
#include <QtGui/QTextDocument>
+#include <QtCore/QtMath>
#include <QtCharts/QLegend>
+#include <QtCharts/QScatterSeries>
+#include <QtCharts/QLineSeries>
+#include <QtCharts/QSplineSeries>
#include <private/qlegend_p.h>
#include <QtCharts/QLegendMarker>
#include <private/qlegendmarker_p.h>
@@ -44,16 +51,18 @@ QT_CHARTS_BEGIN_NAMESPACE
LegendMarkerItem::LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent) :
QGraphicsObject(parent),
m_marker(marker),
- m_markerRect(0,0,10.0,10.0),
+ m_defaultMarkerRect(0.0, 0.0, 10.0, 10.0),
+ m_markerRect(0.0, 0.0, -1.0, -1.0),
m_boundingRect(0,0,0,0),
m_textItem(new QGraphicsTextItem(this)),
- m_rectItem(new QGraphicsRectItem(this)),
+ m_markerItem(nullptr),
m_margin(3),
m_space(4),
+ m_markerShape(QLegend::MarkerShapeDefault),
m_hovering(false),
- m_pressPos(0, 0)
+ m_itemType(TypeRect)
{
- m_rectItem->setRect(m_markerRect);
+ updateMarkerShapeAndSize();
m_textItem->document()->setDocumentMargin(ChartPresenter::textMargin());
setAcceptHoverEvents(true);
}
@@ -67,41 +76,52 @@ LegendMarkerItem::~LegendMarkerItem()
void LegendMarkerItem::setPen(const QPen &pen)
{
- m_rectItem->setPen(pen);
+ m_pen = pen;
+ setItemBrushAndPen();
}
QPen LegendMarkerItem::pen() const
{
- return m_rectItem->pen();
+ return m_pen;
}
void LegendMarkerItem::setBrush(const QBrush &brush)
{
- m_rectItem->setBrush(brush);
+ m_brush = brush;
+ setItemBrushAndPen();
}
QBrush LegendMarkerItem::brush() const
{
- return m_rectItem->brush();
+ return m_brush;
}
-void LegendMarkerItem::setFont(const QFont &font)
+void LegendMarkerItem::setSeriesPen(const QPen &pen)
+{
+ m_seriesPen = pen;
+ setItemBrushAndPen();
+}
+
+void LegendMarkerItem::setSeriesBrush(const QBrush &brush)
{
- m_textItem->setFont(font);
+ m_seriesBrush = brush;
+ setItemBrushAndPen();
+}
+void LegendMarkerItem::setFont(const QFont &font)
+{
QFontMetrics fn(font);
- QRectF markerRect = QRectF(0, 0, fn.height() / 2, fn.height() / 2);
- if (m_markerRect != markerRect) {
- m_markerRect = markerRect;
- emit markerRectChanged();
- }
+ m_font = font;
- updateGeometry();
+ m_defaultMarkerRect = QRectF(0, 0, fn.height() / 2, fn.height() / 2);
+ if (effectiveMarkerShape() != QLegend::MarkerShapeFromSeries)
+ updateMarkerShapeAndSize();
+ m_marker->invalidateLegend();
}
QFont LegendMarkerItem::font() const
{
- return m_textItem->font();
+ return m_font;
}
void LegendMarkerItem::setLabel(const QString label)
@@ -127,10 +147,11 @@ QBrush LegendMarkerItem::labelBrush() const
void LegendMarkerItem::setGeometry(const QRectF &rect)
{
- qreal width = rect.width();
- qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
+ const qreal width = rect.width();
+ const qreal markerWidth = effectiveMarkerWidth();
+ const qreal x = m_margin + markerWidth + m_space + m_margin;
QRectF truncatedRect;
- const QString html = ChartPresenter::truncatedText(m_textItem->font(), m_label, qreal(0.0),
+ const QString html = ChartPresenter::truncatedText(m_font, m_label, qreal(0.0),
width - x, rect.height(), truncatedRect);
m_textItem->setHtml(html);
if (m_marker->m_legend->showToolTips() && html != m_label)
@@ -138,6 +159,7 @@ void LegendMarkerItem::setGeometry(const QRectF &rect)
else
m_textItem->setToolTip(QString());
+ m_textItem->setFont(m_font);
m_textItem->setTextWidth(truncatedRect.width());
qreal y = qMax(m_markerRect.height() + 2 * m_margin, truncatedRect.height() + 2 * m_margin);
@@ -145,9 +167,12 @@ void LegendMarkerItem::setGeometry(const QRectF &rect)
const QRectF &textRect = m_textItem->boundingRect();
m_textItem->setPos(x - m_margin, y / 2 - textRect.height() / 2);
- m_rectItem->setRect(m_markerRect);
+ setItemRect();
+
// The textMargin adjustments to position are done to make default case rects less blurry with anti-aliasing
- m_rectItem->setPos(m_margin - ChartPresenter::textMargin(), y / 2.0 - m_markerRect.height() / 2.0 + ChartPresenter::textMargin());
+ m_markerItem->setPos(m_margin - ChartPresenter::textMargin()
+ + (markerWidth - m_markerRect.width()) / 2.0,
+ y / 2.0 - m_markerRect.height() / 2.0 + ChartPresenter::textMargin());
prepareGeometryChange();
m_boundingRect = QRectF(0, 0, x + textRect.width() + m_margin, y);
@@ -175,18 +200,18 @@ QSizeF LegendMarkerItem::sizeHint(Qt::SizeHint which, const QSizeF& constraint)
Q_UNUSED(constraint)
QSizeF sh;
+ const qreal markerWidth = effectiveMarkerWidth();
switch (which) {
case Qt::MinimumSize: {
- QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(),
- QStringLiteral("..."));
- sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
+ const QRectF labelRect = ChartPresenter::textBoundingRect(m_font, QStringLiteral("..."));
+ sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + markerWidth,
qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
break;
}
case Qt::PreferredSize: {
- QRectF labelRect = ChartPresenter::textBoundingRect(m_textItem->font(), m_label);
- sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + m_markerRect.width(),
+ const QRectF labelRect = ChartPresenter::textBoundingRect(m_font, m_label);
+ sh = QSizeF(labelRect.width() + (2.0 * m_margin) + m_space + markerWidth,
qMax(m_markerRect.height(), labelRect.height()) + (2.0 * m_margin));
break;
}
@@ -221,6 +246,125 @@ void LegendMarkerItem::setToolTip(const QString &tip)
m_textItem->setToolTip(tip);
}
+QLegend::MarkerShape LegendMarkerItem::markerShape() const
+{
+ return m_markerShape;
+}
+
+void LegendMarkerItem::setMarkerShape(QLegend::MarkerShape shape)
+{
+ m_markerShape = shape;
+}
+
+void LegendMarkerItem::updateMarkerShapeAndSize()
+{
+ const QLegend::MarkerShape shape = effectiveMarkerShape();
+
+ ItemType itemType = TypeRect;
+ QRectF newRect = m_defaultMarkerRect;
+ if (shape == QLegend::MarkerShapeFromSeries) {
+ QScatterSeries *scatter = qobject_cast<QScatterSeries *>(m_marker->series());
+ if (scatter) {
+ newRect.setSize(QSizeF(scatter->markerSize(), scatter->markerSize()));
+ if (scatter->markerShape() == QScatterSeries::MarkerShapeCircle)
+ itemType = TypeCircle;
+ } else if (qobject_cast<QLineSeries *>(m_marker->series())
+ || qobject_cast<QSplineSeries *>(m_marker->series())) {
+ newRect.setHeight(m_seriesPen.width());
+ newRect.setWidth(qRound(m_defaultMarkerRect.width() * 1.5));
+ itemType = TypeLine;
+ }
+ } else if (shape == QLegend::MarkerShapeCircle) {
+ itemType = TypeCircle;
+ }
+
+ if (!m_markerItem || m_itemType != itemType) {
+ m_itemType = itemType;
+ QPointF oldPos;
+ if (m_markerItem) {
+ oldPos = m_markerItem->pos();
+ delete m_markerItem;
+ }
+ if (itemType == TypeRect)
+ m_markerItem = new QGraphicsRectItem(this);
+ else if (itemType == TypeCircle)
+ m_markerItem = new QGraphicsEllipseItem(this);
+ else
+ m_markerItem = new QGraphicsLineItem(this);
+ // Immediately update the position to the approximate correct position to avoid marker
+ // jumping around when changing markers
+ m_markerItem->setPos(oldPos);
+ }
+ setItemBrushAndPen();
+
+ if (newRect != m_markerRect) {
+ if (useMaxWidth() && m_marker->m_legend->d_ptr->maxMarkerWidth() < newRect.width())
+ m_marker->invalidateAllItems();
+ m_markerRect = newRect;
+ setItemRect();
+ emit markerRectChanged();
+ updateGeometry();
+ }
+}
+
+QLegend::MarkerShape LegendMarkerItem::effectiveMarkerShape() const
+{
+ QLegend::MarkerShape shape = m_markerShape;
+ if (shape == QLegend::MarkerShapeDefault)
+ shape = m_marker->m_legend->markerShape();
+ return shape;
+}
+
+qreal LegendMarkerItem::effectiveMarkerWidth() const
+{
+ return useMaxWidth() ? m_marker->m_legend->d_ptr->maxMarkerWidth()
+ : m_markerRect.width();
+}
+
+void LegendMarkerItem::setItemBrushAndPen()
+{
+ if (m_markerItem) {
+ QAbstractGraphicsShapeItem *shapeItem =
+ qgraphicsitem_cast<QGraphicsRectItem *>(m_markerItem);
+ if (!shapeItem)
+ shapeItem = qgraphicsitem_cast<QGraphicsEllipseItem *>(m_markerItem);
+ if (shapeItem) {
+ if (effectiveMarkerShape() == QLegend::MarkerShapeFromSeries) {
+ shapeItem->setPen(m_seriesPen);
+ shapeItem->setBrush(m_seriesBrush);
+ } else {
+ shapeItem->setPen(m_pen);
+ shapeItem->setBrush(m_brush);
+ }
+ } else {
+ // Must be line item, it has no brush.
+ QGraphicsLineItem *lineItem =
+ qgraphicsitem_cast<QGraphicsLineItem *>(m_markerItem);
+ if (lineItem)
+ lineItem->setPen(m_seriesPen);
+ }
+ }
+}
+
+void LegendMarkerItem::setItemRect()
+{
+ if (m_itemType == TypeRect) {
+ static_cast<QGraphicsRectItem *>(m_markerItem)->setRect(m_markerRect);
+ } else if (m_itemType == TypeCircle) {
+ static_cast<QGraphicsEllipseItem *>(m_markerItem)->setRect(m_markerRect);
+ } else {
+ qreal y = m_markerRect.height() / 2.0;
+ QLineF line(0.0, y, m_markerRect.width(), y);
+ static_cast<QGraphicsLineItem *>(m_markerItem)->setLine(line);
+ }
+}
+
+bool LegendMarkerItem::useMaxWidth() const
+{
+ return (m_marker->m_legend->alignment() == Qt::AlignLeft
+ || m_marker->m_legend->alignment() == Qt::AlignRight);
+}
+
#include "moc_legendmarkeritem_p.cpp"
QT_CHARTS_END_NAMESPACE
diff --git a/src/charts/legend/legendmarkeritem_p.h b/src/charts/legend/legendmarkeritem_p.h
index c3371742..5325f8d1 100644
--- a/src/charts/legend/legendmarkeritem_p.h
+++ b/src/charts/legend/legendmarkeritem_p.h
@@ -40,6 +40,7 @@
#define LEGENDMARKERITEM_P_H
#include <QtCharts/QChartGlobal>
+#include <QtCharts/QLegend>
#include <QGraphicsObject>
#include <QtGui/QFont>
#include <QtGui/QBrush>
@@ -56,6 +57,12 @@ class LegendMarkerItem : public QGraphicsObject, public QGraphicsLayoutItem
Q_OBJECT
Q_INTERFACES(QGraphicsLayoutItem)
public:
+ enum ItemType {
+ TypeRect,
+ TypeLine,
+ TypeCircle
+ };
+
explicit LegendMarkerItem(QLegendMarkerPrivate *marker, QGraphicsObject *parent = nullptr);
~LegendMarkerItem();
@@ -65,6 +72,9 @@ public:
void setBrush(const QBrush &brush);
QBrush brush() const;
+ void setSeriesPen(const QPen &pen);
+ void setSeriesBrush(const QBrush &brush);
+
void setFont(const QFont &font);
QFont font() const;
@@ -87,25 +97,43 @@ public:
QString displayedLabel() const;
void setToolTip(const QString &tooltip);
+ QLegend::MarkerShape markerShape() const;
+ void setMarkerShape(QLegend::MarkerShape shape);
+
+ void updateMarkerShapeAndSize();
+ QLegend::MarkerShape effectiveMarkerShape() const;
+ qreal effectiveMarkerWidth() const;
+
+ ItemType itemType() const { return m_itemType; }
+
Q_SIGNALS:
void markerRectChanged();
protected:
+ void setItemBrushAndPen();
+ void setItemRect();
+ bool useMaxWidth() const;
+
QLegendMarkerPrivate *m_marker; // Knows
+ QRectF m_defaultMarkerRect;
QRectF m_markerRect;
QRectF m_boundingRect;
QGraphicsTextItem *m_textItem;
- QGraphicsRectItem *m_rectItem;
+ QGraphicsItem *m_markerItem;
qreal m_margin;
qreal m_space;
QString m_label;
+ QLegend::MarkerShape m_markerShape;
QBrush m_labelBrush;
QPen m_pen;
QBrush m_brush;
+ QPen m_seriesPen;
+ QBrush m_seriesBrush;
+ QFont m_font;
bool m_hovering;
- QPointF m_pressPos;
+ ItemType m_itemType;
friend class QLegendMarker;
friend class QLegendMarkerPrivate;
diff --git a/src/charts/legend/qlegend.cpp b/src/charts/legend/qlegend.cpp
index 4f75747c..716e0f06 100644
--- a/src/charts/legend/qlegend.cpp
+++ b/src/charts/legend/qlegend.cpp
@@ -171,6 +171,47 @@ QT_CHARTS_BEGIN_NAMESPACE
*/
/*!
+ \enum QLegend::MarkerShape
+
+ This enum describes the shape used when rendering legend marker items.
+
+ \value MarkerShapeDefault Default shape determined by QLegend is used for the marker.
+ This value is supported only for individual QLegendMarker items.
+ \value MarkerShapeRectangle Rectangular markers are used.
+ Marker size is determined by font size.
+ \value MarkerShapeCircle Circular markers are used.
+ Marker size is determined by font size.
+ \value MarkerShapeFromSeries The marker shape is determined by the series.
+ In case of a scatter series, the legend marker looks like a scatter dot and is the same
+ size as the dot. In case of a line or spline series, the legend marker looks like a small
+ segment of the line. For other series types, rectangular markers are shown.
+
+ \sa markerShape
+*/
+
+/*!
+ \qmlproperty enumeration Legend::markerShape
+ \since 5.9
+
+ The default shape of the legend markers.
+ The default value is \c{MarkerShapeRectangle}.
+
+ \value Legend.MarkerShapeRectangle Legend markers are rectangular
+ \value Legend.MarkerShapeCircle Legend markers are circular
+ \value Legend.MarkerShapeFromSeries Legend marker shape is determined by the series
+
+ \sa QLegend::MarkerShape
+*/
+
+/*!
+ \property QLegend::markerShape
+ \since 5.9
+
+ The default shape of the legend markers.
+ The default value is \c{MarkerShapeRectangle}.
+*/
+
+/*!
\qmlproperty bool Legend::showToolTips
Whether tooltips are shown when the text is truncated. This is false by default.
This currently has no effect as there is no support for tooltips in QML.
@@ -497,6 +538,23 @@ void QLegend::setShowToolTips(bool show)
}
}
+QLegend::MarkerShape QLegend::markerShape() const
+{
+ return d_ptr->m_markerShape;
+}
+
+void QLegend::setMarkerShape(QLegend::MarkerShape shape)
+{
+ QLegend::MarkerShape newShape = shape;
+ if (newShape == MarkerShapeDefault)
+ newShape = MarkerShapeRectangle;
+ if (d_ptr->m_markerShape != newShape) {
+ d_ptr->m_markerShape = newShape;
+ layout()->invalidate();
+ emit markerShapeChanged(newShape);
+ }
+}
+
/*!
\internal \a event see QGraphicsWidget for details
*/
@@ -533,7 +591,8 @@ QLegendPrivate::QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend
m_attachedToChart(true),
m_backgroundVisible(false),
m_reverseMarkers(false),
- m_showToolTips(false)
+ m_showToolTips(false),
+ m_markerShape(QLegend::MarkerShapeRectangle)
{
m_items->setHandlesChildEvents(false);
}
@@ -575,6 +634,17 @@ QList<QLegendMarker*> QLegendPrivate::markers(QAbstractSeries *series)
return markers;
}
+qreal QLegendPrivate::maxMarkerWidth() const
+{
+ qreal maxWidth = 0.0;
+ for (int i = 0; i < m_markers.size(); i++) {
+ LegendMarkerItem *item = m_markers.at(i)->d_ptr->item();
+ if (item)
+ maxWidth = qMax(item->markerRect().width(), maxWidth);
+ }
+ return maxWidth;
+}
+
void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series)
{
if (m_series.contains(series)) {
diff --git a/src/charts/legend/qlegend.h b/src/charts/legend/qlegend.h
index cafbefba..fa3a8258 100644
--- a/src/charts/legend/qlegend.h
+++ b/src/charts/legend/qlegend.h
@@ -53,11 +53,20 @@ class QT_CHARTS_EXPORT QLegend : public QGraphicsWidget
Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor NOTIFY labelColorChanged)
Q_PROPERTY(bool reverseMarkers READ reverseMarkers WRITE setReverseMarkers NOTIFY reverseMarkersChanged)
Q_PROPERTY(bool showToolTips READ showToolTips WRITE setShowToolTips NOTIFY showToolTipsChanged)
+ Q_PROPERTY(MarkerShape markerShape READ markerShape WRITE setMarkerShape NOTIFY markerShapeChanged)
private:
explicit QLegend(QChart *chart);
public:
+ enum MarkerShape {
+ MarkerShapeDefault,
+ MarkerShapeRectangle,
+ MarkerShapeCircle,
+ MarkerShapeFromSeries
+ };
+ Q_ENUMS(MarkerShape)
+
~QLegend();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR);
@@ -97,6 +106,10 @@ public:
bool showToolTips() const;
void setShowToolTips(bool show);
+
+ MarkerShape markerShape() const;
+ void setMarkerShape(MarkerShape shape);
+
protected:
void hideEvent(QHideEvent *event);
void showEvent(QShowEvent *event);
@@ -109,6 +122,7 @@ Q_SIGNALS:
void labelColorChanged(QColor color);
void reverseMarkersChanged(bool reverseMarkers);
void showToolTipsChanged(bool showToolTips);
+ void markerShapeChanged(MarkerShape shape);
private:
QScopedPointer<QLegendPrivate> d_ptr;
diff --git a/src/charts/legend/qlegend_p.h b/src/charts/legend/qlegend_p.h
index 7806015e..83dd0c0b 100644
--- a/src/charts/legend/qlegend_p.h
+++ b/src/charts/legend/qlegend_p.h
@@ -63,6 +63,7 @@ public:
QGraphicsItemGroup* items() { return m_items; }
QList<QLegendMarker*> markers(QAbstractSeries *series = 0);
+ qreal maxMarkerWidth() const;
public Q_SLOTS:
void handleSeriesAdded(QAbstractSeries *series);
@@ -94,6 +95,7 @@ private:
bool m_backgroundVisible;
bool m_reverseMarkers;
bool m_showToolTips;
+ QLegend::MarkerShape m_markerShape;
QList<QLegendMarker *> m_markers;
QList<QAbstractSeries *> m_series;
diff --git a/src/charts/legend/qlegendmarker.cpp b/src/charts/legend/qlegendmarker.cpp
index b9da4852..6ec29cd9 100644
--- a/src/charts/legend/qlegendmarker.cpp
+++ b/src/charts/legend/qlegendmarker.cpp
@@ -148,6 +148,12 @@ QT_CHARTS_BEGIN_NAMESPACE
Visibility of the legend marker. Affects label and the colored square.
*/
+/*!
+ \property QLegendMarker::shape
+
+ The shape of the legend marker. Defaults to QLegend::MarkerShapeDefault, which indicates
+ the shape is determined by QLegend::markerShape property.
+*/
/*!
\internal
@@ -276,6 +282,20 @@ void QLegendMarker::setVisible(bool visible)
d_ptr->m_item->setVisible(visible);
}
+QLegend::MarkerShape QLegendMarker::shape() const
+{
+ return d_ptr->m_item->markerShape();
+}
+
+void QLegendMarker::setShape(QLegend::MarkerShape shape)
+{
+ if (shape != d_ptr->m_item->markerShape()) {
+ d_ptr->m_item->setMarkerShape(shape);
+ d_ptr->handleShapeChange();
+ emit shapeChanged();
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QLegendMarkerPrivate::QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend) :
m_legend(legend),
@@ -285,6 +305,9 @@ QLegendMarkerPrivate::QLegendMarkerPrivate(QLegendMarker *q, QLegend *legend) :
q_ptr(q)
{
m_item = new LegendMarkerItem(this);
+
+ connect(legend, &QLegend::markerShapeChanged, this,
+ &QLegendMarkerPrivate::handleShapeChange);
}
QLegendMarkerPrivate::~QLegendMarkerPrivate()
@@ -294,6 +317,21 @@ QLegendMarkerPrivate::~QLegendMarkerPrivate()
void QLegendMarkerPrivate::invalidateLegend()
{
+ m_item->updateGeometry();
+ m_legend->d_ptr->m_layout->invalidate();
+}
+
+void QLegendMarkerPrivate::invalidateAllItems()
+{
+ QList<QLegendMarker *> markers = m_legend->markers();
+ for (int i = 0; i < markers.size(); i++)
+ markers.at(i)->d_ptr->m_item->updateGeometry();
+ m_legend->d_ptr->m_layout->invalidate();
+}
+
+void QLegendMarkerPrivate::handleShapeChange()
+{
+ m_item->updateMarkerShapeAndSize();
m_legend->d_ptr->m_layout->invalidate();
}
diff --git a/src/charts/legend/qlegendmarker.h b/src/charts/legend/qlegendmarker.h
index 86721440..72ad384c 100644
--- a/src/charts/legend/qlegendmarker.h
+++ b/src/charts/legend/qlegendmarker.h
@@ -31,6 +31,7 @@
#define QLEGENDMARKER_H
#include <QtCharts/QChartGlobal>
+#include <QtCharts/QLegend>
#include <QtCore/QObject>
#include <QtGui/QPen>
#include <QtGui/QBrush>
@@ -62,6 +63,7 @@ public:
Q_PROPERTY(QPen pen READ pen WRITE setPen NOTIFY penChanged)
Q_PROPERTY(QBrush brush READ brush WRITE setBrush NOTIFY brushChanged)
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged)
+ Q_PROPERTY(QLegend::MarkerShape shape READ shape WRITE setShape NOTIFY shapeChanged)
Q_ENUMS(LegendMarkerType)
public:
@@ -86,6 +88,9 @@ public:
bool isVisible() const;
void setVisible(bool visible);
+ QLegend::MarkerShape shape() const;
+ void setShape(QLegend::MarkerShape shape);
+
virtual QAbstractSeries* series() = 0;
Q_SIGNALS:
@@ -97,6 +102,7 @@ Q_SIGNALS:
void penChanged();
void brushChanged();
void visibleChanged();
+ void shapeChanged();
protected:
explicit QLegendMarker(QLegendMarkerPrivate &d, QObject *parent = Q_NULLPTR);
diff --git a/src/charts/legend/qlegendmarker_p.h b/src/charts/legend/qlegendmarker_p.h
index 7a97623d..00d24542 100644
--- a/src/charts/legend/qlegendmarker_p.h
+++ b/src/charts/legend/qlegendmarker_p.h
@@ -67,9 +67,11 @@ public:
virtual QObject* relatedObject() = 0;
void invalidateLegend();
+ void invalidateAllItems();
public Q_SLOTS:
virtual void updated() = 0;
+ void handleShapeChange();
protected:
LegendMarkerItem *m_item;
diff --git a/src/charts/legend/qxylegendmarker.cpp b/src/charts/legend/qxylegendmarker.cpp
index 95ef533c..3ade52e9 100644
--- a/src/charts/legend/qxylegendmarker.cpp
+++ b/src/charts/legend/qxylegendmarker.cpp
@@ -31,6 +31,7 @@
#include <private/qxylegendmarker_p.h>
#include <private/qxyseries_p.h>
#include <QtCharts/QXYSeries>
+#include <QtCharts/QScatterSeries>
QT_CHARTS_BEGIN_NAMESPACE
@@ -122,6 +123,18 @@ void QXYLegendMarkerPrivate::updated()
m_item->setBrush(m_series->brush());
brushChanged = true;
}
+ if (m_item->effectiveMarkerShape() == QLegend::MarkerShapeFromSeries) {
+ QScatterSeries *scatter = static_cast<QScatterSeries *>(m_series);
+ if (scatter) {
+ const bool shapeChangeNeeded =
+ (scatter->markerShape() == QScatterSeries::MarkerShapeCircle
+ && m_item->itemType() != LegendMarkerItem::TypeCircle)
+ || (scatter->markerShape() == QScatterSeries::MarkerShapeRectangle
+ && m_item->itemType() != LegendMarkerItem::TypeRect);
+ if (shapeChangeNeeded || scatter->markerSize() != m_item->markerRect().width())
+ m_item->updateMarkerShapeAndSize();
+ }
+ }
} else {
QBrush emptyBrush;
if (!m_customBrush
@@ -131,6 +144,9 @@ void QXYLegendMarkerPrivate::updated()
brushChanged = true;
}
}
+ m_item->setSeriesBrush(m_series->brush());
+ m_item->setSeriesPen(m_series->pen());
+
invalidateLegend();
if (labelChanged)
diff --git a/tests/manual/qmlchartproperties/qml/qmlchartproperties/ChartEditorLegend.qml b/tests/manual/qmlchartproperties/qml/qmlchartproperties/ChartEditorLegend.qml
index 81bc82dd..534127b2 100644
--- a/tests/manual/qmlchartproperties/qml/qmlchartproperties/ChartEditorLegend.qml
+++ b/tests/manual/qmlchartproperties/qml/qmlchartproperties/ChartEditorLegend.qml
@@ -28,6 +28,7 @@
****************************************************************************/
import QtQuick 2.0
+import QtCharts 2.2
Row {
anchors.fill: parent
@@ -78,6 +79,17 @@ Row {
text: "legend use reverse order"
onClicked: chartLegend.reverseMarkers = !chartLegend.reverseMarkers;
}
+ Button {
+ text: "legend marker shape"
+ onClicked: {
+ if (chartLegend.markerShape === Legend.MarkerShapeRectangle)
+ chartLegend.markerShape = Legend.MarkerShapeCircle
+ else if (chartLegend.markerShape === Legend.MarkerShapeCircle)
+ chartLegend.markerShape = Legend.MarkerShapeFromSeries
+ else
+ chartLegend.markerShape = Legend.MarkerShapeRectangle
+ }
+ }
}
FontEditor {