Skip to content

Commit e54c433

Browse files
Paint a translucent background box on xtick labels to make them stand out a bit more, and render the xticks on top of the graph data. For Ravel #568.
1 parent 840ec3c commit e54c433

File tree

1 file changed

+103
-84
lines changed

1 file changed

+103
-84
lines changed

src/plot.cc

Lines changed: 103 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ namespace
7676
cairo_scale(cairo,scalex,scaley);
7777
Pango::show();
7878
}
79+
// draw a translucent background to make the text "pop"
80+
void drawBackground() const {
81+
double x,y;
82+
cairo_get_current_point(cairo,&x,&y);
83+
{
84+
ecolab::cairo::CairoSave cs(cairo);
85+
cairo_set_source_rgba(cairo,1,1,1,0.4);
86+
cairo_translate(cairo,x,y);
87+
cairo_scale(cairo,scalex,scaley);
88+
cairo_rotate(cairo,angle);
89+
cairo_rectangle(cairo,0,0,width(),height());
90+
cairo_fill(cairo);
91+
}
92+
cairo_move_to(cairo,x,y);
93+
}
7994
};
8095

8196
// stroke the current path using the default linewidth
@@ -711,85 +726,6 @@ namespace ecolab
711726

712727

713728
XFY aff(logy, sy, displayLHSscale()? mm: mm1, 0); //manual affine transform - see ticket #693
714-
if (xticks.size())
715-
{
716-
unsigned startTick=0, endTick;
717-
for (startTick=0; startTick<xticks.size() && xticks[startTick].first < minx; startTick++);
718-
for (endTick=startTick; endTick<xticks.size() && xticks[endTick].first < maxx; endTick++);
719-
unsigned tickIncr=(endTick-startTick)/nxTicks+1;
720-
double xtick=0, incr=0;
721-
pango.angle=xtickAngle*M_PI/180.0;
722-
for (unsigned i=startTick; i<endTick; i+=tickIncr)
723-
{
724-
const std::pair<double,std::string>& xt=xticks[i];
725-
xtick=logx? log10(xt.first): xt.first;
726-
cairo_new_path(cairo);
727-
cairo_move_to(cairo,xtick,0);
728-
cairo_line_to(cairo,xtick,fontSz*h);
729-
stroke(cairo);
730-
cairo_move_to(cairo,xtick,fontSz*h*2);
731-
pango.setMarkup(xt.second);
732-
pango.show();
733-
if (grid)
734-
{
735-
if (i<xticks.size()-tickIncr)
736-
{
737-
double nextX=xticks[i+tickIncr].first;
738-
if (logx) nextX=log10(nextX);
739-
incr=fabs(nextX-xtick);
740-
}
741-
drawGrid(cairo, xtick, incr, true, aff);
742-
}
743-
}
744-
pango.angle=0;
745-
if (grid && incr) // extend grid all the way
746-
while ((xtick+=incr)<maxx)
747-
drawGrid(cairo, xtick, incr, true, aff);
748-
}
749-
else if (logx)
750-
{
751-
LogScale ls(minx, maxx, nxTicks);
752-
int i=0;
753-
for (double xtick=ls(0); xtick<maxx; i++, xtick=ls(i)) //NOLINT
754-
if (xtick>=minx)
755-
{
756-
pango.setMarkup(logAxisLabel(xtick));
757-
cairo_new_path(cairo);
758-
cairo_move_to(cairo,log10(xtick),0);
759-
cairo_line_to(cairo,log10(xtick),fontSz*h);
760-
stroke(cairo);
761-
cairo_move_to(cairo,log10(xtick),fontSz*h*2);
762-
pango.show();
763-
764-
if (grid)
765-
drawGrid(cairo, xtick, ls(i+1)-xtick, true, aff);
766-
}
767-
}
768-
else
769-
{
770-
double xtickIncrement, xtick;
771-
computeIncrementAndOffset(minx, maxx, nxTicks, xtickIncrement, xtick);
772-
if (xtickIncrement<0) return; //avoid infinite loop
773-
cairo_move_to(cairo, maxx-0.05*dx*(1+fontScale), aff(mm+0.04*dy*(1+fontScale)));
774-
showOrderOfMag(pango, xtickIncrement, exp_threshold);
775-
776-
for (; xtick<maxx; xtick+=xtickIncrement) //NOLINT
777-
if (xtick>=minx)
778-
{
779-
pango.setMarkup(axisLabel(xtick,xtickIncrement));
780-
781-
cairo_new_path(cairo);
782-
cairo_move_to(cairo,xtick,aff(mm));
783-
cairo_line_to(cairo,xtick,aff(mm)+fontSz*h);
784-
stroke(cairo);
785-
cairo_move_to(cairo,xtick,aff(mm)+fontSz*h*2);
786-
pango.show();
787-
788-
if (grid)
789-
drawGrid(cairo, xtick, xtickIncrement, true, aff);
790-
}
791-
}
792-
793729
double rightMargin=0.05*dx;
794730

795731
if (logy)
@@ -848,7 +784,7 @@ namespace ecolab
848784
if (aff(ytick)>=fontSz*h)
849785
{
850786
pango.setMarkup(axisLabel(ytick,ytickIncrement,percent));
851-
787+
852788
cairo_new_path(cairo);
853789
cairo_move_to(cairo,iflogx(minx),aff(ytick));
854790
cairo_line_to(cairo,iflogx(minx)+fontSz*dx,aff(ytick));
@@ -874,7 +810,7 @@ namespace ecolab
874810
if (ytick>=mm1+fontSz*dy1)
875811
{
876812
pango.setMarkup(axisLabel(ytick,ytickIncrement,percent));
877-
813+
878814
cairo_new_path(cairo);
879815
double yt=aff((ytick-mm1)*rhsScale+aff.o);
880816
cairo_move_to(cairo,maxx,yt);
@@ -911,11 +847,12 @@ namespace ecolab
911847
case line_scatter:
912848
if (x[i].size()>1)
913849
{
850+
cairo::CairoSave cs(cairo);
914851
cairo_set_source_rgba(cairo, ls.colour.r, ls.colour.g, ls.colour.b, ls.colour.a);
915852
cairo_set_line_width(cairo, ls.width);
916853
vector<double> dashPattern=ls.dashPattern();
917854
cairo_set_dash(cairo, dashPattern.data(), dashPattern.size(), 0);
918-
855+
919856
cairo_new_path(cairo);
920857
auto xfyyij=xfy(y[i][0]);
921858
if (isfinite(xfyyij))
@@ -942,7 +879,7 @@ namespace ecolab
942879
// make bars translucent - see Minsky ticket #893
943880
Colour barColour={ls.colour.r, ls.colour.g, ls.colour.b, 0.5*ls.colour.a};
944881
Colour shadow={0.4, 0.4, 0.6, 0.025};
945-
882+
946883
auto showBox=[&](double x, double y, double w, double h, Colour& c) {
947884
cairo_set_source_rgba(cairo, c.r, c.g, c.b, c.a);
948885
cairo_rectangle(cairo, x, y, w, h);
@@ -1018,6 +955,88 @@ namespace ecolab
1018955
}
1019956
}
1020957

958+
if (xticks.size())
959+
{
960+
unsigned startTick=0, endTick;
961+
for (startTick=0; startTick<xticks.size() && xticks[startTick].first < minx; startTick++);
962+
for (endTick=startTick; endTick<xticks.size() && xticks[endTick].first < maxx; endTick++);
963+
unsigned tickIncr=(endTick-startTick)/nxTicks+1;
964+
double xtick=0, incr=0;
965+
pango.angle=xtickAngle*M_PI/180.0;
966+
for (unsigned i=startTick; i<endTick; i+=tickIncr)
967+
{
968+
const std::pair<double,std::string>& xt=xticks[i];
969+
xtick=logx? log10(xt.first): xt.first;
970+
cairo_new_path(cairo);
971+
cairo_move_to(cairo,xtick,0);
972+
cairo_line_to(cairo,xtick,fontSz*h);
973+
stroke(cairo);
974+
cairo_move_to(cairo,xtick,fontSz*h*2);
975+
pango.setMarkup(xt.second);
976+
pango.drawBackground();
977+
pango.show();
978+
if (grid)
979+
{
980+
if (i<xticks.size()-tickIncr)
981+
{
982+
double nextX=xticks[i+tickIncr].first;
983+
if (logx) nextX=log10(nextX);
984+
incr=fabs(nextX-xtick);
985+
}
986+
drawGrid(cairo, xtick, incr, true, aff);
987+
}
988+
}
989+
pango.angle=0;
990+
if (grid && incr) // extend grid all the way
991+
while ((xtick+=incr)<maxx)
992+
drawGrid(cairo, xtick, incr, true, aff);
993+
}
994+
else if (logx)
995+
{
996+
LogScale ls(minx, maxx, nxTicks);
997+
int i=0;
998+
for (double xtick=ls(0); xtick<maxx; i++, xtick=ls(i)) //NOLINT
999+
if (xtick>=minx)
1000+
{
1001+
pango.setMarkup(logAxisLabel(xtick));
1002+
cairo_new_path(cairo);
1003+
cairo_move_to(cairo,log10(xtick),0);
1004+
cairo_line_to(cairo,log10(xtick),fontSz*h);
1005+
stroke(cairo);
1006+
cairo_move_to(cairo,log10(xtick),fontSz*h*2);
1007+
pango.drawBackground();
1008+
pango.show();
1009+
1010+
if (grid)
1011+
drawGrid(cairo, xtick, ls(i+1)-xtick, true, aff);
1012+
}
1013+
}
1014+
else
1015+
{
1016+
double xtickIncrement, xtick;
1017+
computeIncrementAndOffset(minx, maxx, nxTicks, xtickIncrement, xtick);
1018+
if (xtickIncrement<0) return; //avoid infinite loop
1019+
cairo_move_to(cairo, maxx-0.05*dx*(1+fontScale), aff(mm+0.04*dy*(1+fontScale)));
1020+
showOrderOfMag(pango, xtickIncrement, exp_threshold);
1021+
1022+
for (; xtick<maxx; xtick+=xtickIncrement) //NOLINT
1023+
if (xtick>=minx)
1024+
{
1025+
pango.setMarkup(axisLabel(xtick,xtickIncrement));
1026+
1027+
cairo_new_path(cairo);
1028+
cairo_move_to(cairo,xtick,aff(mm));
1029+
cairo_line_to(cairo,xtick,aff(mm)+fontSz*h);
1030+
stroke(cairo);
1031+
cairo_move_to(cairo,xtick,aff(mm)+fontSz*h*2);
1032+
pango.drawBackground();
1033+
pango.show();
1034+
1035+
if (grid)
1036+
drawGrid(cairo, xtick, xtickIncrement, true, aff);
1037+
}
1038+
}
1039+
10211040
// display value near mouse pointer
10221041
if (!valueString.empty())
10231042
{
@@ -1117,7 +1136,7 @@ namespace ecolab
11171136
cairo_set_line_width(cairo, ls.width);
11181137
vector<double> dashPattern=ls.dashPattern();
11191138
cairo_set_dash(cairo, dashPattern.data(), dashPattern.size(), 0);
1120-
1139+
11211140
// transform y coordinates (handles RHS being a different scale)
11221141
XFY xfy;
11231142
if (*pen<penSide.size() && penSide[*pen]==right)

0 commit comments

Comments
 (0)