Different default sort directions for Columns in Table in React-virtualized - react-virtualized

Using the Table and Column components of react-virtualized, I have achieved a default sort column and direction by defining a sortBy dataKey and the sortDirection in the Table component. I have another column, which I would like to have sort in descending order (instead of the default ascending order) the first time a users clicks it, but can't see how to do this. Is it possible to have a default sort direction per Column?
Update: I don't want to sort columns simultaneously, but instead want to have different sort directions for each column when sort is first implemented per column. For example, I want to start the defaults for my table to be sorted by lastname in ascending order. However, I have a few other columns that hold integers or booleans, and that I would like to sort in descending order when the user first clicks on those columns. In ascending order, those columns would first display false and 0's (if any), but would be more meaningful if they were first sorted with true or a set's upper numbers. I'm trying to slightly improve the user experience as to not have to click twice on the columns to get a descending order.

RV's Table does not support the concept of sorting by multiple columns simultaneously. (I'm not sure how it would make sense, unless 1 field is the primary sort and the other is a secondary sort?) Either way, I think that use-case is uncommon.
I think the easiest way to do what you're looking for would be for you to specify your own headerRenderer for the sorted-by Columns:
<Column
{...otherProps}
headerRenderer={yourHeaderRenderer}
/>
You could even decorate the default/built-in header renderer. Then instead of using the sort-by props from Table just pass your own to the sorted-by columns:
import {defaultTableHeaderRenderer} from 'react-virtualized';
function yourHeaderRenderer(props) {
return defaultTableHeaderRenderer({
...props,
sortBy: yourSortByHere,
sortDirection: yourSortDirectionHere
});
}
Update What you're actually asking for here (a default sort direction per column) is completely up to your application. Basically your sort function could look like this:
let prevSortBy;
const sort = ({ sortBy, sortDirection }) => {
if (sortBy !== prevSortBy) {
// You can decide the initial sort direction based on the data.
// Just ignore RV's best-guess default in your case.
}
prevSortBy = sortBy;
// Do your sort-logic here (eg dispatch a Redux action or whatever)
}

Related

How to compare one row to others in DAX in Excel

I have this table which has foreign keys from several other keys:
Basically, this table shows which students registered in which module run by which teacher in what term.
I want to query the following:
How many students have registered for more than one module run by a given tutor?
It will look something like this:
For example, Vasiliy Kuznetsov runs two modules: FunPro and NO. If one student registers for both of them, he is counted as one.
My sql oriented mind is telling me this: Count all the rows in which student_id and tutor_id are the same. For example, in one row student_id is 5 and tutor_id is 10, and the same is true for the third row. Then, I count it as one.
How can I do that with DAX formulas?
RowCount:=
COUNTROWS( ModuleRegistration )
StudentsWithTwoOrMoreRegistrations:=
COUNTROWS(
FILTER(
VALUES( ModuleRegistration[Student_ID] )
,[RowCount] >= 2
)
)
I refer to arguments positionally, thus the first argument to a function is (1), the second (2), and so on.
So, [RowCount] is trivial.
[StudentsWithTwoOrMoreRegistrations] is a bit more involved. DAX, being a functional language, is best understood inside-out.
FILTER() takes a table expression in (1) and evaluates a boolean predicate, (2), for each row in (1). It returns all rows from (1) for which (2) evaluates to true.
Our FILTER()'s (1) is VALUES( ModuleRegistration[Student_ID] ). VALUES() returns the unique rows from a field based on current filter context (it respects slicers and filters in the pivot table). Thus, we will return some subset of the unique list of [Student_ID]s.
Our FILTER()'s (2) is [RowCount] >= 2. For each [Student_ID] in (1), we'll evaluate [RowCount], checking how many times that student appears in ModuleRegistration. [RowCount] is evaluated in the combination of filter context from the pivot table (the [Faculty Name] field in your sample pivot provides filter context) and row context from FILTER()'s (1). Thus it counts how many times the student appears in ModuleRegistration for the [Faculty Name] on the pivot table row.
We check that [RowCount] is >= 2.
You've not indicated if your measure needs to handle grand totals, or how you might want to see that. If you need more help for the grand total to get it to behave the way you like, let me know.
Edit for grand total
There are a few ways you might want to handle grand totals. I'm gong to assume that you want a unique count of students.
StudentsWithTwoOrMoreRegistrations:=
COUNTROWS(
SUMMARIZE(
FILTER(
SUMMARIZE(
ModuleRegistration
,ModuleRegistration[Tutor_ID]
,ModuleRegistration[Student_ID]
)
,[RowCount] >= 2
)
,ModuleRegistration[Student_ID]
)
)
WTF happened to our measure?
Let's examine:
Starting with the innermost SUMMARIZE(). SUMMARIZE() navigates relationships outward from the table in (1) and groups by the columns listed in (2)-(N) (these don't have to be from the table in (1), but must be reachable by navigating relationships).
This is equivalent to the following in SQL:
SELECT
mr.Tutor_ID
,mr.Student_ID
FROM ModuleRegistration mr
We use FILTER() on this table like earlier. [RowCount] is evaluated in the combination of filter context from the pivot table and the row in the table, defined by our SUMMARIZE() above.
Now our row context is instead of just a student, a student-tutor pair. This pair will have a [RowCount] >= 2 when the student has taken more than one module from a tutor.
Our FILTER() returns the pairs which have a [RowCount] >= 2. This output table has two fields, [Tutor_ID] and [Student_ID], but we want to count distinct [Student_ID]s out of this.
Thus, we use the table from FILTER() as our (1) in the outer SUMMARIZE(). We group only by the values of [Student_ID]. We then count the rows of this table.
When only one [Faculty_Name] is in context, e.g. on a pivot table row, then our inner SUMMARIZE() is grouping by a single value of [Tutor_ID] and whatever [Student_ID]s are associated with it. This is identical to our earlier measure.
When we have many [Tutor_ID]s in context, like in the grand total, then we'll see the appropriate behavior of only counting each [Student_ID] once.

Filter based on existence in one table and non-existence in another

I have the following data model:
Record: Id, ..., CreateDate
FactA: RecordId, CreateDate
FactB: RecordId, CreateDate
Relationships exist from FactA to Record and FactB to Record.
I've written measures on Records such as this with no issues:
FactA's:=CALCULATE(DISTINCTCOUNT(Records[Id]), FactA)
FactB's:=CALCULATE(DISTINCTCOUNT(Records[Id]), FactB)
Now I'd like a count of Records with FactA but no FactB, in SQL I'd do a LEFT JOIN WHERE FactB.RecordId IS NULL but I can't figure out how to do similar in DAX. I've tried:
-- this returns blank, presumably because when there is a FactB then RecordId isn't blank, and when there is no Fact B then RecordId a NULL which isn't blank either
FactA_No_FactB:=CALCULATE(DISTINCTCOUNT(Records[Id]), FactA, FILTER(FactB, ISBLANK([RecordId])))
-- this returns the long "The value for columns "RecordId" in table "FactB" cannot be determined in the current context" error.
FactA_No_FactB:=CALCULATE(DISTINCTCOUNT(Records[Id]), FILTER(FactA, ISBLANK(FactB[RecordId])))
I've also tried various ways of using RELATED and RELATEDTABLE but I don't really understand enough about DAX and context to know what I'm doing.
Can someone explain how I can write the calculated measure to count Records with FactA but no FactB?
Thanks in advance.
Edit - Workaround
I've come up with this, it looks correct so far but I'm not sure if it is the generally correct way to do this:
-- Take the count with FactA and subtract the count of (FactA and FactB)
FactA_No_FactB:=CALCULATE(DISTINCTCOUNT(Records[Id]), FactA) - CALCULATE(DISTINCTCOUNT(Records[Id]), FactA, FactB)
Here's an alternative, that might still not be the best way of doing it:
FactA_No_FactB:=CALCULATE(DISTINCTCOUNT(Records[ID]), FILTER(Records,CONTAINS(FactA, FactA[RecordID],Records[ID]) && NOT(CONTAINS(FactB,FactB[RecordID],Records[ID]))))
The difference between my version and yours is that mine returns a value of 1 for those items in and A but not B and BLANK for everything else. Your version returns 1 for those items in A but not B, 0 for those in both A and B and BLANK for everything else. Depending on your use case, one outcome may be prefereable over the other.

ExtJS 4.2 Change Group by this column

By default my ExtJS 4.2 Grid is grouping correctly.I want to know the event that is called when we click Group By This Field in ExtJS 4.2.I want to get the column value on this grouping has to be done and save the column field in the database.
I'm not sure if I understand you correctly, but let's give it a shot.
The following event is fired when changing the grouping of a grid.
http://docs.sencha.com/extjs/4.2.3/#!/api/Ext.data.Store-event-groupchange
store.on('groupchange', function (store, groupers) {
// group values available here
var values = store.groups.keys;
// name of the column currently grouped by
var columnField = groupers.keys[0];
// then do whatever you want with these values
});

Cassandra BETWEEN & ORDER BY operations

I wanted to perform SQL operations such as BETWEEN, ORDER BY with ASC/DSC order on Cassandra-0.7.8.
As I know, Cassandra-0.7.8 does not have direct support to these operations. Kindly let me know is there a way to accomplish these by tweaking on secondary index?
Below is my Data model design.
Emp(KS){
User(CF):{
bsanderson(RowKey): { eno, name, dept, dob, email }
prothfuss(RowKey): { eno, name, dept, dob, email }
}
}
Queries:
- Select * from emp where dept='IT' ORDER BY dob ASC.
- Select * from emp where eno BETWEEN ? AND ? ORDER BY dob ASC.
Thanks in advance.
Regards,
Thamizhananl
Select * from emp where dept='IT' ORDER BY dob ASC.
You can select rows where the 'dept' column has a certain value, by using the built-in secondary indexes. However, the rows will be returned in the order determined by the partitioner (RandomPartitioner or OrderPreservingPartitioner). To order by arbitrary values such as DOB, you would need to sort at the client.
Or, you could support this query directly by having a row for each dept, and a column for each employee, keyed (and therefore sorted) by DOB. But be careful of shared birthdays! And you'd still need subsequent queries to retrieve other data (the results of your SELECT *) for the employees selected, unless you denormalise so that the desired data is stored in the index too.
Select * from emp where eno BETWEEN ? AND ? ORDER BY dob ASC.
The secondary index querying in Cassandra requires at least one equality term, so I think you can do dept='IT' AND eno >=X AND eno <=y, but not just a BETWEEN-style query.
You could do this by creating your own index row, with a column for each employee, keyed on the employee number, with an appropriate comparator so all the columns are automatically sorted in employee-number order. You could then do a range query on that row to get a list of matching employees - but you would need further queries to retrieve other data for each employee (dob etc), unless you denormalise so that the desired data is stored in the index too. You would still need to do the dob ordering at the client.
As I know the columns will be sorted by comparator when you create column family and you can use clustring key for sorting on your opinion
and row in column family will be sorted by partitioner
I suggest you read this paper
Cassandra The Definitive Guide Chapter 6

Complicated condition

I have predefined item combination (for example brand1|brand2|brand3 etc) in the table.
i like to collect brands and check against with predefined table data.
For example i collected brand1|brand2|brand3 then i can do get some value form that predefined table(it meets the condition).
How can i check?
brands would be unlimited. also brand1|brand2|brand3 of brand1|brand2| exist then returns true.
Okay, taking a wild guess at what you're asking, you have a delimited field with brands in them separated by a | character. You want to return any row that has the right combination of the brands in there, but don't want to return rows with, for example, brand "testify" in them when you search for "test".
You have four search conditions (looking for brand3):
the brand exists by itself: "brand3"
the brand starts the delimited field: "brand3|brand4|brand6"
the brand is in the middle of the field: "brand1|brand3|brand6"
the brand is at the end of the field: "brand1|brand2|brand3"
so, in SQL:
SELECT *
FROM MyTable
WHERE BrandField = 'brand3'
OR BrandField LIKE 'brand3|%'
OR BrandField LIKE '%|brand3|%'
OR BrandField LIKE '%|brand3'
Repeat as required for multiple brands.

Resources