Home > Enterprise >  Vanilla JS get lowest value from cell and change the background color
Vanilla JS get lowest value from cell and change the background color

Time:12-12

Im trying to change the background color of the cells with the lowest value, "the winner", like the picture.Right The lowest value of Co2, Co2% and Co2 per capita. I tried with the code below but it give me wrong result. It looks like this then: Wrong Need some help to iterate through the table.

My table:

<table>
    <thead>
        <tr>
            <th>Country</th>
            <th>Year</th>
            <th>CO2</th>
            <th>CO2 %</th>
            <th>CO2 per capita</th>
            <th>Population</th>
        </tr>
    </thead>
    <tbody id="tablebody"></tbody>
</table>

My code: async function compareData() {

document.querySelectorAll('tbody>tr').forEach((row) => {
  const co2 = row.querySelector('td:nth-child(3)');
  const co2Percent = row.querySelector('td:nth-child(4)');
  const co2PerCapita = row.querySelector('td:nth-child(5)');
  const columns = [co2, co2Percent, co2PerCapita];
  const minValue = Math.min(...columns.map(element => element.textContent));
  columns.find(element => element.textContent == minValue).style.backgroundColor = 'lime';
  });

}

CodePudding user response:

Your code is finding the minimum per row, while you want it per column. So use this instead:

function compareData() {
    const rows = document.querySelector("tbody").rows;
    for (let col = 2; col < 5; col  ) {
        const cells = Array.from(rows, row => row.cells[col]);
        const data = cells.map(cell =>  cell.textContent);
        const min = Math.min(...data);
        const i = data.indexOf(min);
        cells[i].style.backgroundColor = "lime";
    }
}

compareData();
<table>
    <thead>
        <tr>
            <th>Country</th>
            <th>Year</th>
            <th>CO2</th>
            <th>CO2 %</th>
            <th>CO2 per capita</th>
            <th>Population</th>
        </tr>
    </thead>
    <tbody id="tablebody">
        <tr><td>Sweden</td><td>1904</td><td>10.325</td><td>5.306</td><td>1.964</td><td>5257162</td></tr>
        <tr><td>Norway</td><td>1904</td><td>4.159</td><td>-1.901</td><td>1.813</td><td>2293727</td></tr>
        <tr><td>Denmark</td><td>1904</td><td>6.178</td><td>7.869</td><td>2.303</td><td>2682732</td></tr>
    </tbody>
</table>

NB: the two images you posted are not about the same data. I used the data from the second image in this snippet.

CodePudding user response:

This solution generates sample data, and seems similar to trincot in how it works on columns instead of rows.

function fillInData(sel, rows) {
  const t = document.querySelector(sel);
  const cols = t.querySelectorAll("th").length;
  const body = t.querySelector("tbody");
  for (let r=0; r<rows; r  ) {
    let row = ['<tr>'];
    for (let c=0; c<cols; c  ) {
      row.push(`<td>${~~(Math.random()*100)}</td>`);
    }
    body.insertAdjacentHTML("beforeend", row.join(""));
  }
}

function highlightLowestInColumn(sel, color) {
  const t = document.querySelector(sel);
  const cols = t.querySelectorAll("th").length;
  const body = t.querySelector("tbody");
  for (let c=0; c<cols; c  ) {
    const cells=[... body
      .querySelectorAll(`td:nth-child(${c 1}`)];
    const min=Math.min(... cells.map(v=>v.textContent));
    cells.find(e=>e.textContent == min)
      .style.backgroundColor=color;
  }
}

fillInData("#t", 5);
highlightLowestInColumn("#t",'lime');
<table id="t">
    <thead>
        <tr>
            <th>Country</th>
            <th>Year</th>
            <th>CO2</th>
            <th>CO2 %</th>
            <th>CO2 per capita</th>
            <th>Population</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

  • Related