dojo dgrid custom render cell contents - javascript

I'm using a dgrid but find the documentation available from the website (http://dojofoundation.org/packages/dgrid/) a bit lacking: it teaches you the basics but seems to leave you to work out how to do anything more complex by guesswork.
Specifically, I want to modify how the data I've loaded into a memory store is rendered. For example, I'd actually like to combine two columns from the store into one column in the grid with some additional text. Obviously one way would be to create a second memory store, iterate the first store and build the exact contents the dgrid should show in the second store. However, that feels clunky and like having to have two sets of the same data, just differently formated.
I can see there are renderRow and renderCell methods. Can anyone give me examples of how to use these, or point me to some documentation?
Thanks,
Simon

The renderCell function gives you the data object, so you can build the cell using any properties from the data.
var columns = [
{
label : ' ',
field : 'complexCell',
renderCell: function(object, value, node, options) {
domHtml.set(node, object[propA] + ' (' + object[propB] + ')');
}
},
...
];

Related

How do you filter Tabulator data on a class

I'm wondering if it's possible to set a filter to filter rows against a class rather than actual table data (so for instance only show rows where a particular class is present)? If so would this have to be a custom filter or can I use the standard filter operators?
FYI I'm using Tabulator v3.5. Any examples would be much appreciated :-)
Thanks for the reply Oli.
I've implemented mutators to define a few new properties as per your suggestion but I've got another problem of how to remove a filter for a particular property without using clearFilter which as I understand it clears ALL active filters? I've tried removeFilter but this doesn't seem to work.
For example (when checkbox is ticked):
if (chk) {
$("#allocations-table").tabulator("setFilter", "Allocated", "=", "is-allocated");
} else {
$("#allocations-table").tabulator("removeFilter", "Allocated", "=", "is-allocated");
}
Trying to filter a row based on class would be a bit of an anti-pattern when it comes to using Tabulator because you would have to use a formatter to apply the class in the first place, at which point you might as well set a property on the row and then filter things the normal way.
The correct approach would be to create a hidden column that uses a mutator to define a new property on the row, lets call it class, then you use a row formatter to apply this to the row, and then you can filter it as normal.
So lets start by creating our mutator, im going to add some arbitrary logic in this to set a class based on the value of another column (lets say age):
var classMutator = function(value, data){
if(data.age >= 18){
return "is-adult";
}else{
return "is-child";
}
}
Then we want to add that to a column definition, for a hidden column that uses this mutator:
{field:"class", mutator:classMutator, visible:false},
Then we will need a row formatter to apply that class to the row:
rowFormatter:function (row){
row.getElement().classList.add(row.getData().class);
}
So all together we have a table constructor that looks like this:
var table = new Tabulator("#example-table", {
columns:[
{field:"class", mutator:classMutator, visible:false},
//... other table columns go here
],
rowFormatter:function (row){
row.getElement().classList.add(row.getData().class);
}
}
Then to filter you can simply using the setFilter function:
table.setFilter("class", "=", "is-child");
As a side note, i would strongly recommend upgrading to the latest version of Tabulator, v3.5 is almost 2 years old at this point, and there have been significant improvements since then. If you are worried about jQuery compatibility, all of the latest versions come with a [jQuery Wrapper](http://tabulator.info/docs/4.7/jquery] to make migration easier

d3/js data manipulation dropping columns

I have a dataset in csv and it looks like below.
country,col1,col2,col3
Germany,19979188,11233906,43.7719591
UK,3839766,1884423,50.92349378
France,1363608,796271,41.60557873
Italy,957516,557967,41.72765781
I'd like to drop col1, col2 off while keeping country and col3. If possible, I'd like to wrap it into a function where I can pass column list that I'd like to drop/keep.
Using pandas, which I'm familiar with, I can easily do it. e.g. data.drop(['col1', 'col2'], axis = 1). But I found d3 way or js way in general is based on each row so couldn't come up with an idea to drop columns.
I was thinking of d3.map() taking desirable columns only. But I was stuck to build a general function that the column list can be passed in.
Could anyone have thoughts?
D3 fetch methods, like d3.csv, will retrieve the whole CSV and will create an array of objects based on that CSV. Because of that, filtering out some columns is useless. Actually, it's worse than useless: you'll spend time and resources with an unnecessary operation.
Therefore, the only useful solution is, if you have access and own that CSV, creating a new CSV without those columns. That way you'll have a smaller file, faster to load. Otherwise, if you cannot change the CSV itself, don't bother: just load the whole thing and use the columns you want (which will be properties in the objects), ignoring the others.
Finally, if you have a lot of data manipulation it might be interesting reducing the size of the objects in the data array. If that's your case, use a row function to return only the properties you want. For instance:
d3.csv(url, function (d){
return {country: d.country, col3: d.col3}
}).then(etc...)

ext js store, manipulation of data (linq type queries)

I am working on my first Ext JS project and have my source data downloaded from a web server held in a store. Now I want to have various grids all show some variation of that source data. For example, grid 1 would be the source data grouped by 1 particular column. Grid 2 would be grouped by a particular column, and where column X = 'variable'. So on and so on.
I am coming from a c# background working in WPF. So normally I would use observable collections, and run LINQ on the observable collection to form a new observable collection, then bind that new collection to my grid.
My question is, how can I run LINQ type queries on stores in EXT JS?
You can run LINQ type queries on stores in ExtJS: You can easily get a Collection from a store using the query or queryBy method.
But you can't work like this for your grids, because grids can't run solely on collections, they need a store each. You wouldn't want to use LINQ type queries for these stores.
If you are using ExtJS6, you can look into ChainedStore. You can bind each grid to a ChainedStore which has your data store as the source. Each ChainedStore can be filtered, sorted and grouped independently from the source and from other stores, by using the sort(), group() and addFilter() functions on the respective store.
If you are using an earlier version, you have to use multiple stores and copy all data from the main store manually. Please be aware that store.add() takes an array of records, not a collection. Instead of store.add(collection), use store.add(collection.getRange()). The getRange() function will return an array that contains all items in the collection.
To answer your question from the comment:
what if I need to do something as simple as create a new store, from store1, group everything by column1, and sum column2?
In ExtJS6, if you want to show the grouping and the sum in a grid, that would be something along:
var store2 = Ext.create('Ext.data.ChainedStore',{
source:store1, // use the data from the other store.
grouper:{
property:'someTestField' // grouping is done inside this store.
}
});
Ext.create('Ext.grid.Panel',{
store:store2,
features:[{
ftype:'groupingsummary' // a summary row for each group is provided by this
}],
columns:[{
xtype:'numbercolumn'
dataIndex: 'someTestField'
summaryType: 'sum' // this column should have the sum in the summary row.
}]
})
Untested and without warranty. If you want to do it without the grid, just calculate the sum, that would have to be done manually like this:
var sums = {};
store1.getGroups().each(function(group,i) {
sums[i] = 0;
group.each(function(record) {
sums[i] += record.get(propertyName);
});
});

Can I Create a Single HighCharts Graph from Multiple Data Sources (Multiple GoogleSheets in this case)

I’m trying to use data from multiple GoogleSheets to produce a single HighChart graph.
I’d like to do this without moving all the data into one area of a single spreadsheet, particularly as I want to use the drilldown option which would make it difficult to collect all the data together.
I thought I could pass the columns as an array and then reference the array in the data property of my chart, but I’m struggling to do that with even one column from one sheet.
I have searched for answers online, but I have not found anything relating to highcharts getting data from multiple sources.
Previous Research:
Using GoogleSheets Data as an array before creating the chart: (Removed Link) - The problem is that I could only use one GoogleSheets reference here as the chart object sits inside the data object.
API documentation - (Removed Link) – tells me I can access the columns but that’s not the part I’m having problems with
Querying the Chart: (Removed Link) - I have actually considered making hidden charts, then interrogating the data and making new charts from those, but that seems like a very long way round and I’m still not sure I could grab all the data I need.
Using two GoogleSheets for separate charts on the same page: (Removed Link) I have done this.
Please could you help me to understand how I can access the properties and methods of this object outside of the object itself?
Thank you.
My Code:
//Function to produce a data array ***Not Working - Cannot extract array from object method***
function getData(){
Highcharts.data({
googleSpreadsheetKey: '12x66_QEkTKg_UzvpHEygdTmfnu7oH81pSQYn78Hxt80',
googleSpreadsheetWorksheet: 4,
startColumn: 16,
endColumn: 22,
startRow: 63,
endRow: 76,
parsed: function (columns) {
var dataTest2 = [];
var columnLength = columns[1].length;
for (i = 0; i < columnLength; i = i + 1) {
dataTest2.push(columns[1][i]);
}
alert(dataTest2); //This works here, but not if I move it outside of the method, even if I return it.
var testReturn = this.googleSpreadsheetKey; //trying to return any property using "this" - I've also tried this.googleSpreadsheetKey.value but still undefined
return testReturn; //returns "Undefined"
}
});
}
You could use Google Sheets webQuery. Basically, this is a method to export the Spreadsheet's data into a given format such as csv, json, etc. In your case, the link should look like this:
https://docs.google.com/spreadsheet/tq?key=12x66_QEkTKg_UzvpHEygdTmfnu7oH81pSQYn78Hxt80&gid=4&tq=select%20A,%20B&tqx=reqId:1;out:csv;%20responseHandler:webQuery
Please note that here "tg?key" is the key of your Google Sheet, and "&gid=" is NOT 4, this only tells Highcharts to selected Sheet 4, but for Google Sheets look at the source link and copy the numbers which go after "&gid=". Furthermore, "&tq=" is used to select the columns of the Google Sheet, which in the link above selects "Column A" and "Column B". To find out more on how to select columns and query the output refer to:
https://developers.google.com/chart/interactive/docs/querylanguage?csw=1#Setting_the_Query_in_the_Data_Source_URL
Lastly, "&tqx=" is used to output your data in the format you want. The above link uses "out:csv" which will output the data as comma-separated values. This could as well be Json if you like. Have a look at this documentation:
https://developers.google.com/chart/interactive/docs/dev/implementing_data_source#requestformat
In order to implement this output into your javascript code which you would then use to built your chart, you could use external Javascript libraries to handle these outputs. If you output your data as CSV, you can use "papaparse.js" to parse the CSV into Json which you can be then read by highcharts and allows you to built the chart. Refer to this documentation:
http://papaparse.com/docs#remote-files
An alternative to this would be, to output your Google Sheets directly as Json, then use jquery to make an Ajax Call and load the JSON-encoded data into your Javascript code. Precisely, you could perhaps use jQuery.getJSON() to get the data. Look at this link for more details on how to get Json:
http://api.jquery.com/jquery.getjson/
Finally, it is up to you on which format you choose to output the data, I prefer using Json as it saves you the extra step of having to convert the CSV into Json. Whatever suits you best and is easier for you to understand.
Once you have your data, you may have to parse your Json objects with Json.parse(), and then organize your data into an array with .push(). As #jlbriggs stated, organize your data first before you built the chart. Afterwards, you can make two, three or more Ajax calls to import data from different sources. I would not use many as this will impact in your loading and slow down data transfer.
NB: It is important to format the data accordingly for Highcharts to recognize the data, so use parseFloat() to convert strings into numbers, Date.UTC() to convert strings into date, etc.
Hope this helps you.

Web pivot table componet showing text in pivot table data area

I have found these great pivot table components on the web
nicolaskruchten - pivottable
ZKOSS - pivottable
RJackson - pivottable
My problem (or question) lies in the fact that pivot tables inherently "pivot" data around a numeric data-set; meaning the cell intersections can typically only be numeric in nature (SUM/COUNT/FIRST...)
Is there anything out there (or, if you know how to modify a current component) that will show non-numeric data within the pivot "Value" or intersection.
my question is illustrated below.
as can be seen the interaction data is actually the reports which each role has acess to (grouped by the class of report)... I know there are other ways to represent this data, however I really like the way the pivot viewers above can swap the data filters (columns)
thanks in advance.
I can't speak for all the different pivot table implementations out there, some might have a built-in "aggregator" that will allow you to concatenate string values with formatting (to add a cr/lf for example), but a quick look at the nicolaskruchten/pivottable source lets me think you could easily add your own aggregator.
Just look at file pivot.coffee, starting at line 22. You'll see different aggregator templates, so you could probably add your own right there.
EDIT
I just looked at the rjackson/pivot.js implementation, and by the looks of it, if you add your own defaultSummarizeFunction at pivot.js line 586+, and then also add it to the select at lines 651+, you could create your own "concat" SummarizeFunction
EDIT 2
Well, turns out to be even easier than I thought. Using the rjackson/pivot.js one, all you have to do is provide your own summarizeFunction when you define your concatenable field:
{name: 'billed_amount', type: 'string', rowLabelable: false, summarizable: 'string', summarizeFunction: function(rows, field){
var result = '',
i = -1;
m = rows.length;
while (++i < m) {
result = result + rows[i][field.dataSource] + '<br>';
}
return result;
}}
In this example, I turned a field that would normally be summed, and turned it into a concatenated one simply by providing my own summarizeFunction.
Look at an example here: http://mrlucmorin.github.io/pivot.js/
Cheers

Categories

Resources