'ReactJS: HighLight background with variable random value
I am displaying a table that gets data from the data.json file. I built the arrow function getColor to consider the color for the values of columns d, e according to the conditions. Top 10 rows I need to change random data every 3s for columns d and e.
I want when the value in the cell changes, the color also changes according to the condition of the arrow function getColor and will highlight the cell with that changed value in 1s with two backgrouds corresponding to 2 different colors.
I'm not sure how to highlight background the cells that have changed values
below is what i did. You can also watch it at https://codesandbox.io/s/stupefied-perlman-qoi4wp?file=/src/App.js
the App.js file looks like this:
import React, { useState, useEffect } from "react";
import data from './datafile/data.json';
import './styles.css'
export default function App() {
const getColor = (a, b, c, value) =>{
if(value > a && value < b){
return "green";
}else if(value > c && value < a){
return "red"
}
}
let ListData = data.list;
let get10Data = ListData.slice(0, 10)
const [list, setData] = useState(get10Data);
const randomValue = (min, max) => {
let value = Math.floor(Math.random() * (max - min + 1) + min)
return value;
}
const ChangeData = () => {
get10Data.slice().map((info) => {
if (info.a && info.b &&
info.c && info.d && info.e !== undefined) {
randomValue(info.b, info.c)
return (
setData(get10Data.slice(0, 5)),
info.d = randomValue(info.b, info.c),
info.e = randomValue(info.b, info.c)
)
}else {
return ''
}
})
}
useEffect(() => {
setInterval(ChangeData, 3000)
}, [])
const Reacords = data.list.map(info => {
return (
<tr>
<td>{info.name}</td>
<td>{info.a}</td>
<td>{info.b}</td>
<td>{info.c}</td>
<td className={getColor(info.a, info.b, info.c, info.d)}>{info.d}</td>
<td className={getColor(info.a, info.b, info.c, info.e)}>{info.e}</td>
</tr>
)
})
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
<th>e</th>
</tr>
</thead>
<tbody>
{Reacords}
</tbody>
</table>
);
}
the data.json file looks like this:
{
"a": "ok",
"list": [
{
"name": "A",
"a": 50,
"b": 90,
"c": 30,
"d": 40,
"e": 85
},
{
"name": "B",
"a": 63,
"b": 110,
"c": 40,
"d": 87,
"e": 85
},
{
"name": "C",
"a": 48,
"b": 85,
"c": 25,
"d": 30,
"e": 43
},
{
"name": "D",
"a": 45,
"b": 90,
"c": 30,
"d": 40,
"e": 85
},
{
"name": "E",
"a": 63,
"b": 110,
"c": 40,
"d": 87,
"e": 85
},
{
"name": "F",
"a": 48,
"b": 85,
"c": 25,
"d": 30,
"e": 43
},
{
"name": "G",
"a": 50,
"b": 90,
"c": 30,
"d": 40,
"e": 85
},
{
"name": "H",
"a": 63,
"b": 110,
"c": 40,
"d": 87,
"e": 85
},
{
"name": "I",
"a": 48,
"b": 85,
"c": 25,
"d": 30,
"e": 43
},
{
"name": "K",
"a": 50,
"b": 90,
"c": 30,
"d": 40,
"e": 85
},
{
"name": "L",
"a": 63,
"b": 110,
"c": 40,
"d": 87,
"e": 85
},
{
"name": "M",
"a": 48,
"b": 85,
"c": 25,
"d": 30,
"e": 43
}
]
}
Hope you can help. Please show an example of how it is done. random value generation part if anyone have another way can let me know.
Solution 1:[1]
I'm using keyframes to achieve the background color change with animation within 2 seconds (the 1st second to turn green/red, the 2nd second to turn back to the white background)
.App {
font-family: sans-serif;
text-align: center;
}
table {
border: 1px solid #333333;
border-collapse: collapse;
width: 90%;
}
th,
td {
border: 1px solid #333333;
border-collapse: collapse;
text-align: center;
}
@keyframes green-background-fade {
50% {
background: rgba(0, 128, 0, 0.3);
}
100% {
background: #fff;
}
}
@keyframes red-background-fade {
50% {
background: rgba(128, 0, 0, 0.3);
}
100% {
background: #fff;
}
}
.background-green {
animation: green-background-fade 2s forwards;
}
.background-red {
animation: red-background-fade 2s forwards;
}
.green {
color: green;
}
.red {
color: red;
}
You also need to have useEffect with setTimeout to reset animation
import React, { useState, useEffect, useCallback } from "react";
import data from "./datafile/data.json";
import "./styles.css";
const Row = ({ info, mainInfo }) => {
const [backgroundColor, setBackgroundColor] = useState("");
const [textColor, setTextColor] = useState("");
useEffect(() => {
const color = getColor(info.a, info.b, info.c, mainInfo);
setBackgroundColor(`background-${color}`);
setTextColor(color);
setTimeout(() => {
setBackgroundColor("");
}, 2000);
}, [mainInfo]);
const getColor = useCallback((a, b, c, value) => {
if (value > a && value < b) {
return "green";
} else if (value > c && value < a) {
return "red";
}
}, []);
return <td className={[backgroundColor, textColor].join(" ")}>{mainInfo}</td>;
};
const Record = ({ info }) => {
return (
<tr>
<td>{info.name}</td>
<td>{info.a}</td>
<td>{info.b}</td>
<td>{info.c}</td>
<Row info={info} mainInfo={info.d} />
<Row info={info} mainInfo={info.e} />
</tr>
);
};
export default function App() {
let ListData = data.list;
let get10Data = ListData.slice(0, 10);
const [list, setData] = useState(ListData);
const randomValue = (min, max) => {
let value = Math.floor(Math.random() * (max - min + 1) + min);
// value = parseFloat(value / 1000).toFixed(2) * 1000;
return value;
};
const ChangeData = () => {
get10Data.slice().map((info) => {
if (info.a && info.b && info.c && info.d && info.e !== undefined) {
randomValue(info.b, info.c);
return (
setData(get10Data.slice(0, 5)),
(info.d = randomValue(info.b, info.c)),
(info.e = randomValue(info.b, info.c))
);
} else {
return "";
}
});
};
useEffect(() => {
setInterval(ChangeData, 3000);
}, []);
const Records = data.list.map((info, index) => (
<Record key={info.name + index} info={info} />
));
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
<th>e</th>
</tr>
</thead>
<tbody>{Records}</tbody>
</table>
);
}
The full code is in this sanbox
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
