Skip to content

Commit

Permalink
Merge pull request #457 from highperformancecoder/legend-placement
Browse files Browse the repository at this point in the history
Assorted improvements to plots suggested by Blair Fix on Ravel #481.
  • Loading branch information
highperformancecoder committed Mar 25, 2024
2 parents 30d1e4e + 7d9d448 commit cc365f0
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 54 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ endif
ifneq ($(MAKECMDGOALS),clean)
# make sure EcoLab is built first, even before starting to include Makefiles
build_ecolab:=$(shell cd ecolab; if $(MAKE) $(MAKEOVERRIDES) $(JOBS) all-without-models >build.log 2>&1; then echo "ecolab built"; fi)

$(warning $(build_ecolab))
ifneq ($(build_ecolab),ecolab built)
$(error "Making ecolab failed: check ecolab/build.log")
Expand Down
2 changes: 1 addition & 1 deletion ecolab
Submodule ecolab updated 3 files
+5 −0 include/Makefile
+8 −5 include/plot.h
+50 −47 src/plot.cc
1 change: 0 additions & 1 deletion gui-js/libs/shared/src/lib/backend/minsky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,6 @@ export class PlotWidget extends Item {
async legendLeft(...args: number[]): Promise<number> {return this.$callMethod('legendLeft',...args);}
async legendOffset(...args: number[]): Promise<number> {return this.$callMethod('legendOffset',...args);}
async legendSide(...args: string[]): Promise<string> {return this.$callMethod('legendSide',...args);}
async legendSize(a1: number,a2: number,a3: number): Promise<void> {return this.$callMethod('legendSize',a1,a2,a3);}
async legendTop(...args: number[]): Promise<number> {return this.$callMethod('legendTop',...args);}
async lh(a1: number,a2: number): Promise<number> {return this.$callMethod('lh',a1,a2);}
async logx(...args: boolean[]): Promise<boolean> {return this.$callMethod('logx',...args);}
Expand Down
90 changes: 45 additions & 45 deletions model/plotWidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace minsky
const float boundY[PlotWidget::nBoundsPorts]={0.49,0.49,0.47,-0.49, 0.47, -0.49};

// height of title, as a fraction of overall widget height
const double titleHeight=0.07;
const double titleHeight=0.05;

}

Expand Down Expand Up @@ -92,9 +92,11 @@ namespace minsky

void PlotWidget::draw(cairo_t* cairo) const
{
CairoSave cs(cairo);
const double z=Item::zoomFactor();
const double w=iWidth()*z;
double h=iHeight()*z;
cairo_scale(cairo,z,z);
const double w=iWidth();
double h=iHeight();

// if any titling, draw an extra bounding box (ticket #285)
if (!title.empty()||!xlabel().empty()||!ylabel().empty()||!y1label().empty())
Expand All @@ -104,9 +106,9 @@ namespace minsky
cairo_stroke(cairo);
}

CairoSave cs(cairo);
cairo_translate(cairo,-0.5*w,-0.5*h);

yoffs=0;
if (!title.empty())
{
const CairoSave cs(cairo);
Expand All @@ -116,12 +118,11 @@ namespace minsky
pango.setFontSize(fabs(fy));
pango.setMarkup(latexToPango(title));
cairo_set_source_rgb(cairo,0,0,0);
cairo_move_to(cairo,0.5*(w-z*pango.width()), 0);
cairo_scale(cairo,z,z);
cairo_move_to(cairo,0.5*(w-pango.width()), 0);
pango.show();

// allow some room for the title
yoffs=pango.height()*z;
yoffs=pango.height();
h-=yoffs;
}

Expand All @@ -135,7 +136,7 @@ namespace minsky
{
const float x=boundX[i]*w, y=boundY[i]*h;
if (!justDataChanged)
m_ports[i]->moveTo(x + this->x(), y + this->y()+0.5*yoffs);
m_ports[i]->moveTo(x*z + this->x(), y*z + this->y()+0.5*yoffs);
drawTriangle(cairo, x+0.5*w, y+0.5*h+yoffs, palette[(i/2)%palette.size()].colour, orient[i]);

}
Expand All @@ -145,7 +146,7 @@ namespace minsky
{
const float y=0.5*(dy-h) + (i-nBoundsPorts)*dy;
if (!justDataChanged)
m_ports[i]->moveTo(x + this->x(), y + this->y()+0.5*yoffs);
m_ports[i]->moveTo(x*z + this->x(), y*z + this->y()+0.5*yoffs);
drawTriangle(cairo, x+0.5*w, y+0.5*h+yoffs, palette[(i-nBoundsPorts)%palette.size()].colour, 0);
}

Expand All @@ -154,7 +155,7 @@ namespace minsky
{
const float y=0.5*(dy-h) + (i-m_numLines-nBoundsPorts)*dy, x=0.5*w;
if (!justDataChanged)
m_ports[i]->moveTo(x + this->x(), y + this->y()+0.5*yoffs);
m_ports[i]->moveTo(x*z + this->x(), y*z + this->y()+0.5*yoffs);
drawTriangle(cairo, x+0.5*w, y+0.5*h+yoffs, palette[(i-nBoundsPorts)%palette.size()].colour, M_PI);
}

Expand All @@ -163,21 +164,43 @@ namespace minsky
{
const float x=dx-0.5*w + (i-2*m_numLines-nBoundsPorts)*dx;
if (!justDataChanged)
m_ports[i]->moveTo(x + this->x(), y + this->y()+0.5*yoffs);
m_ports[i]->moveTo(x*z + this->x(), y*z + this->y()+0.5*yoffs);
drawTriangle(cairo, x+0.5*w, y+0.5*h+yoffs, palette[(i-2*m_numLines-nBoundsPorts)%palette.size()].colour, -0.5*M_PI);
}

cairo_translate(cairo, portSpace, yoffs);
cairo_set_line_width(cairo,1);
double gw=w-2*portSpace, gh=h-portSpace;
gw/=z; gh/=z; // undo zoomFactor for Plot::draw, and scale
cairo_scale(cairo,z,z);
//TODO Urgh - fix up the const_casts here. Maybe pass plotType as parameter to draw
auto& pt=const_cast<Plot*>(static_cast<const Plot*>(this))->plotType;
if (plotType!=automatic)
pt=static_cast<Plot::PlotType>(plotType);

Plot::draw(cairo,gw,gh);
Plot::draw(cairo,gw,gh);
if (mouseFocus && legend)
{
double width,height,x,y;
legendSize(x,y,width,height,gw,gh);
// following code puts x,y at centre point of legend
x+=0.5*width;
const double arrowLength=6;
y=(h-portSpace)-y+0.5*height;
cairo_move_to(cairo,x-arrowLength,y);
cairo_rel_line_to(cairo,2*arrowLength,0);
cairo_move_to(cairo,x,y-arrowLength);
cairo_rel_line_to(cairo,0,2*arrowLength);

cairo_move_to(cairo,x,y+0.5*height);
cairo_rel_line_to(cairo,0,arrowLength);
cairo_stroke(cairo);
drawTriangle(cairo,x-arrowLength,y,{0,0,0,1},M_PI);
drawTriangle(cairo,x+arrowLength,y,{0,0,0,1},0);
drawTriangle(cairo,x,y-arrowLength,{0,0,0,1},3*M_PI/2);
drawTriangle(cairo,x,y+arrowLength,{0,0,0,1},M_PI/2);
drawTriangle(cairo,x,y+0.5*height+arrowLength,{0,0,0,1},M_PI/2);

cairo_rectangle(cairo,x-0.5*width,y-0.5*height,width,height);
}
cs.restore();
if (mouseFocus)
{
Expand All @@ -186,30 +209,6 @@ namespace minsky
// draw legend tags for move/resize
if (legend)
{
double width,height;
legendSize(width,height,gh);
width+=legendOffset*gw;


const double x=legendLeft*gw-0.5*(w-width)+portSpace;
double y=-legendTop*gh+0.5*(h+height)-portSpace;
if (!title.empty()) y=-legendTop*gh+0.5*(h+height)-portSpace+titleHeight*h; // take into account room for the title
const double arrowLength=6;
cairo_move_to(cairo,x-arrowLength,y);
cairo_rel_line_to(cairo,2*arrowLength,0);
cairo_move_to(cairo,x,y-arrowLength);
cairo_rel_line_to(cairo,0,2*arrowLength);

cairo_move_to(cairo,x,y+0.5*height);
cairo_rel_line_to(cairo,0,arrowLength);
cairo_stroke(cairo);
drawTriangle(cairo,x-arrowLength,y,{0,0,0,1},M_PI);
drawTriangle(cairo,x+arrowLength,y,{0,0,0,1},0);
drawTriangle(cairo,x,y-arrowLength,{0,0,0,1},3*M_PI/2);
drawTriangle(cairo,x,y+arrowLength,{0,0,0,1},M_PI/2);
drawTriangle(cairo,x,y+0.5*height+arrowLength,{0,0,0,1},M_PI/2);

cairo_rectangle(cairo,x-0.5*width,y-0.5*height,width,height);
}
// Resize handles always visible on mousefocus. For ticket 92.
drawResizeHandles(cairo);
Expand Down Expand Up @@ -341,7 +340,7 @@ namespace minsky
const double dx=x-this->x()+0.5*iWidth()*z-portSpace;
const double dy=this->y()-y+0.5*iHeight()*z-portSpace;
const double gw=iWidth()*z-2*portSpace;
const double gh=iHeight()*z-portSpace-yoffs;
const double gh=iHeight()*z-portSpace-yoffs*z;
const double loffx=lh(gw,gh)*!Plot::ylabel.empty(), loffy=lh(gw,gh)*!Plot::xlabel.empty();
return Plot::mouseMove((dx-loffx)/gw, (dy-loffy)/gh, 10.0/std::max(gw,gh),formatter);
}
Expand Down Expand Up @@ -395,15 +394,16 @@ namespace minsky
return ClickType::onPort;
}

double legendWidth, legendHeight;
legendSize(legendWidth, legendHeight, iHeight()*z-portSpace);
const double xx= x-this->x() - portSpace +(0.5-legendLeft)*iWidth()*z;
const double yy= y-this->y() + (legendTop-0.5)*iHeight()*z;
double legendWidth, legendHeight, lx, ly;
legendSize(lx, ly, legendWidth, legendHeight, z*(iWidth()-2*portSpace), z*(iHeight()-portSpace-yoffs));
// xx & yy are in plot user coordinates
const double xx= x-this->x() + z*(0.5*iWidth()-portSpace) - lx;
const double yy= z*(0.5*iHeight()-portSpace)-y+this->y() - ly+legendHeight;
if (legend && xx>0 && xx<legendWidth)
{
if (yy>0 && yy<0.8*legendHeight)
if (yy>0.2*legendHeight && yy<legendHeight)
return ClickType::legendMove;
if (yy>=0.8*legendHeight && yy<legendHeight+6*z) // allow a bit of extra height for resize arrow
if (yy>-6*z && yy<=0.2*legendHeight) // allow a bit of extra height for resize arrow
return ClickType::legendResize;
}

Expand Down
14 changes: 7 additions & 7 deletions test/testPlotWidget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ namespace minsky
addPt(1,0.0,1.0);
labelPen(0,"hello");
labelPen(1,"hello");
double legendWidth, legendHeight;
legendSize(legendWidth, legendHeight, iHeight()-10);
double xoffs, yoffs, legendWidth, legendHeight;
legendSize(xoffs, yoffs, legendWidth, legendHeight, iWidth(), iHeight()-10);
double x=(legendLeft-0.5)*iWidth() +0.5*legendWidth;
double y=(0.5-legendTop)*iHeight() + 0.5*legendHeight;
CHECK_EQUAL(ClickType::legendMove, clickType(x,y));
Expand All @@ -49,7 +49,7 @@ namespace minsky
CHECK_CLOSE(oldLegendTop-20/(iHeight()-10),legendTop,0.01);
// legend should not change size
double newLegendWidth, newLegendHeight;
legendSize(newLegendWidth, newLegendHeight, iHeight()-10);
legendSize(xoffs, yoffs, newLegendWidth, newLegendHeight, iWidth(), iHeight()-10);
CHECK_CLOSE(legendWidth,newLegendWidth, 0.01);
CHECK_CLOSE(legendHeight,newLegendHeight,0.01);
}
Expand All @@ -63,8 +63,8 @@ namespace minsky
addPt(1,0.0,1.0);
labelPen(0,"hello");
labelPen(1,"hello");
double legendWidth, legendHeight;
legendSize(legendWidth, legendHeight, iHeight()-10);
double xoffs, yoffs, legendWidth, legendHeight;
legendSize(xoffs, yoffs, legendWidth, legendHeight, iWidth(), iHeight()-10);
double x=(legendLeft-0.5)*iWidth() +0.5*legendWidth;
double y=(0.5-legendTop)*iHeight() + 0.95*legendHeight;
CHECK_EQUAL(ClickType::legendResize, clickType(x,y));
Expand All @@ -75,8 +75,8 @@ namespace minsky
CHECK_CLOSE(oldLegendLeft,legendLeft, 0.01);
CHECK_CLOSE(oldLegendTop,legendTop,0.01);
double newLegendWidth, newLegendHeight;
legendSize(newLegendWidth, newLegendHeight, iHeight()-10);
// width change will be proportionate - just check the new heigh is about right
legendSize(xoffs, yoffs, newLegendWidth, newLegendHeight, iWidth(), iHeight()-10);
// width change will be proportionate - just check the new height is about right
CHECK_CLOSE(legendHeight+20,newLegendHeight,2);
}
}
Expand Down

0 comments on commit cc365f0

Please sign in to comment.