in assets/js/railroad.js [796:891]
format(x,y,width) {
// Hook up the two sides if this is narrower than its stated width.
var gaps = determineGaps(width, this.width);
new Path(x,y).h(gaps[0]).addTo(this);
new Path(x+gaps[0]+this.width,y+this.height).h(gaps[1]).addTo(this);
x += gaps[0];
const first = this.items[0];
const last = this.items[this.items.length-1];
const allButFirst = this.items.slice(1);
const allButLast = this.items.slice(0, -1);
// upper track
var upperSpan = (sum(allButLast, x=>x.width+(x.needsSpace?20:0))
+ (this.items.length - 2) * Options.AR*2
- Options.AR
);
new Path(x,y)
.arc('se')
.v(-(this._upperTrack - Options.AR*2))
.arc('wn')
.h(upperSpan)
.addTo(this);
// lower track
var lowerSpan = (sum(allButFirst, x=>x.width+(x.needsSpace?20:0))
+ (this.items.length - 2) * Options.AR*2
+ (last.height > 0 ? Options.AR : 0)
- Options.AR
);
var lowerStart = x + Options.AR + first.width+(first.needsSpace?20:0) + Options.AR*2;
new Path(lowerStart, y+this._lowerTrack)
.h(lowerSpan)
.arc('se')
.v(-(this._lowerTrack - Options.AR*2))
.arc('wn')
.addTo(this);
// Items
for(const [i, item] of enumerate(this.items)) {
// input track
if(i === 0) {
new Path(x,y)
.h(Options.AR)
.addTo(this);
x += Options.AR;
} else {
new Path(x, y - this._upperTrack)
.arc('ne')
.v(this._upperTrack - Options.AR*2)
.arc('ws')
.addTo(this);
x += Options.AR*2;
}
// item
var itemWidth = item.width + (item.needsSpace?20:0);
item.format(x, y, itemWidth).addTo(this);
x += itemWidth;
// output track
if(i === this.items.length-1) {
if(item.height === 0) {
new Path(x,y)
.h(Options.AR)
.addTo(this);
} else {
new Path(x,y+item.height)
.arc('se')
.addTo(this);
}
} else if(i === 0 && item.height > this._lowerTrack) {
// Needs to arc up to meet the lower track, not down.
if(item.height - this._lowerTrack >= Options.AR*2) {
new Path(x, y+item.height)
.arc('se')
.v(this._lowerTrack - item.height + Options.AR*2)
.arc('wn')
.addTo(this);
} else {
// Not enough space to fit two arcs
// so just bail and draw a straight line for now.
new Path(x, y+item.height)
.l(Options.AR*2, this._lowerTrack - item.height)
.addTo(this);
}
} else {
new Path(x, y+item.height)
.arc('ne')
.v(this._lowerTrack - item.height - Options.AR*2)
.arc('ws')
.addTo(this);
}
}
return this;
}