Hi i have the following table to generate a json dataset
it has the following data i have script teh table
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
In my middle tier ASP MVC the controller converts this to the the following json (UPADATED TO HAVE A STRING 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"}];
i have used the following code to generate the grid using JqGrid free-grid. for easiness i have added the above json array to the data array
<!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>
the generated grid is shown below image link
i have so many questions relating to this grid. but i will post them one by one as answers progresses. But for now the following questions to start off with:
when i turned on teh grouping what happened to teh collapse icon image that should appear behind the group name? SOLVED: i have found the answer to this question, the missing font-awesome library caused the issue
How do i convert the json dates in teh dates columns and display them in actual dates?SOLVED:This issue was solved once i made the conversion in the middle tier to return saledate a string value
The Grid has two entries on the Toyota Corolla but this should be one entry and in that entry, totalnumofsales values should be placed on the two matching dates. AKA in a single row entry to toyota corolla 120000 in 2010-12-01 cell and 100000 in 2010-12-15
also teh fuel consuption value must be the first row value i.e. 10-14
for the cell that don't have values shows 0.00 instead of showing 0.00 i need them to display an empty cell
How do i turn off the automatic sorting of the grid becuase when grid is generated the groups names are sorted in the alphabetical order but i dont wont grid to sort them, instead keep their original order that comes from the backend
how do i acheive the above?
I think origin of your question are some common misunderstanding what is pivot table and how one can use it. I try to explain all below in details on an example of your input data.
You use the following input 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"
}]
Every item of data have many properties. Some properties contains different (or even unique) values (like id). Other properties should be grouped together and calculate some aggregation function on another properties on every item inside of the group. I explain the above statement on an example.
The input data contains sale information of some car models. It could be interesting, for example, to display the number of sales of every car model by date or by year etc.
Pivot tables contains three main parameters xDimension, yDimension and aggregates. For example, look at the following picture below
The left part (markt in orange) represents xDimension (make and model). It build mostly the rows of the grid. The right part (marked in blue) represents yDimension (year and month of the input items). The lowest level of the information on the right size contains the result of calculation of aggregate functions (max and count) on some input property (it was totalnumberofsales in the example).
If one defined only one aggregate function inside of aggregates parameter, then the name of aggregate function will be not displayed:
Now I have to display what jqPivot do to create jqGrid. First of all it scan all input data by all X and by Y parameters. If you define for example the following pivot model
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" }
]
then all data will be first scanned for the items having the same ["make", "model"] values in xDimension and by ["salesdate"] in yDimension. The input data has 6 elements with the indexes from 0 till 5. The resulting xIndexes and yIndexes contains unique values by x and y and the indexes of source data (from 0 till 5) to the items, which has the data. One can add the following lines after jqPivot call to see the indexes:
var p = $("#list483").jqGrid("getGridParam");
console.log(JSON.stringify(p.pivotOptions.xIndex));
console.log(JSON.stringify(p.pivotOptions.yIndex));
As the result one will see the demo https://jsfiddle.net/oadzsnov/. I include the resulting xIndex and yIndex below. xIndex is
{
"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]
}
yIndex is
{
"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]
}
The xIndex.items build the rows of the resulting pivot table and yIndex build the columns. You can see that the rows will be
["toyota", "corolla"],
["toyota", "belta"],
["toyota", "camry"],
["nissan", "skyline"],
["nissan", "zx300"]
and the columns:
["2012-01-06"],
["2011-04-23"],
["2011-01-10"],
["2010-12-15"],
["2010-12-01"],
["2010-09-10"]
One can see additionally that 2 elements of source data (see xIndex.indexesOfSourceData, which is [0, 1]) xIndex.items corresponds the same x-vector ["toyota", "corolla"]. The content of the pivot table (see yellow marked data on the first picture) will be the result of executing the specified aggregate function. We used
aggregates: [
{ member: "totalnumberofsales", aggregator: "max" }
]
and the source elements with the index 0 and 1 are
[{
...
"make": "toyota",
"model": "corolla",
...
"totalnumberofsales": 120000.0000,
...
"salesdate": "2010-12-01"
}, {
...
"make": "toyota",
"model": "corolla",
...
"totalnumberofsales": 100000.0000,
...
"salesdate": "2010-12-15"
}
The items have different y-vectors ("salesdate": "2010-12-01" for the first item and "salesdate": "2010-12-15" for the second one). Thus the calculation of aggregates will be very simple: 120000 in the column "2010-12-01", 100000 in the column "2010-12-15" and 0 for all other dates, because there are no ["toyota", "corolla"] sales at the day:
If you would assign separate salesYear and salesMonth properties based on the salesdate, then you can use
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"
}]
to create the pivot table. Both first source items has the same salesdate ("2010-12-15" and "2010-12-15"). The calculation of max aggregater over the both items get 120000, which one will see in the resulting grid
see https://jsfiddle.net/fa40onkz/
If you could follow me till the place, then you could understand any from effect, which you could see in the resulting pivot table.
For example, it's wrong to use
{/*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 }
in option of jqPivot, because two ["toyota", "corolla"] source items have different fuelusagecity, fuelusagehwy and highsalestext values. The salesaboveavg value is the same, but I suppose the usage of salesaboveavg is the same error. You should remove the items from xDimension.
To display empty cell in the cells with 0 value you can define column template
var myIntTemplate = {
formatter: "currency",
align: "right", sorttype: "number",
searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] },
formatoptions: { defaultValue: ""}};
and to use it in aggregates:
aggregates: [{
member: "cellvalue",
template: myIntTemplate,
aggregator: "max"
}]
You will get the results like
like on the demo https://jsfiddle.net/tnr2dgkv/
Your last question was about sorting. Sorting of source items is extremely important to create correct pivot table. You can use skipSortByX: true or/and skipSortByY: true options of jqPivot to suppress sorting of initial data, but the resulting data will be sorted once more if you use grouping (groupField: ["x0"]). I think that the simplest way (but it's still not so simple in the implementation) to hold the order of resulting items would be by defining custom sorting functions for xDimension items. I recommend you to read the wiki article for more information.
Related
I am looking for a way to display the numeric value 0 in a dropdown list that also includes placeholder text when the cell is empty. Currently, if 0 is selected the placeholder text shows through. I'm hoping for a built-in option and I'd like to avoid casting the number to string and back if I can (that would tear up my current validation scheme). The following example is modified from the HandsOnTable dropdown docs. The 'Chassis Color' column contains the issue.
jsfiddle:
https://jsfiddle.net/y3pL0vjq/
snippet:
function getCarData() {
return [
["Tesla", 2017, "black", "black"],
["Nissan", 2018, "blue", "blue"],
["Chrysler", 2019, "yellow", "black"],
["Volvo", 2020, "white", "gray"]
];
}
var
container = document.getElementById('example1'),
hot;
hot = new Handsontable(container, {
data: getCarData(),
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
columns: [
{},
{type: 'numeric'},
{
type: 'dropdown',
placeholder: "blah",
source: [null, 0, 1, 2, 3]
},
{
type: 'dropdown',
source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white']
}
]
});
The best way I found to handle this dropdown list of numbers is to omit the "type" attribute and specify the editor and validator as 'autocomplete. Then make a custom renderer to merge the NumericRenderer functionality with the autocomplete dropdown list.
To finalize the similar look and feel of the native dropdown function, you then add "strict: true" and "filter: false", as explained in the dropdown docs.
Internally, cell {type: "dropdown"} is equivalent to cell {type: "autocomplete", strict: true, filter: false}.
Dropdown Docs
Example:
function getCarData() {
return [
["Tesla", 2017, null, "black"],
["Nissan", 2018, 0, "blue"],
["Chrysler", 2019, 1, "black"],
["Volvo", 2020, 2, "gray"]
];
}
var
container = document.getElementById('example1'),
hot;
function myRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.NumericRenderer.apply(this, arguments);
td.innerHTML += '<div class="htAutocompleteArrow">▼</div>'
}
hot = new Handsontable(container, {
data: getCarData(),
colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
columns: [
{},
{type: 'numeric'},
{
editor: 'autocomplete',
validator: 'autocomplete',
renderer: myRenderer,
strict: true,
filter: false,
placeholder: "blah",
source: [null, 0, 1, 2, 3]
},
{
type: 'dropdown',
source: ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white']
}
]
});
Tabulator doesn't accept bottomCalcFormatter in column definition
My Tabulator table works pretty well and I can successfully add bottomCalc and formatter, but I can't seem to add bottomCalcFormatter. so I have a column of money with formatter:"money" and a bottomCalc:"sum" but the sum is not formatted as money. If I try to add bottomCalcFormatter:"money" the table doesn't render.
This renders although the sum is not in a "money" format:
columns:[
{title:0, titleFormatter:closeButton},
{title:"Revision#", field:"revNum", sorter:"number", align:"center", formatter:revisionDoc, formatterParams:{urlField:"hyperlink"}},
{formatter:pdfIcon, align:"center", formatterParams:{urlField:"hyperlink"}},
{title:"TO Amount", field:"toAmount", sorter:"number", formatter:"money", align:"right", bottomCalc:"sum"},
{title:"Adjusted", field:"adjusted", align:"right", formatter:"money", bottomCalc:"sum"},
],
This table does not render at all:
columns:[
{title:0, titleFormatter:closeButton},
{title:"Revision#", field:"revNum", sorter:"number", align:"center", formatter:revisionDoc, formatterParams:{urlField:"hyperlink"}},
{formatter:pdfIcon, align:"center", formatterParams:{urlField:"hyperlink"}},
{title:"TO Amount", field:"toAmount", sorter:"number", formatter:"money", align:"right", bottomCalc:"sum"},
{title:"Adjusted", field:"adjusted", align:"right", formatter:"money", bottomCalc:"sum", bottomCalcFormatter:"money"},
],
I just checked the Tabulator.js there is an additional parameter
bottomCalcFormatterParams
Check this code it sums currency and the calculation shows $ sign
<!DOCTYPE html>
<html lang="en">
<head><link href="https://unpkg.com/tabulator-tables#4.2.4/dist/css/tabulator.min.css" rel="stylesheet"></head>
<body>
<div id="example-table"></div>
<script
src="https://code.jquery.com/jquery-3.4.0.min.js"
integrity="sha256-BJeo0qm959uMBGb65z40ejJYGSgR7REI4+CW1fNKwOg="
crossorigin="anonymous"></script>
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.2.4/dist/js/tabulator.min.js"></script>
<script>
const tabledata = [
{id: 1, name: "Oli Bob", money: "12", col: "red", dob: ""},
{id: 2, name: "Mary May", money: "1", col: "blue", dob: "14/05/1982"},
{id: 3, name: "Christine Lobowski", money: "42", col: "green", dob: "22/05/1982"},
{id: 4, name: "Brendon Philips", money: "125", col: "orange", dob: "01/08/1980"},
{id: 5, name: "Margret Marmajuke", money: "16", col: "yellow", dob: "31/01/1999"},
];
const table = new Tabulator("#example-table", {
height: 205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
data: tabledata, //assign data to table
layout: "fitColumns", //fit columns to width of table (optional)
columns: [ //Define Table Columns
{title: "Name", field: "name", width: 150},
{
title: "money",
field: "money",
align: "left",
formatter: "money",
bottomCalc: "sum",
bottomCalcParams: {
precision: 3
},
bottomCalcFormatter: "money",
bottomCalcFormatterParams: {
decimal: ".",
thousand: ",",
symbol: "$"
},
formatterParams: {
decimal: ".",
thousand: ",",
symbol: "$"
}
},
{title: "Favourite Color", field: "col"},
{title: "Date Of Birth", field: "dob", sorter: "date", align: "center"},
]
});
</script>
</body>
</html>
Am Chart showing incorrectly, Here is following ajax code, incorrect thumb of chart.
I am using ajax to get the response and initialized the amchart (area)
Ajax json response data
{"success":true,"graph_data":[{"date":"2018-06-21","value":121.65},{"date":"2018-06-20","value":121.65},{"date":"2018-06-19","value":121.5},{"date":"2018-06-18","value":121.3},{"date":"2018-06-17","value":120.55},{"date":"2018-06-16","value":119.84},{"date":"2018-06-14","value":119.88}],"min_period":"DD","message":null}
Here code which I am initializing for amchart
var chart = AmCharts.makeChart( "graph_chart_div", {
"type": "serial",
"theme": "light",
"marginRight": 5,
"marginLeft": 5,
"minPeriod":response.min_period,
"autoMarginOffset": 5,
"dataDateFormat": "YYYY-MM-DD",
"valueAxes": [ {
"id": "v1",
"axisAlpha": 0,
"position": "left",
"ignoreAxisWidth": true
} ],
"balloon": {
"borderThickness": 1,
"shadowAlpha": 0
},
"graphs": [ {
"id": "g1",
"balloon": {
"drop": true,
"adjustBorderColor": false,
"color": "#ffffff",
"type": "smoothedLine"
},
"fillAlphas": 0.2,
"bullet": "round",
"bulletBorderAlpha": 1,
"bulletColor": "#FFFFFF",
"bulletSize": 5,
"hideBulletsCount": 50,
"lineThickness": 2,
"title": "red line",
"useLineColorForBulletBorder": true,
"valueField": "value",
"balloonText": "<span style='font-size:18px;'>[[value]]</span>"
} ],
"chartCursor": {
"valueLineEnabled": true,
"valueLineBalloonEnabled": true,
"cursorAlpha": 0,
"zoomable": false,
"valueZoomable": true,
"valueLineAlpha": 0.5
},
"valueScrollbar": {
"autoGridCount": true,
"color": "#000000",
"scrollbarHeight": 50
},
"categoryField": "date",
"categoryAxis": {
"gridPosition": "start",
"labelRotation": 45,
"minorGridEnabled": true,
/* ENSURE 2 LINES BELOW ARE ADDED */
"autoGridCount": false,
"gridCount": 12,
"parseDates": true,
"dashLength": 1,
// "minorGridEnabled": true
},
"export": {
"enabled": false
},
// "dataProvider": graph_data
"dataProvider": response.graph_data
} );
This is currently initialized chart
I want to show the following chart for my data
Your date data is out of order. AmCharts requires your date-based data to be in date-ascending order when using parseDates.
Important: If this is set to true, the data points needs to come pre-ordered in ascending order. Data with incorrect order might result in visual and functional glitches on the chart.
Once you fix the sort order, your chart will render correctly.
I used the solution mentioned in How to update value of data in jqgrid to update data locally. It worked for me as shown in the first fiddle. In the "Action" column, there is button added conditionally, based on the data in "IsActive" column. If it is "true", a "Retire" button gets added as an action. If it is false, "Activate" button gets added. When the javascript function is called, the button changes to "Activate".
Fiddle 1
Now, I added another column to display the status value as text. Now, both "Status" column and "Action" column are utilizing the same data column - IsActive. After adding this column, the javascript function is not changing the button from "Retire" to "Activate".
Fiddle 2
What is the best way to fix this issue?
CODE
$(document).ready(function () {
function updateActiveStatus(rowid, isToActive) {
alert('function');
// first change the cell in the visible part of grid
$("#list").jqGrid('setCell', rowid, 'firstname', 'A');
// now change the internal local data
$("#list").jqGrid('getLocalRow', rowid).firstname = 'A';
$("#list").jqGrid('setCell', rowid, 'IsActive', false);
$("#list").jqGrid('getLocalRow', rowid).IsActive = false;
}
var myData = [
{ "id": "35", "firstname": null, "codeval": "G", "note": "xx7866", "amount": "23", "IsActive": true },
{ "id": "73", "firstname": null, "codeval": "W", "note": "dd1047", "amount": "34", "IsActive": true },
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323", "amount": "56", "IsActive": true },
{ "id": "95", "firstname": "EST", "codeval": "M", "note": "gg574", "amount": "55", "IsActive": true }
],
myGrid = $("#list");
myGrid.jqGrid({
datatype:'local',
data: myData,
colNames: ['ID', 'FirstName', 'Code', 'Amount', 'Note', 'Action'],
colModel:[
{name:'id',width:70,align:'center',sorttype: 'int'},
{name:'firstname',width:80, align:'center'},
{ name: 'codeval', width: 70 },
{name:'amount',width:100, formatter:'number'},
{name:'note',index:'note',width:100,sortable:false},
{
name: 'IsActive',
width: 100,
formatter: function (cellvalue, options, rowObject) {
if (cellvalue == true) {
return '<div style="padding-left:5px;"><button class="ui-button ui-widget ui-state-default app-custom-button-retire" >' +
'<span title="" class="ui-button-icon-primary ui-icon ui-icon-scissors"></span>Retire' +
'</button></div>';
}
else {
return '<div style="padding-left:5px;"><button class="ui-button ui-widget ui-state-default app-custom-button-activate" >' +
'<span title="" class="ui-button-icon-primary ui-icon ui-icon-check"></span>Activate' +
'</button></div>';
}
}
}
],
rowNum:10,
pager: '#pager',
gridview:true,
ignoreCase:true,
rownumbers:true,
viewrecords: true,
sortorder: 'desc',
height: '100%',
beforeSelectRow: function (rowid, e) {
var $self = $(this),
$td = $(e.target).closest("tr.jqgrow>td"),
rowid = $td.parent().attr("id"),
//rowData = $self.jqGrid("getLocalRow", rowid),
rowData = $self.jqGrid("getRowData", rowid)
iCol = $td.length > 0 ? $td[0].cellIndex : -1,
colModel = $self.jqGrid("getGridParam", "colModel");
celValue = $self.jqGrid('getCell', rowid, 'FirstName');
if (iCol >= 0 && colModel[iCol].name === "IsActive") {
if ($(e.target).hasClass("app-custom-button-retire")) {
updateActiveStatus(rowid,false);
return false;
}
if ($(e.target).hasClass("app-custom-button-activate")) {
updateActiveStatus(rowid, true);
return false;
}
}
//Avoid selection of row
return false;
}
});
myGrid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn" });
});
I seem multiple misunderstanding in your code. First of all you have some source data, which are the array of item. Every item is object with multiple properties, like:
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323",
"amount": "56", "IsActive": true }
or, which is the same,
{ id: "75", firstname: "LORA", codeval: "H", note: "rr7323",
amount: "56", IsActive: true }
It should be clear that such item can't have multiple properties with the same name. The object
{ "id": "75", "firstname": "LORA", "codeval": "H", "note": "rr7323",
"amount": "56", "IsActive": true, "IsActive": true }
would be wrong even if some web browser could ignore the error. Even if you specify the same value true for both "IsActive" properties.
In the same way you can't use colModel with multiple columns with the same name property. Your second demo https://jsfiddle.net/LijoCheeran/rqab1veh/11/ have two columns with the same property name: 'IsActive'. It's wrong. You can fix the code by usage, for example, name: 'IsActive1' in the second column. The formatter of IsActive1 can use rowObject.IsActive instead of cellvalue to access to the required data. The corresponding code will be the follwing
{
name: 'IsActive1',
width: 75,
formatter: function (cellvalue, options, rowObject) {
return rowObject.IsActive == true ? 'Active' : 'Retired';
}
},
{
name: 'IsActive',
width: 100,
formatter: function (cellvalue, options, rowObject) {
return cellvalue == true ? retireButton : activeButton;
}
}
where retireButton and activeButton contains HTML fragments of the buttons.
Now it's important to understand, that jqGrid hold the data array. The method $("#list").jqGrid('getLocalRow', rowid) get you the reference to the data item which corresponds the data of the row. The method getRowData will get the data from HTML representation of the cells (from <td> elements) and unformat there. The type of the fields of returned object will be strings.
Because you need to update not only the data, but the cell content of firstname, IsActive1 and IsActive columns then you have to call setCell on every the field or better call one setRowData:
function updateActiveStatus (rowid, isToActive) {
alert('calling the function');
$("#list").jqGrid('setRowData', rowid, {
firstname: 'A',
IsActive1: false,
IsActive: false
});
var item = $("#list").jqGrid('getLocalRow', rowid);
// delete unneeded IsActive1 property created in the item
delete item.IsActive1;
}
The only small disadvantage of the setRowData call is creating new property IsActive1 in the item of data. Old jqGrid 4.6 have no possibility to save the data "virtually" in some another place as the item.IsActive1. Free jqGrid allows to specify saveLocally callback, which can make custom "saving" of the data of the column in the local item. It's not real large problem in your case and you need just delete unneeded property by delete item.IsActive1
You can see the results on the modified demo https://jsfiddle.net/OlegKi/rqab1veh/12/
I'm using jqGrid with the jqPivot API.
The problem I'm encountering is that jqPivot removes the spaces from the pivoted column names. Is there any way to change this behaviour?
eg.
var mydata = [
{id: "1", emp:"Michelle", product:"A A", sold:"8"},
{id: "2", emp:"Tania", product:"A A", sold:"3"},
{id: "6", emp:"Mark", product:"A B", sold:"1"},
{id: "3", emp:"Tommy", product:"A B", sold:"5"},
{id: "4", emp:"Dave", product:"B B", sold:"2"},
{id: "5", emp:"Carol", product:"B B", sold:"5"},
];
var grid = $("#grid");
grid.jqGrid('jqPivot',
mydata, {
xDimension: [{
dataName: 'id',
label: 'ID',
width: 90
}, {
dataName: 'emp',
label: 'Employee',
width: 90
}, ],
yDimension: [{
dataName: 'product'
}],
aggregates: [{
member: 'sold',
aggregator: 'sum',
width: 50,
label: 'Sold'
}, ],
colTotals: true
}, {
width: "100%",
height: "100%",
pager: "#pager",
caption: "Daily Sales"
});
http://jsfiddle.net/aUDHx/968/
Instead of "A A" and "A B" etc. it displays the columns as "AA" and "AB".
I agree that it's a problem. The reason is the line of jqPivot code. As a quick and dirty workaround I could suggest you to use converter which replace the space to some other character like _, ( ) or .
yDimension: [{
dataName: 'product',
converter: function (val) {return val.replace(/\s/g, ' ');}
}],
See the modified demo http://jsfiddle.net/OlegKi/aUDHx/970/.