I can place my small parts in the most optimized way for a single large part in my project. The algorithm logic is as follows; The pieces I have are sorted by height from largest to smallest and then placed from left to right. when i have multiple large parts i keep those big parts in a state.
In the first large piece, when there is no suitable place for the small pieces to be added, I want the appropriate region to be queried in the second big piece. here is my code: index.js
import React, { useContext, useEffect, useRef, useState } from 'react'
import data from '../data'
import Graph from './graph/graph'
import SmallAreaGraph from './graph/small-area-graph';
import { IndexContext } from './IndexContext';
function Index() {
var height = 50;
var width = 50;
const [defaultHeight, setDefaultHeight] = useState(50);
const [defaultWidth, setDefaultWidth] = useState(50);
const [planes, setPlanes] = useState();
const [testState, setTestState] = useState([]);
const [bigBoard, setBigBoard] = useState(new Array(defaultWidth).fill(0).map(() => new Array(defaultHeight).fill(0)));
const [smallPlanes, setSmallPlanes] = useState([]);
const [smallPlanesArea, setSmallPlanesArea] = useState([]);
const [freeSpaceAreas, setFreeSpaceAreas] = useState([]);
const [bigPlanes, setBigPlanes] = useState([{ bigBoard: bigBoard, planes: [], height: defaultHeight, width: defaultWidth, color: "pink" }]);
var totalWidth;
const heightRef = useRef();
const widthRef = useRef();
var smallPlane, totalArea = 0;
function Placement() {
let total = 0;
let totalHeight = 0;
let allArea = [];
for (let i = 0; i < smallPlanes.length; i++) {
if (i === 0) {
smallPlanes[i].x = 1;
} else {
if (allArea !== []) {
} else {
total = total + smallPlanes[i - 1].width + 2;
totalHeight = totalHeight + smallPlanes[i - 1].height + 2;
allArea.push(smallPlanes[i - 1]);
}
if (total + smallPlanes[i].width > Number(width)) {
total = 0;
allArea.push(smallPlanes[i]);
smallPlanes[i].x = 1;
smallPlanes[i].y = allArea[0].height + 2;
return total
} else {
smallPlanes[i].x = total;
}
}
}
}
function Sort() {
let gecici;
for (let i = 0; i <= testState.length - 1; i++) {
for (let j = i; j <= testState.length; j++) {
// >(büyük) işareti <(küçük ) olarak değiştirilirse büyükten küçüğe sıralanır
if (testState[i]?.height < testState[j]?.height) {
gecici = testState[j];
testState[j] = testState[i];
testState[i] = gecici;
setTestState(testState);
}
}
}
// Placement();
}
useEffect(() => {
if (testState !== [] || testState !== undefined) {
Sort();
}
}, [testState]);
function AddBigPlane() {
setBigPlanes([...bigPlanes, { bigBoard: bigBoard, planes: [], height: defaultHeight, width: defaultWidth, color: "pink" }])
}
function Revaluation(w, h, row, col, k) {
totalWidth = totalWidth + Number(w);
if (Number(col + w) <= bigPlanes[k].bigBoard.length) {
if (Number(row + h) <= bigPlanes[k].bigBoard[row].length) {
for (let i = row; i < Number(row + h); i++) {
for (let j = col; j < Number(col + w); j++) {
let bashData = bigPlanes[k];
bashData.bigBoard[i][j] = 1
setBigPlanes(bashData);
}
}
}
}
}
function test(w, h, row, col, index) {
if (Number(row + w) <= bigPlanes[index].width && Number(col + h) <= bigPlanes[index].height) {
for (let i = row; i < Number(row + w); i++) {
for (let j = col; j < Number(col + h); j++) {
if (bigPlanes[index].bigBoard[i][j] === 0) {
if (i === (Number(row + w) - 1) && j === (Number(col + h) - 1)) {
freeSpaceAreas[index] = freeSpaceAreas[index] - smallPlane;
setFreeSpaceAreas([...freeSpaceAreas]);
setTestState([...testState, {
height: Number(heightRef?.current?.value), width: Number(widthRef?.current?.value)
}])
// return Revaluation(Number(widthRef?.current?.value), Number(heightRef?.current?.value), row, col, index);
// let bashData = bigPlanes;
// bashData[k].planes.height = Number(heightRef?.current?.value);
// bashData[k].planes.width = Number(widthRef?.current?.value);
// setBigPlanes(bashData);
}
}
}
}
}
}
function Control(index) {
//ilk 0 değerine sahip row-col (coordinat) değerlri
console.log(index);
for (let row = 0; row < bigPlanes[index].bigBoard.length; row++) {
for (let col = 0; col < bigPlanes[index].bigBoard[row].length; col++) {
if (bigPlanes[index].bigBoard[row][col] === 0) {
//bulunduktan sonra test fonksiyonuna aktarılır.
return test(Number(widthRef.current.value), Number(heightRef.current.value), row, col, index);
}
}
}
}
useEffect(() => {
if (bigPlanes.length !== freeSpaceAreas.length) {
for (let i = 0; i < bigPlanes.length; i++) {
console.log(bigPlanes);
setFreeSpaceAreas([...freeSpaceAreas, bigPlanes[i].width * bigPlanes[i].height])
}
}
}, [bigPlanes]);
function AreaControl() {
// smallPlanesArea?.length && smallPlanesArea.map(area => {
// totalArea = totalArea + area;
// })
console.log("test");
for (let i = 0; i < freeSpaceAreas.length; i++) {
if (smallPlane <= freeSpaceAreas[i]) {
console.log(i);
return Control(i);
}
}
heightRef.current.value = "";
widthRef.current.value = "";
}
function handleKeyDown(e) {
if (e.key === "Enter") {
if (heightRef?.current.value !== "") {
if (widthRef.current.value !== "") {
smallPlane = Number(heightRef?.current.value) * Number(widthRef?.current.value);
AreaControl();
// widthRef.current.value = "";
// heightRef.current.value = "";
} else {
alert("Lütfen bir genişlik değeri giriniz");
}
} else {
alert("Lütfen bir yükseklik değeri giriniz");
}
}
}
useEffect(() => {
console.log(freeSpaceAreas);
}, [freeSpaceAreas]);
function AddAreas() {
// Gerçek zamanlı arr state'i güncelleme.
setPlanes([...smallPlanes]);
ResetSmallPlane();
ResetBigPlane();
for (let i = 0; i < testState.length; i++) {
findCoords(testState[i])
}
}
var totalWidth = 0, totalHeight = 0, totW = 0, totH = 0;
// function RevaluationTwo(w, h, row, col) {
// let bashData;
// for (let i = row; i < Number(row + h); i++) {
// for (let j = col; j < Number(col + w); j++) {
// bashData = bigBoard;
// bashData[i][j] = 1;
// setBigBoard(bashData);
// }
// }
// }
function ResetBigPlane() {
for (let k = 0; k < bigPlanes.length; k++) {
for (let row = 0; row < bigPlanes[k].bigBoard.length; row++) {
for (let col = 0; col < bigPlanes[k].bigBoard[row].length; col++) {
if (bigPlanes[k].bigBoard[row][col] === 1) {
let bashData = bigPlanes;
bashData[k].bigBoard[row][col] = 0
setBigPlanes(bashData);
}
}
}
}
}
function bigPlanesControl() {
for (let i = 0; i < bigPlanes.length; i++) {
}
}
function ResetSmallPlane() {
let arrAttributes = [];
for (let i = 0; i < bigPlanes.length; i++) {
var arr = bigPlanes[i].planes;
arr.length = 0;
arrAttributes.push(arr);
}
setBigPlanes([...arrAttributes]);
}
function createCoords(w, h, row, col, i) {
let bashData = [];
totW = totW + Number(w);
if (Number(col + w) <= bigPlanes[i].width) {
if (Number(row + h) <= bigPlanes[i].height) {
bashData = bigPlanes;
bashData[i].planes.push({ height: h, width: w, x: col + 1, y: row + 1 });
setBigPlanes([...bashData]);
} else {
return;
}
} else {
return;
}
}
function findCoords(test) {
console.log(test);
for (let k = 0; k < bigPlanes.length; k++) {
for (let row = 0; row < bigPlanes[k].bigBoard.length; row++) {
for (let col = 0; col < bigPlanes[k].bigBoard[row].length; col++) {
if (bigPlanes[k].bigBoard[row][col] === 0) {
Revaluation(test.width, test.height, row, col, k);
if (Number(bigPlanes[k].bigBoard[row].length - col) >= test.width) {
return createCoords(test.width, test.height, row, col, k);
}
else
return;
}
}
}
}
}
function Approve() {
ResetSmallPlane();
ResetBigPlane();
for (let i = 0; i < testState.length; i++) {
findCoords(testState[i])
}
}
return (
<div className='container mt-5'>
<div className='big-plane'>
</div>
<div className='d-flex justify-content-between '>
<div></div>
<div className='d-flex'>
<div className='me-4'>
<input className='input form-control ' type="text" ref={heightRef} placeholder="Yükseklik giriniz.." onKeyUp={handleKeyDown} />
</div>
<div className='me-4'>
<input className='input form-control ' type="text" ref={widthRef} placeholder="Genişlik giriniz.." onKeyUp={handleKeyDown} />
</div>
<div className='btn btn-success' onClick={() => Approve()}>
Onayla
</div>
<div className='btn btn-success' onClick={() => AddAreas()}>
Ekle
</div>
</div>
<div className='btn btn-danger d-flex align-items-center'>
<div onClick={() => AddBigPlane()}>Cam Plaka Ekle</div> <b style={{ fontWeight: "bolder", fontSize: "20px", marginLeft: "5px" }}>+</b>
</div>
</div>
{
testState?.length ? testState.map((plane, i) => {
return <SmallAreaGraph color="purple" key={i} data={data} height={Number(plane.height)} width={Number(plane.width)} />
}) : ""
}
<div className='mt-5'>
{/* where large parts are added */}
{
bigPlanes.length ? bigPlanes.map((plane, i) => {
totalWidth = totalWidth + bigPlanes[i].width;
return <Graph smallPlanesProps={plane.planes} data={plane.bigBoard} key={i} color={plane.color} height={plane.height} width={plane.width} x={0} y={0} position="absolute" zIndex="-10" left={totalWidth} />
}
) : ""
}
</div>
</div>
)
}
export default Index