1

嗨,我有下表来生成 json 数据集

数据库表设计

它有以下数据我有脚本表

USE [GridSamples]
GO
/****** Object:  Table [dbo].[SalesStats]    Script Date: 12/13/2016 07:34:51 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[SalesStats](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [makes] [nchar](10) NOT NULL,
    [models] [nchar](10) NOT NULL,
    [fuelusagecity] [nchar](10) NOT NULL,
    [fuelusagehwy] [nchar](10) NOT NULL,
    [salesaboveavg] [bit] NOT NULL,
    [totalnumofsales] [money] NOT NULL,
    [highsalestext] [varchar](50) NULL,
    [saledate] [date] NOT NULL,
 CONSTRAINT [PK_SalesStats] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[SalesStats] ON 

GO
INSERT [dbo].[SalesStats] ([id], [makes], [models], [fuelusagecity], [fuelusagehwy], [salesaboveavg], [totalnumofsales], [highsalestext], [saledate]) VALUES (1, N'toyota    ', N'corolla   ', N'17        ', N'12        ', 0, 120000.0000, NULL, CAST(0x9A330B00 AS Date))
GO
INSERT [dbo].[SalesStats] ([id], [makes], [models], [fuelusagecity], [fuelusagehwy], [salesaboveavg], [totalnumofsales], [highsalestext], [saledate]) VALUES (2, N'toyota    ', N'corolla   ', N'10        ', N'14        ', 0, 100000.0000, N'HIGH', CAST(0xA8330B00 AS Date))
GO
INSERT [dbo].[SalesStats] ([id], [makes], [models], [fuelusagecity], [fuelusagehwy], [salesaboveavg], [totalnumofsales], [highsalestext], [saledate]) VALUES (3, N'toyota    ', N'belta     ', N'15        ', N'10        ', 1, 200000.0000, NULL, CAST(0xC2330B00 AS Date))
GO
INSERT [dbo].[SalesStats] ([id], [makes], [models], [fuelusagecity], [fuelusagehwy], [salesaboveavg], [totalnumofsales], [highsalestext], [saledate]) VALUES (4, N'toyota    ', N'camry     ', N'13        ', N'10        ', 0, 300000.0000, N'HIGH', CAST(0x29340B00 AS Date))
GO
INSERT [dbo].[SalesStats] ([id], [makes], [models], [fuelusagecity], [fuelusagehwy], [salesaboveavg], [totalnumofsales], [highsalestext], [saledate]) VALUES (5, N'nissan    ', N'skyline   ', N'14        ', N'9         ', 1, 500000.0000, N'HIGH', CAST(0x48330B00 AS Date))
GO
INSERT [dbo].[SalesStats] ([id], [makes], [models], [fuelusagecity], [fuelusagehwy], [salesaboveavg], [totalnumofsales], [highsalestext], [saledate]) VALUES (6, N'nissan    ', N'zx300     ', N'10        ', N'8         ', 0, 400000.0000, NULL, CAST(0x2B350B00 AS Date))
GO
SET IDENTITY_INSERT [dbo].[SalesStats] OFF
GO

在我的中间层 ASP MVC 中,控制器将其转换为以下 json (更新为有一个字符串 SalesDate)

var data = [{"id":1,"make":"toyota","model":"corolla","fuelusagecity":"17","fuelusagehwy":"12","salesaboveavg":false,"totalnumberofsales":120000.0000,"highsalestext":null,"salesdate":"2010-12-01"},{"id":2,"make":"toyota","model":"corolla","fuelusagecity":"10","fuelusagehwy":"14","salesaboveavg":false,"totalnumberofsales":100000.0000,"highsalestext":"HIGH","salesdate":"2010-12-15"},{"id":3,"make":"toyota","model":"belta","fuelusagecity":"15","fuelusagehwy":"10","salesaboveavg":true,"totalnumberofsales":200000.0000,"highsalestext":null,"salesdate":"2011-01-10"},{"id":4,"make":"toyota","model":"camry","fuelusagecity":"13","fuelusagehwy":"10","salesaboveavg":false,"totalnumberofsales":300000.0000,"highsalestext":"HIGH","salesdate":"2011-04-23"},{"id":5,"make":"nissan","model":"skyline","fuelusagecity":"14","fuelusagehwy":"9","salesaboveavg":true,"totalnumberofsales":500000.0000,"highsalestext":"HIGH","salesdate":"2010-09-10"},{"id":6,"make":"nissan","model":"zx300","fuelusagecity":"10","fuelusagehwy":"8","salesaboveavg":false,"totalnumberofsales":400000.0000,"highsalestext":null,"salesdate":"2012-01-06"}];

我使用以下代码使用 JqGrid free-grid 生成网格。为方便起见,我已将上述json数组添加到data数组中

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>

    <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/south-street/jquery-ui.css" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/free-jqgrid/4.13.5/css/ui.jqgrid.min.css" />
</head>
<body>

<table id="list483"></table>
<div id=""></div>

<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<!--<script src="https://cdn.jsdelivr.net/free-jqgrid/4.13.5/js/i18n/grid.locale-de.min.js"></script>-->
<script src="https://cdn.jsdelivr.net/free-jqgrid/4.13.5/js/jquery.jqgrid.min.js"></script>
<script>

var data = [{"id":1,"make":"toyota","model":"corolla","fuelusagecity":"17","fuelusagehwy":"12","salesaboveavg":false,"totalnumberofsales":120000.0000,"highsalestext":null,"salesdate":"2010-12-01"},{"id":2,"make":"toyota","model":"corolla","fuelusagecity":"10","fuelusagehwy":"14","salesaboveavg":false,"totalnumberofsales":100000.0000,"highsalestext":"HIGH","salesdate":"2010-12-15"},{"id":3,"make":"toyota","model":"belta","fuelusagecity":"15","fuelusagehwy":"10","salesaboveavg":true,"totalnumberofsales":200000.0000,"highsalestext":null,"salesdate":"2011-01-10"},{"id":4,"make":"toyota","model":"camry","fuelusagecity":"13","fuelusagehwy":"10","salesaboveavg":false,"totalnumberofsales":300000.0000,"highsalestext":"HIGH","salesdate":"2011-04-23"},{"id":5,"make":"nissan","model":"skyline","fuelusagecity":"14","fuelusagehwy":"9","salesaboveavg":true,"totalnumberofsales":500000.0000,"highsalestext":"HIGH","salesdate":"2010-09-10"},{"id":6,"make":"nissan","model":"zx300","fuelusagecity":"10","fuelusagehwy":"8","salesaboveavg":false,"totalnumberofsales":400000.0000,"highsalestext":null,"salesdate":"2012-01-06"}];


    $("#list483").jqGrid("jqPivot",
            data,
            {
                frozenStaticCols: true,
                xDimension: [
                    {/*x0*/ dataName: "make", width: 200, label: "Make" },
                    {/*x1*/ dataName: "model", skipGrouping: true },
                    {/*x2*/ dataName: "fuelusagecity", hidden: true, skipGrouping: true },
                    {/*x3*/ dataName: "fuelusagehwy", width: 80, align: "center",
                        label: "fuel consumption", skipGrouping: true,
                        formatter: function (cellvalue, options, rowObject) {
                            return rowObject.x2 === null || rowObject.x3 === null ?
                                    "-" :
                            String(rowObject.x2) + "-" + String(cellvalue);
                        }
                    },
                    {/*x4*/ dataName: "salesaboveavg", hidden: true, width: 50, align: "center", skipGrouping: true },
                    {/*x5*/ dataName: "highsalestext", hidden: true, skipGrouping: true }
                ],
                yDimension: [
                    {/*y0*/    dataName: "salesdate",
                    sorttype: "date",
                        formatter: function (cellvalue, options, rowObject) {
                        //var x = rawObject.y0;
                        console.log(rowObject);
//                            return rowObject;
                    }
                }],
                aggregates: [{
                    member: "totalnumberofsales",
                    aggregator: "max"
                }]
            },
// grid options
            {
                iconSet: "fontAwesome",
                cmTemplate: { autoResizable: true, width: 90 },
                shrinkToFit: false,
                useUnformattedDataForCellAttr: false,
                autoResizing: { compact: true },
                groupingView: {
                    groupField: ["x0"],
                    groupColumnShow: [false],
                    groupText: ['<b>{0}</b>']
                },
                width: 450,
                pager: true,
                rowNum: 20,
                rowList: [5, 10, 20, 100, "10000:All"],
                caption: "<b>Car sales statistics</b>"
            }
    );
</script>

</body>
</html>

生成的网格如下图链接所示

在此处输入图像描述

我有很多关于这个网格的问题。但随着答案的进展,我会一一发布。但现在要从以下问题开始:

  1. 当我打开分组时,应该出现在组名后面的折叠图标图像发生了什么?已解决:我找到了这个问题的答案,缺少的 font-awesome 库导致了这个问题

  2. 如何转换日期列中的 json 日期并在实际日期中显示它们?已解决:一旦我在中间层进行转换以返回 saledate 一个字符串值,这个问题就解决了

  1. 网格在 Toyota Corolla 上有两个条目,但这应该是一个条目,并且在该条目中,totalnumofsales值应该放在两个匹配的日期上。120000AKA在2010-12-01单元格100000中的 toyota corolla 的单行条目中以及2010-12-15 燃料消耗值必须是第一行值,即 10-14

  2. 对于没有值的单元格显示 0.00 而不是显示 0.00 我需要它们显示一个空单元格

  3. 我如何关闭网格的自动排序,因为生成网格时,组名称按字母顺序排序,但我不会使用网格对它们进行排序,而是保留来自后端的原始顺序

我如何实现上述目标?

4

1 回答 1

1

我认为您的问题的起源是一些常见的误解,什么是数据透视表以及如何使用它。我尝试在下面的输入数据示例中详细解释所有内容。

您使用以下输入数据:

[{
    "id": 1,
    "make": "toyota",
    "model": "corolla",
    "fuelusagecity": "17",
    "fuelusagehwy": "12",
    "salesaboveavg": false,
    "totalnumberofsales": 120000.0000,
    "highsalestext": null,
    "salesdate": "2010-12-01"
}, {
    "id": 2,
    "make": "toyota",
    "model": "corolla",
    "fuelusagecity": "10",
    "fuelusagehwy": "14",
    "salesaboveavg": false,
    "totalnumberofsales": 100000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2010-12-15"
}, {
    "id": 3,
    "make": "toyota",
    "model": "belta",
    "fuelusagecity": "15",
    "fuelusagehwy": "10",
    "salesaboveavg": true,
    "totalnumberofsales": 200000.0000,
    "highsalestext": null,
    "salesdate": "2011-01-10"
}, {
    "id": 4,
    "make": "toyota",
    "model": "camry",
    "fuelusagecity": "13",
    "fuelusagehwy": "10",
    "salesaboveavg": false,
    "totalnumberofsales": 300000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2011-04-23"
}, {
    "id": 5,
    "make": "nissan",
    "model": "skyline",
    "fuelusagecity": "14",
    "fuelusagehwy": "9",
    "salesaboveavg": true,
    "totalnumberofsales": 500000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2010-09-10"
}, {
    "id": 6,
    "make": "nissan",
    "model": "zx300",
    "fuelusagecity": "10",
    "fuelusagehwy": "8",
    "salesaboveavg": false,
    "totalnumberofsales": 400000.0000,
    "highsalestext": null,
    "salesdate": "2012-01-06"
}]

每一项数据都有许多属性。一些属性包含不同的(甚至是唯一的)值(如id)。其他属性应该组合在一起,并在组内每个项目的其他属性上计算一些聚合函数。我以一个例子来解释上述陈述。

输入数据包含一些车型的销售信息。例如,按日期或年份等显示每种车型的销售数量可能会很有趣。

数据透视表包含三个主要参数xDimensionyDimensionaggregates。例如,看下面这张图 在此处输入图像描述 ,左边部分(橙色标记)代表xDimensionmakemodel)。它主要构建网格的行。右侧部分(标记为蓝色)表示输入项的yDimension(year和)。month正确大小的信息的最低级别包含对某些输入属性(在示例中)的聚合函数 (max和) 的计算结果。counttotalnumberofsales

如果在参数中只定义了一个聚合函数aggregates,那么聚合函数的名称将不会显示: 在此处输入图像描述

现在我必须显示 jqPivot 为创建 jqGrid 所做的工作。首先,它通过所有 X 和 Y 参数扫描所有输入数据。例如,如果您定义以下枢轴模型

xDimension: [
    { dataName: "make", width: 100, label: "Make" },
    { dataName: "model", width: 100, label: "Model", align: "center" }
],
yDimension: [
    { dataName: "salesdate", sortorder: "desc" }
],
aggregates: [
    { member: "totalnumberofsales", aggregator: "max" }
]

然后将首先扫描所有数据以查找in和 by具有相同["make", "model"]值的项目。输入数据有 6 个元素,索引从 0 到 5。生成的 xIndexes 和 yIndexes 包含 x 和 y 的唯一值以及源数据(从 0 到 5)到具有数据的项目的索引。可以在 jqPivot 调用后添加以下行以查看索引:xDimension["salesdate"]yDimension

var p = $("#list483").jqGrid("getGridParam");
console.log(JSON.stringify(p.pivotOptions.xIndex));
console.log(JSON.stringify(p.pivotOptions.yIndex));

结果将看到演示https://jsfiddle.net/oadzsnov/。我在下面包含了生成的 xIndex 和 yIndex。xIndex 是

{
    "items": [
        ["toyota", "corolla"],
        ["toyota", "belta"],
        ["toyota", "camry"],
        ["nissan", "skyline"],
        ["nissan", "zx300"]
    ],
    "indexesOfSourceData": [
        [0, 1],
        [2],
        [3],
        [4],
        [5]
    ],
    "trimByCollect": true,
    "caseSensitive": false,
    "skipSort": true,
    "fieldLength": 2,
    "fieldNames": ["make", "model"],
    "fieldSortDirection": [1, 1],
    "fieldCompare": [null, null]
}

y索引是

{
    "items": [
        ["2012-01-06"],
        ["2011-04-23"],
        ["2011-01-10"],
        ["2010-12-15"],
        ["2010-12-01"],
        ["2010-09-10"]
    ],
    "indexesOfSourceData": [
        [5],
        [3],
        [2],
        [1],
        [0],
        [4]
    ],
    "trimByCollect": true,
    "caseSensitive": false,
    "skipSort": false,
    "fieldLength": 1,
    "fieldNames": ["salesdate"],
    "fieldSortDirection": [-1],
    "fieldCompare": [null]
}

xIndex.items构建生成的数据透视表的行并构建yIndex列。您可以看到行将是

["toyota", "corolla"],
["toyota", "belta"],
["toyota", "camry"],
["nissan", "skyline"],
["nissan", "zx300"]

和列:

["2012-01-06"],
["2011-04-23"],
["2011-01-10"],
["2010-12-15"],
["2010-12-01"],
["2010-09-10"]

还可以看到源数据的 2 个元素(参见xIndex.indexesOfSourceData,即[0, 1]xIndex.items对应于相同的 x 向量["toyota", "corolla"]。数据透视表的内容(见第一张图中黄色标记的数据)将是执行指定聚合函数的结果。我们用了

aggregates: [
    { member: "totalnumberofsales", aggregator: "max" }
]

索引为 0 和 1 的源元素是

[{
    ...
    "make": "toyota",
    "model": "corolla",
    ...
    "totalnumberofsales": 120000.0000,
    ...
    "salesdate": "2010-12-01"
}, {
    ...
    "make": "toyota",
    "model": "corolla",
    ...
    "totalnumberofsales": 100000.0000,
    ...
    "salesdate": "2010-12-15"
}

这些项目有不同的 y 向量"salesdate": "2010-12-01"第一个项目和"salesdate": "2010-12-15"第二个项目)。因此,聚合的计算将非常简单:120000在 column "2010-12-01"100000在 column"2010-12-15"和所有其他日期,因为当天0没有销售:["toyota", "corolla"]

在此处输入图像描述

如果您要基于分配单独 salesYear的和属性,那么您可以使用salesMonthsalesdate

xDimension: [
    { dataName: "make", width: 100, label: "Make" },
    { dataName: "model", width: 100, label: "Model", align: "center" }
],
yDimension: [
    { dataName: "salesYear", sorttype: "integer" },
    { dataName: "salesMonth", sorttype: "integer" }
],
aggregates: [{
    member: "totalnumberofsales",
    aggregator: "max"
}]

创建数据透视表。两个第一个源项具有相同的salesdate("2010-12-15""2010-12-15")。max对两项 get的聚合器计算,120000将在生成的网格中看到

在此处输入图像描述

https://jsfiddle.net/fa40onkz/

如果你能跟着我直到那个地方,那么你可以理解任何效果,你可以在生成的数据透视表中看到。

例如使用是错误的

{/*x2*/ dataName: "fuelusagecity", hidden: true, skipGrouping: true },
{/*x3*/ dataName: "fuelusagehwy", width: 80, align: "center",
    label: "fuel consumption", skipGrouping: true,
    formatter: function (cellvalue, options, rowObject) {
        return rowObject.x2 === null || rowObject.x3 === null ?
                "-" :
        String(rowObject.x2) + "-" + String(cellvalue);
    }
},
{/*x4*/ dataName: "salesaboveavg", hidden: true, width: 50, align: "center", skipGrouping: true },
{/*x5*/ dataName: "highsalestext", hidden: true, skipGrouping: true }

在 jqPivot 选项中,因为两个["toyota", "corolla"]源项具有不同 fuelusagecity的 ,fuelusagehwyhighsalestext值。该salesaboveavg值是相同的,但我想使用salesaboveavg是相同的错误。您应该从中删除项目xDimension

要在具有值的单元格中显示空单元格,0您可以定义列模板

var myIntTemplate = {
    formatter: "currency",
    align: "right", sorttype: "number",
    searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] },
    formatoptions: { defaultValue: ""}};

并将其用于aggregates

aggregates: [{
    member: "cellvalue",
    template: myIntTemplate,
    aggregator: "max"
}]

你会得到类似的结果 在此处输入图像描述

就像在演示https://jsfiddle.net/tnr2dgkv/

你的最后一个问题是关于排序的。源项目的排序对于创建正确的数据透视表非常重要。您可以使用jqPivot 的skipSortByX: trueor/and选项来禁止对初始数据进行排序,但如果您使用分组 ( ) skipSortByY: true,则结果数据将再次排序。groupField: ["x0"]我认为保持结果项目顺序的最简单方法(但在实现中仍然不是那么简单)是为项目定义自定义排序函数xDimension。我建议您阅读wiki 文章以获取更多信息。

于 2016-12-25T22:20:56.240 回答