Public
Edited
Dec 13, 2022
1 fork
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
margin = ({ left: 120, right: 0 })
Insert cell
scales = ({
x: d3
.scaleLinear()
.domain([0, 96])
.range([0, width - margin.left - margin.right])
})
Insert cell
<style>
.cut-list .board {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
font-size: 0.9em;
}

.cut-list .board .meta {
flex: 1 1 ${margin.left};
text-align: left;
padding-right: 10px;
}
.cut-list .board .cuts {
flex: 0 0 ${scales.x(96) + 1}px;
display: flex;
border: 1px solid black;
margin-bottom: 2px;
padding: 1px 0 1px 1px;
align-items: flex-start;
}
.cut-list .board .cut {
display: inline-block;
height: 100%;
}

.cut-list .board .cut:not(:last-child) {
margin-right: ${scales.x(kerfThickness)}px;
}

.cut.stock-4x4 {
color: white;
}

.fade {
opacity: 0.5;
}

${Array.from(Object.entries(boardColors))
.map(([stock, color]) => `.cut.stock-${stock} {
background-color: ${color};
}
`).join('\n')}
</style>
Insert cell
cutAllocation = {
let usedStock = [];
let lastStockId = {};
for (let needed of d3.sort(cutsNeeded, (d) => -d.length)) {
for (let i = 0; i < needed.quantity; i++) {
const canFit = usedStock.filter(
(d) => d.size === needed.stock && d.remaining() >= needed.length
);
let byLeastRemaining = d3.sort(canFit, (d) => d.remaining());
const boardToCut = byLeastRemaining[0];
if (boardToCut?.remaining() >= needed.length) {
boardToCut.add(needed);
} else {
lastStockId[needed.stock] = (lastStockId[needed.stock] ?? 0) + 1;
let newStock = new StockPiece(needed.stock, lastStockId[needed.stock]);
newStock.add(needed);
usedStock.push(newStock);
}
}
}
return usedStock;
}
Insert cell
class StockPiece {
constructor(size, id) {
this.size = size;
this.id = id;
this.cuts = [];
}
remaining() {
let r =
stockLength -
d3.sum(this.cuts, (d) => d.length) -
kerfThickness * this.cuts.length;
if (r < 0 && r >= -kerfThickness) {
return 0;
}
return r;
}
add(cut) {
this.cuts.push(cut);
}
}
Insert cell
Insert cell
Insert cell
cutsNeeded = d3.csvParse(
`id,stock,length,quantity
1a,4x4,46.5,2
1b,4x4,86,2
2a,2x4,96,2
2b,2x4,93,1
2z,2x4,4.5,2
3a,2x2,93,1
3b,2x4,86.5,2
3c,2x2,86.5,1
3d,2x2,96,1
3e,2x2,42.25,4
4a,2x2,43.5,2
4b,2x2,89.5,3
4c,2x2,19.5,4
5a,2x2,16.5,1
5b,2x2,89.5,1
5c,2x2,69.75,1
5d,2x2,40.5,1
5e,2x2,43.5,1
5f,2x2,91,1
5g,2x2,13.5,1
8a,2x4,46.5,2
8b,2x4,43.5,3
8c,2x4,96,1
10a,2x2,63.75,2
10b,2x4,25,2
10c,2x2,22,1
10d,2x2,39,1
`,
(d) => ({
...d,
length: parseFloat(d.length),
quantity: parseFloat(d.quantity),
step: parseInt(d.id.match(/(\d+)/)[1])
})
)
Insert cell
shelf stuff
```
11b,2x2,14.25,9,45deg
11c,2x2,17.125,1,45deg
```
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more