3d-matching-problem

https://en.wikipedia.org/wiki/3-dimensional_matching

by Lamik

HTML

Type 3d vector with (positive integer numbers e.g. 1,2,3)<br>
<input id="vec" value="1,2,3">
<button onclick="update()">add</button>
<button onclick="clearAll()">clear all</button>

<div class="content">
  <div id='container'>

  </div>
  <div id='list'>
  </div>
</div>

CSS

.point {
opacity:1;fill:#d40000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate
}

.point_0 { fill:#d40000 }
.point_1 { fill:#00d400 }
.point_2 { fill:#0000d4 }

.matF { opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#e6e6e6;stroke-width:22;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate }

.matB { opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:24;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate}

.content {
  display: flex;
}

.listItem { cursor: pointer}

.text { font-size:16px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Sans;-inkscape-font-specification:Sans Italic }

JavaScript

// matching = [[1,2,3], [2,3,4]]; // numbers shod be integers
function draw(divSelector,matching) {
  
  let c='';
  let r=10, marginLeft=40, marginTop=40; 
  let spaceX=100, spaceY=100, mSizeMin=10, mSizeMax=20;
  let max=Math.max(...matching.flat());
  let min=Math.min(...matching.flat());
    
  ['X','Y','Z'].forEach((e,i)=>{
    c+=`<text class="text"><tspan x="${marginLeft+i*spaceX}" y="${marginTop-20}">${e}</tspan></text>`
  });
  
  if(matching.length>0) {
  console.log(matching.length);
    [...Array(25)].map((_,i) => i+min).forEach((e,i)=>{
    c+=`<text class="text"><tspan x="${marginLeft-20}" y="${marginTop+i*spaceY}">${min+i}</tspan></text>`
    });
  }
  
    
  // matching  
  matching.forEach((e,j)=>{
    let x0=marginLeft+0*spaceX, y0=marginTop+(e[0]-min)*spaceY;
    let x1=marginLeft+1*spaceX, y1=marginTop+(e[1]-min)*spaceY;
    let x2=marginLeft+2*spaceX, y2=marginTop+(e[2]-min)*spaceY;
    let st=mSizeMin+(mSizeMax-mSizeMin)*(1-j/(matching.length-1)); // matching size
    let sc=127+(128*j/(matching.length))|0; sc=`rgb(${sc},${sc},${sc})` // color
    let mF=`<path class="matF" d="M ${x0},${y0} L ${x1},${y1} L ${x2},${y2}" style="stroke-width:${st}; stroke:${sc}"/>`
    let mB=`<path class="matB" d="M ${x0},${y0} L ${x1},${y1} L ${x2},${y2}" style="stroke-width:${st+2}"/>`

    c+=mB+mF;
  });
  
  // points
  for(let i=0; i<3; i++) {
    for(let j=0; j<=max-min; j++) {
      let x=marginLeft+i*spaceX, y=marginTop+j*spaceY;
      let p=`<path class="point point_${i}" d="M ${x+r/2},${y} A 1,1 0 1 1 ${x-r/2},${y} A 1,1 0 1 1 ${x+r/2},${y} z"/>`;
      c+=p;
      console.log(p);
    }}
  
  let s= `<svg height=${2*marginTop+spaceY*(max-min)} width=${2*marginLeft+spaceX*2} xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">${c}</svg>`;

	document.querySelector(divSelector).innerHTML=s;  
}

function showList(list) {
  let s=''
  list.forEach((x,i)=>{
  	s += `<div class="listItem" onclick="removeElement(${i})">[ ${x} ]...