update: allow to style median-line of boxplots independently

This commit is contained in:
jkriege2 2019-05-05 19:58:52 +02:00
parent 67d23150f2
commit c873041d93
6 changed files with 236 additions and 34 deletions

View File

@ -49,8 +49,14 @@ You can further style the plot by e.g. setting:
graph->setFillColor(graphh->getColor().lighter()); graph->setFillColor(graphh->getColor().lighter());
// 4.2 make whiskers dashed // 4.2 make whiskers dashed
graph->setWhiskerLineStyle(Qt::DashLine); graph->setWhiskerLineStyle(Qt::DashLine);
graph->setWhiskerLineColor(graph->getLineColor().darker());
// 4.3 change mean symbol // 4.3 change mean symbol
graph->setSymbolType(JKQTPstar); graph->setSymbolType(JKQTPFilledStar);
graph->setSymbolFillColor(QColor("silver"));
// 4.4 change median line color
graph->setMedianLineColor(QColor("darkgreen"));
// 4.5 change box width to 75% of distance
graph->setBoxWidth(0.75);
``` ```
The result looks like this: The result looks like this:

View File

@ -84,9 +84,14 @@ int main(int argc, char* argv[])
graphh->setFillColor(graphh->getLineColor().lighter()); graphh->setFillColor(graphh->getLineColor().lighter());
// 6.2 make whiskers dashed // 6.2 make whiskers dashed
graphh->setWhiskerLineStyle(Qt::DashLine); graphh->setWhiskerLineStyle(Qt::DashLine);
graphh->setWhiskerLineColor(graphh->getLineColor().darker());
// 6.3 change mean symbol // 6.3 change mean symbol
graphh->setSymbolType(JKQTPstar); graphh->setSymbolType(JKQTPFilledStar);
graphh->setSymbolFillColor(QColor("silver"));
// 6.4 change median line color
graphh->setMedianLineColor(QColor("darkgreen"));
// 6.5 change box width to 75% of distance
graphh->setBoxWidth(0.75);
// 7. add the graphs to the plot, so it is actually displayed // 7. add the graphs to the plot, so it is actually displayed
plot.addGraph(graph); plot.addGraph(graph);

View File

@ -39,6 +39,8 @@ JKQTPGraphBoxplotStyleMixin::JKQTPGraphBoxplotStyleMixin()
m_whiskerLinePen=QPen(getLineColor(), getLineWidth()); m_whiskerLinePen=QPen(getLineColor(), getLineWidth());
whiskerLineWidth=getLineWidth(); whiskerLineWidth=getLineWidth();
m_medianLinePen=QPen(getLineColor(), getLineWidth());
medianLineWidth=getLineWidth();
} }
@ -53,9 +55,13 @@ void JKQTPGraphBoxplotStyleMixin::initBoxplotStyle(JKQTBasePlotter *parent, int
m_whiskerLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color()); m_whiskerLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
m_whiskerLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style()); m_whiskerLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
whiskerLineWidth=parent->getPlotStyle(parentPlotStyle).widthF(); whiskerLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
m_medianLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
m_medianLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
medianLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
} }
setWhiskerLineColor(getLineColor()); setWhiskerLineColor(getLineColor());
setMedianLineColor(getLineColor());
} }
void JKQTPGraphBoxplotStyleMixin::setBoxplotColor(QColor c, JKQTBasePlotter *parent) void JKQTPGraphBoxplotStyleMixin::setBoxplotColor(QColor c, JKQTBasePlotter *parent)
@ -67,6 +73,17 @@ void JKQTPGraphBoxplotStyleMixin::setBoxplotColor(QColor c, JKQTBasePlotter *par
setSymbolColor(c); setSymbolColor(c);
setSymbolFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c)); setSymbolFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
setWhiskerLineColor(getLineColor()); setWhiskerLineColor(getLineColor());
setMedianLineColor(getLineColor());
}
void JKQTPGraphBoxplotStyleMixin::setBoxWidth(double __value)
{
this->boxWidth = __value;
}
double JKQTPGraphBoxplotStyleMixin::getBoxWidth() const
{
return this->boxWidth;
} }
void JKQTPGraphBoxplotStyleMixin::setWhiskerLineStyle(Qt::PenStyle __value) void JKQTPGraphBoxplotStyleMixin::setWhiskerLineStyle(Qt::PenStyle __value)
@ -79,15 +96,6 @@ Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineStyle() const
return this->m_whiskerLinePen.style(); return this->m_whiskerLinePen.style();
} }
void JKQTPGraphBoxplotStyleMixin::setBoxWidth(double __value)
{
this->boxWidth = __value;
}
double JKQTPGraphBoxplotStyleMixin::getBoxWidth() const
{
return this->boxWidth;
}
void JKQTPGraphBoxplotStyleMixin::setWhiskerLineWidth(double __value) void JKQTPGraphBoxplotStyleMixin::setWhiskerLineWidth(double __value)
{ {
@ -172,6 +180,97 @@ QPen JKQTPGraphBoxplotStyleMixin::getWhiskerPen(JKQTPEnhancedPainter &painter, J
void JKQTPGraphBoxplotStyleMixin::setMedianLineStyle(Qt::PenStyle __value)
{
this->m_medianLinePen.setStyle(__value);
}
Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getMedianLineStyle() const
{
return this->m_medianLinePen.style();
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineWidth(double __value)
{
medianLineWidth=__value;
}
double JKQTPGraphBoxplotStyleMixin::getMedianLineWidth() const
{
return medianLineWidth;
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineColor(QColor __value)
{
m_medianLinePen.setColor(__value);
}
QColor JKQTPGraphBoxplotStyleMixin::getMedianLineColor() const
{
return m_medianLinePen.color();
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineDashOffset(qreal offset)
{
m_medianLinePen.setDashOffset(offset);
}
qreal JKQTPGraphBoxplotStyleMixin::getMedianLineDashOffset() const
{
return m_medianLinePen.dashOffset();
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineDashPattern(const QVector<qreal> &pattern)
{
m_medianLinePen.setDashPattern(pattern);
m_medianLinePen.setStyle(Qt::CustomDashLine);
}
QVector<qreal> JKQTPGraphBoxplotStyleMixin::getMedianLineDashPattern() const
{
return m_medianLinePen.dashPattern();
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineJoinStyle(Qt::PenJoinStyle style)
{
m_medianLinePen.setJoinStyle(style);
}
Qt::PenJoinStyle JKQTPGraphBoxplotStyleMixin::getMedianLineJoinStyle() const
{
return m_medianLinePen.joinStyle();
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineCapStyle(Qt::PenCapStyle style)
{
m_medianLinePen.setCapStyle(style);
}
Qt::PenCapStyle JKQTPGraphBoxplotStyleMixin::getMedianLineCapStyle() const
{
return m_medianLinePen.capStyle();
}
void JKQTPGraphBoxplotStyleMixin::setMedianLineBrush(const QBrush &style)
{
m_medianLinePen.setBrush(style);
}
QBrush JKQTPGraphBoxplotStyleMixin::getMedianLineBrush() const
{
return m_medianLinePen.brush();
}
QPen JKQTPGraphBoxplotStyleMixin::getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const
{
QPen pw=m_medianLinePen;
pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*medianLineWidth)));
pw.setJoinStyle(Qt::MiterJoin);
return pw;
}
@ -220,6 +319,7 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
@ -267,7 +367,7 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
const double medianv=datastore->get(medianColumn,static_cast<size_t>(i)); const double medianv=datastore->get(medianColumn,static_cast<size_t>(i));
const double meanv=datastore->get(meanColumn,static_cast<size_t>(i)); const double meanv=datastore->get(meanColumn,static_cast<size_t>(i));
QVector<QLineF> lines_p, lines_pw; QVector<QLineF> lines_p, lines_pw, lines_m;
//std::cout<<"(xv, yv) = ( "<<xv<<", "<<yv<<" )\n"; //std::cout<<"(xv, yv) = ( "<<xv<<", "<<yv<<" )\n";
if (posColumn>=0 && JKQTPIsOKFloat(xv) ) { if (posColumn>=0 && JKQTPIsOKFloat(xv) ) {
@ -324,16 +424,16 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
} }
if (minColumn>=0) { if (minColumn>=0) {
lines_p.append(QLineF(xmi4, min, xma4, min)); lines_pw.append(QLineF(xmi4, min, xma4, min));
lines_pw.append(QLineF(x, min, x, minstop)); lines_pw.append(QLineF(x, min, x, minstop));
} }
if (maxColumn>=0) { if (maxColumn>=0) {
lines_p.append(QLineF(xmi4, max, xma4, max)); lines_pw.append(QLineF(xmi4, max, xma4, max));
lines_pw.append(QLineF(x, max, x, maxstop)); lines_pw.append(QLineF(x, max, x, maxstop));
} }
if (percentile25Column>=0 && percentile75Column>=0) painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25))); if (percentile25Column>=0 && percentile75Column>=0) painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
if (medianColumn>=0) lines_p.append(QLineF(xmi+p.widthF()/2.0, median, xma-p.widthF()/2.0, median)); if (medianColumn>=0) lines_m.append(QLineF(xmi+p.widthF()/2.0, median, xma-p.widthF()/2.0, median));
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) {
plotStyledSymbol(parent, painter,x,mean); plotStyledSymbol(parent, painter,x,mean);
} }
@ -343,7 +443,9 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
if (lines_p.size()>0) painter.drawLines(lines_p); if (lines_p.size()>0) painter.drawLines(lines_p);
painter.setPen(pw); painter.setPen(pw);
if (lines_pw.size()>0) painter.drawLines(lines_pw); if (lines_pw.size()>0) painter.drawLines(lines_pw);
painter.setPen(pm);
if (lines_m.size()>0) painter.drawLines(lines_m);
// add hit-test graph points // add hit-test graph points
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) {
@ -608,11 +710,13 @@ void JKQTPBoxplotVerticalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRe
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
p.setWidthF(qMin(1.0, p.widthF())); p.setWidthF(qMin(1.0, p.widthF()));
pw.setWidthF(qMin(1.0, pw.widthF())); pw.setWidthF(qMin(1.0, pw.widthF()));
pm.setWidthF(qMin(1.0, pm.widthF()));
double x=rect.left()+rect.width()/2.0; double x=rect.left()+rect.width()/2.0;
double xma=x+rect.width()/2.5; double xma=x+rect.width()/2.5;
@ -631,10 +735,11 @@ void JKQTPBoxplotVerticalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRe
painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25))); painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
} }
painter.setPen(pm);
painter.drawLine(QLineF(xmi, median, xma, median)); painter.drawLine(QLineF(xmi, median, xma, median));
painter.setPen(pw);
painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max)); painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max));
painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min)); painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min));
painter.setPen(pw);
painter.drawLine(QLineF(x, max, x, p75)); painter.drawLine(QLineF(x, max, x, p75));
painter.drawLine(QLineF(x, min, x, p25)); painter.drawLine(QLineF(x, min, x, p25));
@ -656,10 +761,12 @@ void JKQTPBoxplotHorizontalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, Q
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
p.setWidthF(qMin(1.0, p.widthF())); p.setWidthF(qMin(1.0, p.widthF()));
pw.setWidthF(qMin(1.0, pw.widthF())); pw.setWidthF(qMin(1.0, pw.widthF()));
pm.setWidthF(qMin(1.0, pm.widthF()));
double y=rect.top()+rect.height()/2.0; double y=rect.top()+rect.height()/2.0;
@ -679,10 +786,11 @@ void JKQTPBoxplotHorizontalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, Q
painter.drawRect(QRectF(p75, ymi, fabs(p75-p25), fabs(yma-ymi))); painter.drawRect(QRectF(p75, ymi, fabs(p75-p25), fabs(yma-ymi)));
} }
painter.setPen(pm);
painter.drawLine(QLineF(median, ymi, median, yma)); painter.drawLine(QLineF(median, ymi, median, yma));
painter.setPen(pw);
painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0)); painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0));
painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0)); painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0));
painter.setPen(pw);
painter.drawLine(QLineF(max, y, p75, y)); painter.drawLine(QLineF(max, y, p75, y));
painter.drawLine(QLineF(min, y, p25, y)); painter.drawLine(QLineF(min, y, p25, y));
@ -802,6 +910,7 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
@ -847,7 +956,7 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
const double medianv=datastore->get(medianColumn,static_cast<size_t>(i)); const double medianv=datastore->get(medianColumn,static_cast<size_t>(i));
const double meanv=datastore->get(meanColumn,static_cast<size_t>(i)); const double meanv=datastore->get(meanColumn,static_cast<size_t>(i));
QVector<QLineF> lines_p, lines_pw; QVector<QLineF> lines_p, lines_pw, lines_m;
//std::cout<<"(xv, yv) = ( "<<xv<<", "<<yv<<" )\n"; //std::cout<<"(xv, yv) = ( "<<xv<<", "<<yv<<" )\n";
if (posColumn>=0 && JKQTPIsOKFloat(yv) ) { if (posColumn>=0 && JKQTPIsOKFloat(yv) ) {
@ -907,15 +1016,15 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
ymi4=transformY(yv-getBoxWidth()/4.0); ymi4=transformY(yv-getBoxWidth()/4.0);
} }
if (minColumn>=0) { if (minColumn>=0) {
lines_p.append(QLineF(min, ymi4, min, yma4)); lines_pw.append(QLineF(min, ymi4, min, yma4));
lines_pw.append(QLineF(min, y, minstop, y)); lines_pw.append(QLineF(min, y, minstop, y));
} }
if (maxColumn>=0) { if (maxColumn>=0) {
lines_p.append(QLineF(max, ymi4, max, yma4)); lines_pw.append(QLineF(max, ymi4, max, yma4));
lines_pw.append(QLineF(max, y, maxstop, y)); lines_pw.append(QLineF(max, y, maxstop, y));
} }
if (percentile25Column>=0 && percentile75Column>=0) painter.drawRect(QRectF(p25, qMin(yma,ymi), fabs(p75-p25), fabs(yma-ymi))); if (percentile25Column>=0 && percentile75Column>=0) painter.drawRect(QRectF(p25, qMin(yma,ymi), fabs(p75-p25), fabs(yma-ymi)));
if (medianColumn>=0) lines_p.append(QLineF(median, ymi-p.widthF()/2.0, median, yma+p.widthF()/2.0)); if (medianColumn>=0) lines_m.append(QLineF(median, ymi-p.widthF()/2.0, median, yma+p.widthF()/2.0));
if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) { if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) {
plotStyledSymbol(parent, painter, mean, y); plotStyledSymbol(parent, painter, mean, y);
@ -926,6 +1035,8 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
if (lines_p.size()>0) painter.drawLines(lines_p); if (lines_p.size()>0) painter.drawLines(lines_p);
painter.setPen(pw); painter.setPen(pw);
if (lines_pw.size()>0) painter.drawLines(lines_pw); if (lines_pw.size()>0) painter.drawLines(lines_pw);
painter.setPen(pm);
if (lines_m.size()>0) painter.drawLines(lines_m);
// add hit-test graph points // add hit-test graph points
@ -1028,6 +1139,7 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
@ -1089,6 +1201,7 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
} }
if (drawMedian && JKQTPIsOKFloat(medianv)) { if (drawMedian && JKQTPIsOKFloat(medianv)) {
painter.setPen(pm);
painter.drawLine(QLineF(xmi, median, xma, median)); painter.drawLine(QLineF(xmi, median, xma, median));
if (JKQTPIsOKFloat(medianv)) { if (JKQTPIsOKFloat(medianv)) {
QStringList sl=labelValues, sll=labelNames; QStringList sl=labelValues, sll=labelNames;
@ -1098,9 +1211,9 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
} }
} }
if (drawMinMax) { if (drawMinMax) {
painter.setPen(pw);
if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max)); if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max));
if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min)); if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min));
painter.setPen(pw);
if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(x, max, x, p75)); if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(x, max, x, p75));
if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(x, min, x, p25)); if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(x, min, x, p25));
if (JKQTPIsOKFloat(minv)) { if (JKQTPIsOKFloat(minv)) {
@ -1308,10 +1421,12 @@ void JKQTPBoxplotVerticalElement::drawKeyMarker(JKQTPEnhancedPainter& painter, Q
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
p.setWidthF(qMin(1.0, p.widthF())); p.setWidthF(qMin(1.0, p.widthF()));
pw.setWidthF(qMin(1.0, pw.widthF())); pw.setWidthF(qMin(1.0, pw.widthF()));
pm.setWidthF(qMin(1.0, pm.widthF()));
double x=rect.left()+rect.width()/2.0; double x=rect.left()+rect.width()/2.0;
@ -1331,10 +1446,11 @@ void JKQTPBoxplotVerticalElement::drawKeyMarker(JKQTPEnhancedPainter& painter, Q
painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25))); painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
} }
painter.setPen(pm);
painter.drawLine(QLineF(xmi, median, xma, median)); painter.drawLine(QLineF(xmi, median, xma, median));
painter.setPen(pw);
painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max)); painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max));
painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min)); painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min));
painter.setPen(pw);
painter.drawLine(QLineF(x, max, x, p75)); painter.drawLine(QLineF(x, max, x, p75));
painter.drawLine(QLineF(x, min, x, p25)); painter.drawLine(QLineF(x, min, x, p25));
@ -1351,10 +1467,12 @@ void JKQTPBoxplotHorizontalElement::drawKeyMarker(JKQTPEnhancedPainter& painter,
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
p.setWidthF(qMin(1.0, p.widthF())); p.setWidthF(qMin(1.0, p.widthF()));
pw.setWidthF(qMin(1.0, pw.widthF())); pw.setWidthF(qMin(1.0, pw.widthF()));
pm.setWidthF(qMin(1.0, pm.widthF()));
double y=rect.top()+rect.height()/2.0; double y=rect.top()+rect.height()/2.0;
double yma=y+rect.height()/2.5; double yma=y+rect.height()/2.5;
@ -1373,10 +1491,11 @@ void JKQTPBoxplotHorizontalElement::drawKeyMarker(JKQTPEnhancedPainter& painter,
painter.drawRect(QRectF(p75, ymi, fabs(p75-p25), fabs(yma-ymi))); painter.drawRect(QRectF(p75, ymi, fabs(p75-p25), fabs(yma-ymi)));
} }
painter.setPen(pm);
painter.drawLine(QLineF(median, ymi, median, yma)); painter.drawLine(QLineF(median, ymi, median, yma));
painter.setPen(pw);
painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0)); painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0));
painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0)); painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0));
painter.setPen(pw);
painter.drawLine(QLineF(max, y, p75, y)); painter.drawLine(QLineF(max, y, p75, y));
painter.drawLine(QLineF(min, y, p25, y)); painter.drawLine(QLineF(min, y, p25, y));
@ -1459,6 +1578,7 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
QPen p=getLinePenForRects(painter, parent); QPen p=getLinePenForRects(painter, parent);
QPen pw=getWhiskerPen(painter, parent); QPen pw=getWhiskerPen(painter, parent);
QPen pm=getMedianPen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
const double yv=pos; const double yv=pos;
@ -1517,6 +1637,7 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
} }
if (drawMedian && JKQTPIsOKFloat(medianv)) { if (drawMedian && JKQTPIsOKFloat(medianv)) {
painter.setPen(pm);
painter.drawLine(QLineF(median, ymi, median, yma)); painter.drawLine(QLineF(median, ymi, median, yma));
if (JKQTPIsOKFloat(medianv)) { if (JKQTPIsOKFloat(medianv)) {
QStringList sl=labelValues, sll=labelNames; QStringList sl=labelValues, sll=labelNames;
@ -1525,9 +1646,9 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
addHitTestData(medianv, yv, "\\ensuremath{\\begin{bmatrix}"+sll.join("\\\\")+"\\end{bmatrix}\\;=\\;\\begin{bmatrix}"+sl.join("\\\\")+"\\end{bmatrix}}"); addHitTestData(medianv, yv, "\\ensuremath{\\begin{bmatrix}"+sll.join("\\\\")+"\\end{bmatrix}\\;=\\;\\begin{bmatrix}"+sl.join("\\\\")+"\\end{bmatrix}}");
} } } }
if (drawMinMax) { if (drawMinMax) {
painter.setPen(pw);
if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0)); if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0));
if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0)); if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0));
painter.setPen(pw);
if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(max, y, p75, y)); if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(max, y, p75, y));
if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(min, y, p25, y)); if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(min, y, p25, y));
if (JKQTPIsOKFloat(minv)) { if (JKQTPIsOKFloat(minv)) {

View File

@ -47,13 +47,6 @@ class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMi
void initBoxplotStyle(JKQTBasePlotter* parent, int &parentPlotStyle); void initBoxplotStyle(JKQTBasePlotter* parent, int &parentPlotStyle);
/*! \brief set the line style of whisker lines */
void setWhiskerLineStyle(Qt::PenStyle __value);
/*! \brief get the line style of whisker lines */
Qt::PenStyle getWhiskerLineStyle() const;
/*! \copydoc boxWidth /*! \copydoc boxWidth
\see see boxWidth for details */ \see see boxWidth for details */
void setBoxWidth(double __value); void setBoxWidth(double __value);
@ -61,6 +54,13 @@ class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMi
\see see boxWidth for details */ \see see boxWidth for details */
double getBoxWidth() const; double getBoxWidth() const;
/*! \brief set the line style of whisker lines */
void setWhiskerLineStyle(Qt::PenStyle __value);
/*! \brief get the line style of whisker lines */
Qt::PenStyle getWhiskerLineStyle() const;
/*! \brief set the width [pt] of whisker lines */ /*! \brief set the width [pt] of whisker lines */
void setWhiskerLineWidth(double __value); void setWhiskerLineWidth(double __value);
/*! \brief get the width [pt] of whisker lines */ /*! \brief get the width [pt] of whisker lines */
@ -116,6 +116,72 @@ class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMi
/** \brief build a pen to be used for drawing whiskers */ /** \brief build a pen to be used for drawing whiskers */
QPen getWhiskerPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const; QPen getWhiskerPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
/*! \brief set the line style of median lines */
void setMedianLineStyle(Qt::PenStyle __value);
/*! \brief get the line style of median lines */
Qt::PenStyle getMedianLineStyle() const;
/*! \brief set the width [pt] of median lines */
void setMedianLineWidth(double __value);
/*! \brief get the width [pt] of median lines */
double getMedianLineWidth() const;
/*! \brief set the color of median lines */
void setMedianLineColor(QColor __value);
/*! \brief get the color of median lines */
QColor getMedianLineColor() const;
/** \brief sets the dash offset for a custom dash style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
*/
void setMedianLineDashOffset(qreal offset);
/** \brief returns the dash offset for a custom dash style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
*/
qreal getMedianLineDashOffset() const;
/** \brief sets the dash pattern for a custom dash style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
*/
void setMedianLineDashPattern(const QVector<qreal> &pattern);
/** \brief gets the dash pattern for a custom dash style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
*/
QVector<qreal> getMedianLineDashPattern() const;
/** \brief sets the join style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
*/
void setMedianLineJoinStyle(Qt::PenJoinStyle style);
/** \brief returns the join style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
*/
Qt::PenJoinStyle getMedianLineJoinStyle() const;
/** \brief sets the cap style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
*/
void setMedianLineCapStyle(Qt::PenCapStyle style);
/** \brief gets the cap style of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
*/
Qt::PenCapStyle getMedianLineCapStyle() const;
/** \brief sets the brush used to fill the line area of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setBrush
*/
void setMedianLineBrush(const QBrush& style);
/** \brief gets the brush used to fill the line area of median lines
* \see https://doc.qt.io/qt-5/qpen.html#setBrush
*/
QBrush getMedianLineBrush() const;
/** \brief build a pen to be used for drawing medians */
QPen getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
protected: protected:
/*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/ /*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/
void setBoxplotColor(QColor c, JKQTBasePlotter *parent); void setBoxplotColor(QColor c, JKQTBasePlotter *parent);
@ -124,6 +190,10 @@ class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMi
QPen m_whiskerLinePen; QPen m_whiskerLinePen;
/** \brief line width (in pt) of the whisker lines */ /** \brief line width (in pt) of the whisker lines */
double whiskerLineWidth; double whiskerLineWidth;
/** \brief line style of the median lines */
QPen m_medianLinePen;
/** \brief line width (in pt) of the median lines */
double medianLineWidth;
/** \brief width of box in percent of distance between the current two posColumn values /** \brief width of box in percent of distance between the current two posColumn values
* if we only plot one box&whiskers then this is the width in pt */ * if we only plot one box&whiskers then this is the width in pt */
double boxWidth; double boxWidth;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB