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 href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" 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>我不知道错误出在哪里。谁能为我提供处理大量数据的数据表进度条的完美方法?先谢谢了。</p>
I have found a solution. The mistake was that I put the word
async
insideres.forEach
. When I put it afterfetch.then
and use afor
loop instead offorEach
, the behavior of the function execution changes and it completes successfully. TheloadNumber
variable can be used to determine how much data will be plotted in the data table per unit time.