Bootstrap DataTable迷你图从逗号分隔的字符串而不是数组中获取数据



我使用的是Bootstrap DataTable组件,我可以从数据库中获取数据,并将其显示在我的Asp.net Core MVC应用程序上。现在,在我想添加一个sparkline的列中,组件要求sparkline列是一个值数组,但我有一个逗号分隔的字符串,我需要帮助了解如何更改JS以使用我的值类型。

为了更简单,我创建了一个没有DB的新应用程序,并使用JS中直接定义的数据,如本例所示:https://datatables.net/examples/basic_init/stocks.html

这非常有效。

现在我必须改变";最后一个";来自:

var stock_data = [
{
"name": "ACME Gadgets",
"symbol": "AGDTS",
"last": [2.57, 2.54, 2.54, 2.56, 2.57, 2.58, 2.59]
},
.....
]

收件人:

var stock_data = [
{
"name": "ACME Gadgets",
"symbol": "AGDTS",
"last": "2.57, 2.54, 2.54, 2.56, 2.57, 2.58, 2.59"
},
.....
]

这是需要更改的js:

$(document).ready(function () {
debugger;
var stock_data = [
{
"name": "ACME Gadgets",
"symbol": "AGDTS",
"last": [2.57, 2.54, 2.54, 2.56, 2.57, 2.58, 2.59]
},
{
"name": "Spry Media Productions",
"symbol": "SPMP",
"last": [1.12, 1.11, 1.08, 1.08, 1.09, 1.11, 1.08]
},
{
"name": "Widget Emporium",
"symbol": "WDEMP",
"last": [3.40, 3.39, 3.46, 3.51, 3.50, 3.48, 3.49]
},
{
"name": "Sole Goodman",
"symbol": "SGMAN",
"last": [16.20, 16.40, 16.36, 16.35, 16.61, 16.46, 16.19]
},
{
"name": "Stanler Bits and Bobs",
"symbol": "SBIBO",
"last": [82.51, 83.47, 83.40, 83.68, 83.81, 83.29, 83.72]
}
];
let table = $('#example').DataTable({
ajax: function (dataSent, callback, settings) {
let data = this.api().ajax.json();
if (data == undefined) {
data = stock_data;
} else {
data = data.data;
for (i = 0; i < data.length; i++) {
data[i].last.push(data[i].last.shift())
}
}
callback({ data: data });
},
paging: false,
initComplete: function () {
let api = this.api();
setInterval(function () {
api.ajax.reload();
}, 5000);
},
drawCallback: function () {
$('.sparkline')
.map(function () {
return $('canvas', this).length ? null : this;
})
.sparkline('html', {
type: 'line',
width: '250px'
})
},
columns: [
{
data: 'name'
},
{
data: 'symbol'
},
{
data: null,
render: function (data, type, row, meta) {
return row.last[row.last.length - 1].toFixed(2);
}
},
{
data: null,
render: function (data, type, row, meta) {
var val = (row.last[row.last.length - 1] - row.last[row.last.length - 2]).toFixed(2);
var colour = val < 0 ? 'red' : 'green'
return type === 'display' ?
'<span style="color:' + colour + '">' + val + '</span>' :
val;
}
},
{
data: 'last',
render: function (data, type, row, meta) {
return type === 'display' ?
'<span class="sparkline">' + data.toString() + '</span>' :
data;
}
}
]
});
});

我试着在"中使用一些.split(","(;data:"last",render;但运气不好,我也很难调试js(在site.js中(,我试着放了一些console.log,但没有在输出中写入任何内容。

UPDATE感谢@andrewJames,现在我的代码运行良好,出于某种原因,它甚至不需要任何数据传输,这就像自动将csv字符串转换为所需的数组。

我还添加了一些其他功能,如按列分组和使用moment.js 转换日期时间显示格式

这是完整的代码:

$(document).ready(function () {
var groupColumn = 0;
let table = $('#example').DataTable({
responsive: true,
autoWidth: true,
processing: true,
ordering: true,
scrollY: '50vh',
scrollCollapse: true,
paging: false,
searching: true,
"ajax": {
"url": "api/ApartmentsAvailables",
"type": "GET",
"contentType": "application/json; charset=utf-8",
"dataType": "json",
},
columnDefs: [{ visible: false, targets: groupColumn },
{
targets: 7,
render: DataTable.render.datetime('YYYY-MM-DDT00:00:00', 'MMMM D, YYYY', 'en'),
},
{ responsivePriority: 1, targets: 0 },
],
order: [[groupColumn, 'asc']],

drawCallback: function (settings) {
$('.sparkline')
.map(function () {
return $('canvas', this).length ? null : this;
})
.sparkline('html', {
type: 'line',
width: '250px'
})
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api
.column(groupColumn, { page: 'current' })
.data()
.each(function (group, i) {
if (last !== group) {
$(rows)
.eq(i)
.before('<tr class="group" style="background-color:DarkGray; text-align:center;font-weight: bold; color:white;"><td  colspan="8">' + group + '</td></tr>');
last = group;
}
})
},
columns: [
{ "data": "building" },
{ "data": "floor_Plan" },
{ "data": "apt_Number" },
{ "data": "rent" },
{ "data": "bedrooms" },
{ "data": "bathrooms" },
{ "data": "sqft" },
{ "data": "available_Date" },
{
data: 'prices',
render: function (data, type, row, meta) {
return type === 'display' ?
'<span class="sparkline">' + data.toString() + '</span>' :
data;
}
},
]
});
new $.fn.dataTable.FixedHeader(table);
// Order by the grouping
$('#example tbody').on('click', 'tr.group', function () {
var currentOrder = table.order()[0];
if (currentOrder[0] === groupColumn && currentOrder[1] === 'asc') {
table.order([groupColumn, 'desc']).draw();
} else {
table.order([groupColumn, 'asc']).draw();
}
});
});

我现在面临的唯一问题是,一旦我启用responsive: true,,sparkline列就会被隐藏,当我单击展开行以显示隐藏列时,它显示的是整个Value数组,而不是sparkline。

我想

drawCallback: function (settings) {
$('.sparkline')
.map(function () {
return $('canvas', this).length ? null : this;
})
.sparkline('html', {
type: 'line',
width: '250px'
})

无法应用于隐藏的列。

如果没有响应选项,为td生成的html为:

<td>
<span class="sparkline">
<canvas style="display: inline-block; width: 250px; height: 21px; vertical-align: top;"
width="250"
height="21"/>
</span>
</td>

响应设置为true时:

<td style="display: none;"
class="dtr-hidden">
<span class="sparkline">3446,3446,3416,3416,3416,3546,3546,3546,3546,3546,3546,3561,3556,3551,3396,3396,3396,3346,3306,3306,3306</span>
</td>

我想我应该以某种方式捕捉鼠标在展开图标上的点击,然后重新注入画布,但我不知道如何做到这一点。

您可以使用以下方法将包含逗号分隔数字的每个字符串转换回数字数组:

for(i = 0; i < data.length; i++) {
data[i].last = data[i].last.split(",").map(element => {
return Number(element);
});
}

这将执行标准的split(),但它会在数组中为您提供字符串值。因此,我们还使用map()函数将每个作为字符串的mumber转换回一个数字。

这个放在哪里?

在问题中的代码中,它位于以下行之后:

data = stock_data;

这里有一个独立的演示:

$(document).ready(function() {
var stock_data = [
{
"name": "ACME Gadgets",
"symbol": "AGDTS",
"last": "2.57, 2.54, 2.54, 2.56, 2.57, 2.58, 2.59"
},
{
"name": "Spry Media Productions",
"symbol": "SPMP",
"last": "1.12, 1.11, 1.08, 1.08, 1.09, 1.11, 1.08"
},
{
"name": "Widget Emporium",
"symbol": "WDEMP",
"last": "3.40, 3.39, 3.46, 3.51, 3.50, 3.48, 3.49"
},
{
"name": "Sole Goodman",
"symbol": "SGMAN",
"last": "16.20, 16.40, 16.36, 16.35, 16.61, 16.46, 16.19"
},
{
"name": "Stanler Bits and Bobs",
"symbol": "SBIBO",
"last": "82.51, 83.47, 83.40, 83.68, 83.81, 83.29, 83.72"
}
];

let table = $('#example').DataTable({
ajax: function(dataSent, callback, settings) {
let data = this.api().ajax.json();
if(data == undefined) {
data = stock_data;
for(i = 0; i < data.length; i++) {
data[i].last = data[i].last.split(",").map(element => {
return Number(element);
});
}
} else {
data = data.data;
for(i = 0; i < data.length; i++) {
data[i].last.push(data[i].last.shift())
}
}
callback({data: data});
},
paging: false,
initComplete: function() {
let api = this.api();
setInterval(function() {
api.ajax.reload();
}, 5000);
},
drawCallback: function() {
$('.sparkline')
.map(function() {
return $('canvas', this).length ? null : this;
})
.sparkline('html', {
type: 'line',
width: '250px'
})
},
columns: [
{
data: 'name'
},
{
data: 'symbol'
},
{
data: null,
render: function(data, type, row, meta) {
return row.last[row.last.length - 1].toFixed(2);
}
},
{
data: null,
render: function(data, type, row, meta) {
var val = (row.last[row.last.length - 1] - row.last[row.last.length - 2]).toFixed(2);
var colour = val < 0 ? 'red' : 'green'
return type === 'display' ?
'<span style="color:' + colour + '">' + val + '</span>' :
val;
}
},
{
data: 'last',
render: function(data, type, row, meta) {
return type === 'display' ?
'<span class="sparkline">' + data.toString() + '</span>' :
data;
}
}
]
});
});
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>  

<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>
<body>
<div style="margin: 20px;">
<table id="example" class="display nowrap" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>Difference</th>
<th>Last</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>Difference</th>
<th>Last</th>
</tr>
</tfoot>
</table>
</div>
</body>
</html>


更新

关于评论:如果你真的使用以下作为你的真实数据源。。。

ajax: "api/ApartmentsAvailables"

那么您可以采用与上面相同的逻辑。

为此,您需要展开DataTablesajax选项以使用DataTablesdataSrc选项。使用此选项可以预处理从Ajax URL接收的JSON,并使用与我上面使用的基本相同的逻辑将这些逗号分隔的字符串转换回数字数组。

"ajax": {
"url": "api/ApartmentsAvailables",
"dataSrc": function ( json ) { // the JSON containing strings
// transform the received JSON here...

return json;  // the updated JSON containing arrays
}
}

如果您需要在转换JSON之前和之后仔细检查JSON的确切结构,则可以使用console.log( json )

我不知道您从URL接收到的JSON的结构,所以您可能需要调整我的原始代码以适应实际的JSON。尝试一下,如果你陷入困境,你可以问一个新问题——但Stack Overflow上有很多关于dataSrc的问题。

这是官方文件:ajax.dataSrc。正如您从上面的示例中看到的,您需要查看function语法的语法和示例。

stock_data[n].last.toSring();

n类似于元素的索引。

https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/toString

最新更新