How can I sorting the grouped rows based on the count of igGrid from infragistics ignite-ui? (jQuery) - infragistics

I use the igGrid from infragastics ignite-ui. I have activeted the 'group by' feature of the widget which works fine.
The GroupByLabel has an ASC and DESC sorting option too but usually it is alphabetic sorting. Is it possible to attach somehow my sorting logic for that?
The most important is that ASC/DESC sorting happens on the count of the grouped rows (length of their children) instead of the alphabetic order.
I did not see any method, event which is triggered when the user sorting by the group label (and not by the columns!)
I use the jQuery version and not the Angular.

You can add your custom comparingFunction in columnSettings of the compare feature. You can check the documentation here about the comparingFunction as well as a sample how to use it in this fiddle.
You can use something like this:
features: [
{
name: 'GroupBy',
columnSettings: [
{
columnKey: "ModifiedDate",
isGroupBy: true,
compareFunc: function (val1, val2, recordsData) {
// sort as you need
}
}
]
}
]

Related

How to hide other options in the filter using powerBi Embed

so I am appling a basic filter in my config object for my report, it's working but the problem is that the rest of the selections are shown in the filter section, so the user can remove the filtered data and get all the data they want, is there a way to disable this and make only the filtered option visible? Or hide the basic filter while its doing its job in the background?
here is the object i am using:
const facilityFilter = {
$schema: "http://powerbi.com/product/schema#basic",
target: {
table: "HealthFacilities",
column: "FacilityName"
},
operator: "In",
values: ["Test Facility"],
filterType: models.FilterType.BasicFilter,
requireSingleSelection: true
};
Here is a Demonstration Screenshot:
The only way to make this happen (currently) is through applying Row Level Security or similar approaches in your dataset.
If certain table column values should not be available for certain users, these values must be filtered using RLS rules and role assignments.

Row divider igx Grid

I have an igx Grid with sorted rows. The rows are sorted by date (this is a column from the grid). So I have multiple rows with the same date. How can I put a divider between the rows where the date is changed? Here is an example:
Row Date Some stuff
1 01.01.2021 some data
2 01.01.2021 some data
3 01.01.2021 some data
__________________________________________
4 03.01.2021 other data
5 03.01.2021 other data
__________________________________________
So from the 4. row the date is changed, how can I put a divider (something like in this tutorial: https://www.infragistics.com/products/ignite-ui-angular/angular/components/divider) before the 4. row programmatically? How can I do this in Typescript?
Since the Ignite UI for Angular Grid is virtualized and thus its record rendering is entirely data driven, there's no way to inset arbitrary elements in-between rows that I can think of. It'll mess with both rendering/scroll and navigation as you can imagine, so the templatable areas are controlled.
On first glance, your example can probably be achieved with a simple border style through some data manipulation and Conditional Row Styling. You can provide a callback for each row to trigger a class or custom styles.
However, seeing as you already sort by the date it really looks like the scenario you're describing is something that can be handled by Grouping. Group By is already an extension of sorting with the added groups with templatable headers and expand-collapse functionality. Actually, there's an example of this exact type of group under the custom group by example:
What you should be looking at is the expression, the DaySortingStrategy if the default isn't enough, but mostly the groupingComparer which determines if items belong in the same group. Here's a simplified version from the sample:
this.sortingStrategy = DaySortingStrategy.instance(); // or DefaultSortingStrategy.instance()
this.initialExpr = [{
dir: SortingDirection.Asc,
fieldName: 'OrderDate',
ignoreCase: true,
strategy: this.sortingStrategy,
groupingComparer: (a, b) => {
const dateA = this.sortingStrategy.getParsedDate(a);
const dateB = this.sortingStrategy.getParsedDate(b);
return dateA.day === dateB.day && dateA.month === dateB.month ? 0 : -1;
}
}];
which is bound to the Grid's groupingExpressions:
<igx-grid #grid1 [data]="data" [groupingExpressions]="initialExpr">
I suspect the groupingComparer can even be simplified further depending on your data.

How to use MapReduce when extracting a group of document id's by some criteria from CouchDB

I'm in my first week of CouchDB experimentation and trying to stop thinking in SQL. I have a collection of documents (5000 event files) that all have some ID value that will be common to groups of documents. So there might be 10 that all have TheID: 'foobar'.
(In case someone asks - TheID is not an auto-increment value from a relational database - it is a unique id assigned by a partner company of ours. I cannot redesign my source data to identify itself some other way, I have to use this TheID field to recognise groups of documents.)
I want to query my list of documents:
{ _id: 'document1', Message: { TheID: 'foobar' } }
{ _id: 'document2', Message: { TheID: 'xyz' } }
{ _id: 'document3', Message: { TheID: 'xyz' } }
{ _id: 'document4', Message: { TheID: 'foobar' } }
{ _id: 'document5', Message: { TheID: 'wibble' } }
{ _id: 'document6', Message: { TheID: 'foobar' } }
I want the results:
'foobar': [ 'document1', 'document4', 'document6' ]
'xyz': [ 'document2', 'document3' ]
'wibble': [ 'document5' ]
The aim is to represent groups of documents on our UI grouped by TheID, so the user can see all documents for a specific TheID together, and select that TheID to drill into the data querying just by that TheID value. Yes, the string id of each document is useful - in our case, the _id value of each document is the source event identifier, so it is a unique and useful value that the user is going to want to see in the list on screen.
In SQL one might order by or group by the TheID field and iterate the result set appropriately. I doubt this thinking is any use at all with a CouchDB query.
I know that I can use a map function to extract the TheID value for each document, for example:
function (doc) {
emit(doc.Message.TheID, 1);
}
or perhaps
function (doc) {
emit(doc._id, doc.Message.TheID);
}
I'm not sure exactly what I should emit as the key and value. Even if this is useful, I'm getting the feeling that I should not use a reduce function to try to 'reduce' the large map output (1 result row per document in the database) to what I want (3 results each with a list of document id's).
http://guide.couchdb.org/draft/views.html says "A common mistake new CouchDB users make is attempting to construct complex aggregate values with a reduce function. Full reductions should result in a scalar value, like 5, and not, for instance, a JSON hash with a set of unique keys and the count of each."
I thought I might be able to use reduce to scan the results of the map and somehow collect all results that have a common TheID value into a single result object. What I see when reading the reduce documentation is that it will be given arrays of keys and values that contain fairly unpredictable collections, driven by the structure of the btree underlying the map results. It won't be given arrays guaranteed to contain all similar TheID values that I could scan for. This approach seems completely broken.
So, is a map/reduce pair the right thing to do here? Should I look at using a 'show' or 'list' instead? I'm intending to build a mustache based HTML template engine around the results, so 'list' seems the wrong way to go.
Thanks in advance for any guidance.
EDIT I have done some local dev and come up with what I think is a broken solution. Hopefully this will show you the direction I'm trying to go in. See a public cloud based CouchDB I created at https://neek.iriscouch.com/_utils/database.html?test/_design/test/_view/collectByTheID
This is public. If you would like to play, please copy it to a new view, don't pollute this one in case others come in and want to see the original.
map function:
function(doc) {
emit(doc.Message.TheID, doc._id);
}
reduce function:
function(keys, values, rereduce) {
if (!rereduce) {
return values;
} else {
var ret = [];
values.forEach(function (ar) {
ret.concat(ar);
});
return ret;
}
}
Results:
"foobar" ["document6", "document4", "document1"]
"wibble" ["document5"]
"xyz" ["document3", "document2"]
The reduce function first leaves the array of values alone, and on the second pass concatenates them together. However when I run this on my large 5000+ document database it comes up with some TheID values with empty document id arrays. I believe this suffers from the problem I mentioned before, where the array of values passed to reduce are build dependent on the btree structure of the map they are extractd from and are not guaranteed to contain a complete set of values for given keys.
Make use of the group_level feature:
Map:
emit([doc.message.TheID, doc._id], null)
Reduce:
You must include a reduce to use group_level, it can be empty as below or something else, i.e. _count
function(keys, values){
return null;
}
A query with group_level=1 would return:
/_design/d/_view/v?group_level=1
[
{key: ["foobar"], value: null},
{key: ["xyz"], value: null},
{key: ["wibble"], value: null}
]
You would use this query to populate the top level in your grouping UI. When the user expands a category, you would do another query with group_level 2 and start and end keys:
/_design/d/_view/v?group_level=2&startkey=["foobar"]&endkey=["foobar",{}]
[
{key: ["foobar", "document6"], value: null},
{key: ["foobar", "document4"], value: null},
{key: ["foobar", "document1"], value: null}
]
This doesn't produce the output exactly as you are requesting, however, I think you'll find it flexible enough

How should be my MDX query to use Google geo map in icCube ic3report?

According to this, I should select the first column as the city name and the second/third as optional values to be displayed:
https://google-developers.appspot.com/chart/interactive/docs/gallery/geomap?hl=en
However, when I use the following MDX query ic3report does not show me any info on the map, and I already checked the query and it is returning all results:
WITH MEMBER [Measures].[City Name] AS [Customers].[Location].currentmember.name
SELECT
NON EMPTY { {
[City Name],
[Measures].[My Value]
} } ON COLUMNS,
NON EMPTY { NonEmpty( [Customers].[Location].[City].allmembers, [Measures].[My Value]) } ON ROWS
FROM [My Cube]
Since I could not find any icCube examples on this, can anybody help me?
I'm assuming you'd like to have some "markers" for the cities.
For that, you can configure the Geo widget Properties:
Region : world (for example)
Display Mode : markers-name
Then your MDX might be as following using the icCube's demo. Sales cube; the [Measures] being on the axis 0 and the cities on the axis 1 :
SELECT
{ {[Measures].[Amount]} } ON COLUMNS,
{ [Customers].[Geography].[City].allmembers } ON ROWS
FROM [Sales]
Note depending on the numbers of markers it might take some time to display them (you could use lat/long instead of names for faster rendering).
Hope that helps.

Extjs dynamic filter

I have created a filter that contains unik values of column:
{
header : 'Вопрос А',
dataIndex: 'answerA',
itemId: 'answerA',
width : 100,
filter: {
type: 'list',
options: this.getStore().collect('answerA'),
},
editor: 'textfield'
}
When the user inputs new value in the cell of the column this value must appear in the filter. How can I do this?
I have looked at Extjs Grid Filter - Dynamic ListFilter but it doesn't help me much.
You should carefully look at StringFilter.js file which is at ux/grid/filter. I did this myself by adding a combobox to each filter. On combo expand I update its store by parsing the corresponding column data. Besides I advise you to collect unique values, for this task use Ext.Array.unique function. Otherwise, if two cells contain the same data both values will go to the store, which is not good, because any of them will produce the same filtration. I do not attach my code, because it is heavily dependent on my custom data types, but the idea is quite easy, I think.