MediaWiki:LeadingAndTrailingCells.js

From APL Wiki
Revision as of 15:34, 20 November 2019 by RichPark (talk | contribs) (6 revisions imported: Migrate from miraheze)
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
let div = (a,b) => Math.floor(a/b);

const sc = 0.7;
let svg = d3.select('.LeadingAndTrailingCells')
    .append('svg').attrs({height:820*sc, width:620*sc})
    .append('g')
    .attr('transform',`scale(${sc})`)
    .attr('font-size',46)
    .attr('text-anchor','middle');
let w = 60,
    h = 58,
    boxPad = 5,
    xp = 3;

let shape = [3,3,4],
    rank = shape.length,
    dat = [0,0,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,0,1,1,0,0,1,0,1,1,1,0];
function getPos(i) {
    let a = rank-1;
    let pos = [div(i,shape[a]), i%shape[a]]; a--;
    let y = pos[0];
    while (a--) { y=div(y,shape[a]); pos[0]+=y; }
    return {x:w*pos[1], y:h*pos[0]};
}

let Wo= w/2+10,
    W = (shape[rank-1]-1)*w,
    Wg= 180,
    H = (shape[0]*(1+shape[1])-1)*h;
let gs = svg.selectAll().data(['Trailing','Leading']).enter()
    .append('g').attr('transform',(_,i)=>`translate(${Wo+(W+Wg)*i},70)`);
gs.append('rect').attrs({x:-w/2,y:0,width:W+w,height:H,fill:'white'});
gs.append('text').text(t=>t).attrs({ x:W/2, y:-40, 'font-size':40, fill:'#6b6560' });
gs.attr('stroke-width',3);

let getColor = i => d3.hsl(d3.interpolateViridis(0.9-0.25*i));
function getColors(i) {
    let c = getColor(i); c.s+=0.2; c.l-=0.05;
    let f = d3.hsl(c); f.l=0.96;
    return {s:c,f:f};
}
function getRect(i,j,dim) {
    let t = boxPad*i,
        c = getColors(i),
        xp= 3;
    return {
        x:-t-w/2+xp, width: w*dim[0]+2*(t-xp),
        y:-t+4*h*j,  height:h*dim[1]+2*t,
        stroke:c.s, fill:c.f
    };
}

let trail = gs.filter((_,i)=>i===0)
    .selectAll().data(d3.range(rank).reverse()).enter()
    .append('rect').attrs(i => {
       let dim = [1,1];
       d3.range(i).forEach(j=>dim[j]=shape[rank-1-j]);
       return getRect(i,0,dim);
    });

let lead = gs.filter((_,i)=>i===1).selectAll()
    .data(d3.range(rank).reverse()).enter()
    .append('g');
lead.selectAll().data(i => {
       let dim = [1,1];
       if (i>1) dim[1]=shape[rank-2];
       return d3.range(i>0?3:1).map(j=>getRect(i,j,dim));
    }).enter()
    .append('rect').attrs(a=>a);

gs.selectAll().data(dat).enter()
    .append('text').text(b=>b)
    .attrs((b,i)=>{let p=getPos(i); p.y+=h-13; return p;});

let iw = w*1.16,
    iH = H+h+32;
indg = gs.append('g').attr('transform',`translate(${(w-iw)*rank/2},0)`)
    .selectAll().data((_,j)=>shape.map(_=>j)).enter();
let inds = indg.append('text').text('1')
    .attrs((j,i)=>({x:(i+1/2)*iw, y:iH, 'font-size':42, 'font-weight':'bold',
                    fill:'#444'/*getColors(j?i:rank-1-i).s.darker(0.2)*/}));
indg.selectAll().data((j,i)=>{
        i%=rank;
        let c = getColor(i);
        c.l = 1 - (1-c.l)*0.8; c.s*=0.86;
        let y = iH+8+4*i,
            dy= -44-8*i,
            sw= [5,3],
            ir= rank-i;
        return [
            [0 , 0 , ir],
            [ir, 0 , dy],
            [ir, dy, i ]
        ].map((r,i) => {
            let h = i!==1,
                p = ['M',' ',h?'h':'v'],
                mulh = m => { r[0]*=m; if (h) r[2]*=m; };
            if (j) r[0]-=rank; r[1]+=y;
            mulh(iw);
            r[2-i] += (i-1)*(sw[0]-sw[1]);
            if (i===2) r[2]+=18;
            if (j) mulh(-1);
            return {
                d:d3.merge(d3.zip(p,r)).join(''),
                stroke:c, 'stroke-width':sw[+(i===1)]
            };
        });
    }).enter()
    .append('path')
    .attrs({ fill:'none', 'stroke-linecap':'round', 'stroke-linejoin':'round' })
    .attrs(a=>a)
    .filter((_,i)=>i==2).lower();

gs.on('mousemove', function () {
    let m = d3.mouse(this);
    let x = div(m[0]+w/2,w),
        y = div(m[1]    ,h),
        s0= 1+shape[0],
        b = y%s0,
        c = div(y,s0);
    if (x<0||x>=shape[rank-1] || b>=shape[0] || c<0||c>=shape[1]) return;
    inds.data([c,b,x]).text(i=>i+1);
    x*=w; c*=s0;
    let s = b+c,
        yt= [s,s,c],
        yl= [s,b,0];
    trail.attr('transform', i=>`translate(${(i?0:x)},${h*yt[i]})`);
    lead .attr('transform', i=>`translate(${     x },${h*yl[i]})`);
});