Как отсортировать элементы по DOM по его внутреннему тексту - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть график, который отображает свои значения в виде div внутри элемента body с классом в соответствии с их числовыми значениями. Это работает нормально. Но затем мне нужно отсортировать элементы в соответствии с их числовыми значениями или цветом фона. НО, это должно начаться в левом нижнем углу страницы и развернуться вверх вправо, поскольку числа увеличиваются. По сути, как линейный график.

Я бы хотел избежать библиотек, если это вообще возможно.

Как бы я подошел к этому? Спасибо всем.

let interval = setInterval(makeDivs, 5);

function makeDivs(){
   let cont = checkHeight();
   if(cont){
      let div = document.createElement('div');
      let randNum = Math.random() * 100;
      if(randNum < 20) { div.classList.add('blue') }
      if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
      if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
      if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
      if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
      div.textContent = randNum.toFixed(2);
      document.querySelector('body').appendChild(div);
   } else {
      alert('done');
      clearInterval(interval);
      sortDivs(); // Begin sorting divs
   }
}

function checkHeight(){
   let w = window.innerHeight;
   let b = document.querySelector('body').offsetHeight;
   if(b < w) {
      return true;
   } else {
      return false;
   }
}

function sortDivs(){
   document.querySelector("body div:last-child").remove();
   alert('sorting now...')
}
* { box-sizing: border-box;}
body { width: 100vw; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: end;}
body div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body div.blue { background: aqua; }
body div.green { background: green; }
body div.yellow { background: yellow; }
body div.orange { background: orange; }
body div.red { background: red; }

enter image description here


ОБНОВЛЕНИЕ !!!

Итак, у меня пока что все основано на обратной связи внизу. Проблема сейчас в том, что сортировка происходит только в поперечном направлении, а не по углу (распространение вправо и вверх).

let interval = setInterval(makeDivs, 10);

      function makeDivs(){
         let cont = checkHeight();
         if(cont){
            let div = document.createElement('div');
            let randNum = Math.random() * 100;
            if(randNum < 20) { div.classList.add('blue') }
            if(randNum >= 20 && randNum < 40) { div.classList.add('green') }
            if(randNum >= 40 && randNum < 60) { div.classList.add('yellow') }
            if(randNum >= 60 && randNum < 80) { div.classList.add('orange') }
            if(randNum >= 80 && randNum < 101) { div.classList.add('red') }
            div.textContent = randNum.toFixed(2);
            document.querySelector('.outPut').appendChild(div);
         } else {
            clearInterval(interval);
            document.querySelector(".outPut div:last-child").remove();
            compileArrays(); // Begin sorting divs
         }
      }

      function checkHeight(){
         let w = window.innerHeight;
         let b = document.querySelector('.outPut').offsetHeight;
         if(b < w) {
            return true;
         } else {
            return false;
         }
      }

      function compileArrays(){
         let divs = document.querySelectorAll('.outPut div');
         let bArr = [], gArr = [], yArr = [], oArr = [], rArr = [];
         divs.forEach( (d) => {
            if( d.classList.contains('blue') ){ bArr.push(d) }
            if( d.classList.contains('green') ){ gArr.push(d) }
            if( d.classList.contains('yellow') ){ yArr.push(d) }
            if( d.classList.contains('orange') ){ oArr.push(d) }
            if( d.classList.contains('red') ){ rArr.push(d) }
         });
         let finalArr = sortArray(bArr).concat(sortArray(gArr)).concat(sortArray(yArr)).concat(sortArray(oArr)).concat(sortArray(rArr));
         newDom(finalArr);
      }

      function sortArray(arr){
         let newArr = arr;
         newArr.sort( (a, b) => {
            return a.innerText - b.innerText;
         });
         return newArr;
      }

      function newDom(arr){
         let b = document.querySelector('.outPut');
         b.innerHTML = '';
         arr.reverse();
         arr.forEach((a) => {
            b.appendChild(a);
         });

      }
* { box-sizing: border-box;}
body { width: 100vw; height: 100vh; margin: 0; padding: 0; display: flex; align-items: flex-end;}
body .outPut { flex: 1; display: flex; flex-wrap: wrap; flex-direction:row-reverse; }
body .outPut div { width: calc(10% + 1px); text-align: center; border: 1px solid #ddd; margin: -1px 0 0 -1px; padding: 10px;}
body .outPut div.blue { background: aqua; }
body .outPut div.green { background: #44df15; }
body .outPut div.yellow { background: yellow; }
body .outPut div.orange { background: orange; }
body .outPut div.red { background: red; }
<div class="outPut"></div>

Ответы [ 3 ]

0 голосов
/ 13 апреля 2020

Это работало с первым примером кода. завернуть в обратном направлении. Надеюсь, что смогу помочь

0 голосов
/ 13 апреля 2020

Вот небольшая скрипка с моим примером кода, демонстрирующая простое решение в чистом JavaScript и абсолютном CSS позиционировании для того, чего вы пытаетесь достичь. Ссылка

Как уже указывали некоторые, может существовать библиотека, которая уже предоставляет лучшее и полное решение для этого - я не исследовал, так ли это.

Код:

file. js

var container = document.getElementById("container")

var results = [1,2,3,4,5,6,7,8]

//you can pre-calculate the order of the distances
//here already orderdered array [distanec][X-axis][Y-axis]
var distances =[[0,0,0],
                [1,1,0],
                [1,0,1],
                [1.414, 1,1],
                [2,0,2],
                [2,2,0],
                [2.234, 2,1],
                [2.234, 1,2]]


for (i = 0; i < results.length; i++){

  var newDiv = document.createElement("div")
  newDiv.className = "result"
  newDiv.innerHTML = results[i]
  newDiv.style.left = distances[i][1]*20 + "px"
  newDiv.style.bottom = distances[i][2]*20 + "px"
  container.appendChild(newDiv)

}


function setColor(element){
 // set class based on value - you already have this part
}

style. css

#container {
  border: 4px;
  border-color: red;
  border-style: solid;
  height: 200px;
  width: 200px;
  position: relative;
}

.result{
  border: 2px;
  width: 20px;
  height: 20px;
  position: absolute;
  border-color: blue;
  border-style: solid;
  text-align: center;
}

site. html

<div id="container">
</div>

Вывод:

enter image description here

0 голосов
/ 13 апреля 2020

Предполагается, что у вас уже есть механизм для организации таких DIV в сетке, как показано, следующее должно дать вам то, что вы ищете:

var items = divList.filter((div) => div.nodeType == 1); // get rid of the whitespace text nodes

items.sort(function(a, b) {
  return a.innerHTML == b.innerHTML
      ? 0
      : (a.innerHTML > b.innerHTML ? 1 : -1);
});

Затем поместите их обратно в DOM по мере необходимости, пример:

for (i = 0; i < items.length; ++i) {
  divList.appendChild(items[i]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...