How to create progress bar in datatable?
P粉422227023
2023-08-26 21:01:16
<p>I am currently working on a data table containing a large amount of data (5000). To be able to load the data at a progressive pace, I added a progress bar that illustrates how much data has been loaded per time unit. But the code below no longer works.</p>
<p><br /></p>
<pre class="brush:js;toolbar:false;">let handleProgressBar = (id, value, total) => {
let percent = Math.round((value / total) * 10000) / 100;
$(id " > div").html(percent "%");
$(id " > div").css('width', percent "%");
}
let table = $('#data').DataTable();
fetch('https://jsonplaceholder.typicode.com/photos')
.then((res) => res.json())
.then((res) => {
res.forEach(async(data, index)=>{
table.row.add([
data.id,
data.albumId,
data.title,
data.url
]);
handleProgressBar('#progress-bar', index 1, res.length);
await new Promise(r => setTimeout(r, 1)); // sleep 1 ms
});
table.draw();
});</pre>
<pre class="brush:css;toolbar:false;">.progress-bar-striped {
overflow: hidden;
height: 20px;
margin-bottom: 20px;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.progress-bar-striped>div {
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-size: 40px 40px;
float: left;
width: 0%;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #000000;
font-weight: bold;
text-align: center;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
/*-webkit-transition: width 3s ease;
-moz-transition: width 3s ease;
-o-transition: width 3s ease;
transition: width 3s ease;*/
animation: progress-bar-stripes 2s linear infinite;
background-color: #288ade;
}
.progress-bar-striped p {
margin: 0;
}
@keyframes progress-bar-stripes {
0% {
background-position: 40px 0;
}
100% {
background-position: 0 0;
}
}</pre>
<pre class="brush:html;toolbar:false;"><link rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<div id="progress-bar" class="progress-bar-striped">
<div style="width: 0%;">
<p>0%</p>
</div>
</div>
<table id="data" class="table display table-stripped">
<thead>
<tr>
<th>ID</th>
<th>Album ID</th>
<th>Title</th>
<th>URL Photo</th>
</tr>
</thead>
<tbody></tbody>
</table></pre>
<p><br /></p>
<p>The table loaded successfully, but the progress bar shows <code>100%</code> instead of incrementing from <code>0%</code> to <code>100%</ code>. I was wondering if it would work (<em>but not perfectly</em>) if I didn't use a datatable, as shown in the code below.</p>
<p><br /></p>
<pre class="brush:js;toolbar:false;">let handleProgressBar = (id, value, total) => {
let percent = Math.round((value / total) * 10000) / 100;
$(id " > div").html(percent "%");
$(id " > div").css('width', percent "%");
}
(async() =>{
let n = 5000;
handleProgressBar('#progress-bar', 0, n);
for(let i = 1; i <= n; i ) {
handleProgressBar('#progress-bar', i, n);
await new Promise(r => setTimeout(r, 1)); // sleep 1 ms
}
})();</pre>
<pre class="brush:css;toolbar:false;">.progress-bar-striped {
overflow: hidden;
height: 20px;
margin-bottom: 20px;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.progress-bar-striped>div {
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-size: 40px 40px;
float: left;
width: 0%;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #000000;
font-weight: bold;
text-align: center;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
/*-webkit-transition: width 3s ease;
-moz-transition: width 3s ease;
-o-transition: width 3s ease;
transition: width 3s ease;*/
animation: progress-bar-stripes 2s linear infinite;
background-color: #288ade;
}
.progress-bar-striped p {
margin: 0;
}
@keyframes progress-bar-stripes {
0% {
background-position: 40px 0;
}
100% {
background-position: 0 0;
}
}</pre>
<pre class="brush:html;toolbar:false;"><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="progress-bar" class="progress-bar-striped">
<div style="width: 0%;">
<p>0%</p>
</div>
</div></pre>
<p><br /></p>
<p>我不知道錯誤出在哪里。誰能為我提供處理大量數(shù)據(jù)的數(shù)據(jù)表進度條的完美方法?先謝謝了。</p>
I have found a solution. The mistake was that I put the word async
inside res.forEach
. When I put it after fetch.then
and use a for
loop instead of forEach
, the behavior of the function execution changes and it completes successfully. The loadNumber
variable can be used to determine how much data will be plotted in the data table per unit time.
let handleProgressBar = (id, value, total) => {
let percent = Math.round((value / total) * 10000) / 100;
$(id + " > div").html(percent + "%");
$(id + " > div").css('width', percent + "%");
}
let table = $('#data').DataTable({
dom: 'ilpftr'
});
fetch('https://jsonplaceholder.typicode.com/photos')
.then((res) => res.json())
.then(async(res) => {
let loadNumber = 50;
for(let i = 0; i < res.length; i++) {
table.row.add([
res[i].id,
res[i].albumId,
res[i].title,
res[i].url
]);
if (i % loadNumber == 0) {
table.draw();
handleProgressBar('#progress-bar', i+1, res.length);
await new Promise(r => setTimeout(r, 1)); // sleep 1 ms
}
}
table.draw();
handleProgressBar('#progress-bar', res.length, res.length);
});
.progress-bar-striped {
overflow: hidden;
height: 20px;
margin-bottom: 20px;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.progress-bar-striped>div {
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
background-size: 40px 40px;
float: left;
width: 0%;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #000000;
font-weight: bold;
text-align: center;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
/*-webkit-transition: width 3s ease;
-moz-transition: width 3s ease;
-o-transition: width 3s ease;
transition: width 3s ease;*/
animation: progress-bar-stripes 2s linear infinite;
background-color: #288ade;
}
.progress-bar-striped p {
margin: 0;
}
@keyframes progress-bar-stripes {
0% {
background-position: 40px 0;
}
100% {
background-position: 0 0;
}
}
<link rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<div id="progress-bar" class="progress-bar-striped">
<div style="width: 0%;">
<p>0%</p>
</div>
</div>
<table id="data" class="table display table-stripped">
<thead>
<tr>
<th>ID</th>
<th>Album ID</th>
<th>Title</th>
<th>URL Photo</th>
</tr>
</thead>
<tbody></tbody>
</table>
Like +0
P粉422227023
reply