Feature #85

Add a function that can be called through JavaScript to filter the data based on certain criteria

Added by Andy Dufilie over 5 years ago. Updated over 5 years ago.

Status:ResolvedStart date:07/20/2011
Priority:ImmediateDue date:
Assignee:Kyle Monico% Done:

100%

Category:JavaScript InterfaceEstimated time: (Total: 16.00 h)
Target version:1.0
Complexity:Medium OIC Priority:
Required by:Grand Rapids, Michigan

Description

Allow creating a subset based on a range of data values for a specific column.

All this needs to be is a function that returns the keys from a column that meet a filter criteria. Once we can get a list of keys in JavaScript, we can do anything after that. Also we should have a function that converts an array of {keyType: ..., localName: ...} objects into an array of IQualifiedKey objects which can then be passed to a function like KeySet.replaceKeys().


Subtasks


Related issues

Related to Weave - Feature #99: Create a tool for filtering data based on attribute values Resolved 07/20/2011
Blocked by Weave - Feature #82: Provide a way to call any function of any object from the JavaScript interface Resolved 06/30/2011

History

#1 Updated by test user over 5 years ago

  • Assignee set to test user

#2 Updated by test user over 5 years ago

  • Assignee deleted (test user)

#3 Updated by Andy Dufilie over 5 years ago

  • Complexity set to Medium

#4 Updated by admin account over 5 years ago

  • Complexity changed from Medium to 2-Medium

#5 Updated by admin account over 5 years ago

  • Complexity changed from 2-Medium to ** Medium **

#6 Updated by admin account over 5 years ago

  • Complexity changed from ** Medium ** to Medium

#7 Updated by Andy Dufilie over 5 years ago

  • Required by set to Grand Rapids, Michigan

#8 Updated by Andy Dufilie over 5 years ago

  • Estimated time set to 25.00

#9 Updated by Andy Dufilie over 5 years ago

  • Description updated (diff)

#10 Updated by Andy Dufilie over 5 years ago

  • Estimated time set to 16.00

#11 Updated by Chris Stefanich over 5 years ago

Can not edit the due date, please set to November 25, 2011, thanks!

#12 Updated by Andy Dufilie over 5 years ago

  • Assignee set to Kyle Monico

#13 Updated by Andy Dufilie over 5 years ago

  • Description updated (diff)

#14 Updated by Kyle Monico over 5 years ago

  • Category changed from Internal Code Refactoring to JavaScript Interface
  • Status changed from Open to Awaiting Feedback

Just wrote a function called getQKeysInNumericRange(column, min, max, inclusiveRange) inside ColumnUtils which will get the keys from a column inside a range.

Here's an example:

var obesityColumnPath = ['LineChartTool', 'children', 'visualization', 'layers', 'plot', 'plotter', 'internalObject', 'columns', 'ReferencedColumn19'];
var keys = weave.evaluateExpression(obesityColumnPath, 'getQKeysInNumericRange(this, 21, 23.6, true)', null, ['weave.utils::ColumnUtils']);
var nameColumnPath = ['DataTableTool', 'columns', 'DynamicColumn'];
for (var i = 0; i < keys.length; ++i)
{
    var key = keys[i];
    var data = weave.evaluateExpression(obesityColumnPath, 'getNumber(this, qkey)', {qkey : key}, ['weave.utils::ColumnUtils']);
    var name = weave.evaluateExpression(nameColumnPath, 'getString(this, qkey)', {qkey : key}, ['weave.utils::ColumnUtils']);
    console.log(data, "\t", name);
}

I'm not sure if this covers everything that's required. It's also possible to simply get all of the keys from a column in Javascript and perform the filtering inside Javascript, then you can pass the return value of getQKeys(genericObjects) into KeySet.replaceKeys().

For example,

var keys = weave.evaluateExpression...;
<filtering of the keys here using ColumnUtils functions>
weave.evaluateExpression(['defaultSubsetKeyFilter', 'included'], 'replaceKeys( getQKeys(keys) )', null, ['weave.utils::ColumnUtils'])

Does this solve the issue?

#15 Updated by Chris Stefanich over 5 years ago

The main thing we want to accomplish with this feature is for a point layer file to be loaded, and someone can filter these points based on criteria.

Say we have a point file of public schools, and the user wants to only see the schools with enrollment higher than 450. They could choose the filtering criteria, and it would only show the points that matched.

#16 Updated by Kyle Monico over 5 years ago

The code above should work then.

It's also possible to get all the keys for a column (as generic objects with keyType and localName properties), use the getNumber, getString, etc functions in ColumnUtils to get the data, and filter in Javascript based on any criteria you may wish to define or let the user define.

Then after filtering, you can use the example in the second code box above (which uses getQKeys so weave gets an array of QKeys) to set the keys in the subset key filter.

The getQKeysInNumericRange function is just for convenience.

#17 Updated by Andy Dufilie over 5 years ago

  • Target version set to 1.0

#18 Updated by Chris Stefanich over 5 years ago

I tried this with the maptool and point layer with this code:

var pointPath = ['MapTool', 'children', 'visualization', 'layers', 'points', 'plotter', 'GeometryPlotter', 'geometryColumn'];
        var keys = document.getElementById("weave").evaluateExpression(pointPath, 
                'getQKeysInNumericRange(Enrolled11, 300, 500, true)', 
                null, ['weave.utils::ColumnUtils']
        );

for (var i = 0; i < keys.length; ++i){
    var key = keys[i];
    var data = document.getElementById("weave").evaluateExpression(pointPath, 
            'getNumber(Enrolled11, qkey)', {qkey : key}, 
            ['weave.utils::ColumnUtils']
    );
    console.log(data);
}

Enrolled11 is the data I would like to filter by, the keys array is undefined. Am I missing something?

#19 Updated by Kyle Monico over 5 years ago

Hi Chris,

The first argument in evaluateExpression is the path to an object in the session state which will be the "this" pointer in the expression to evaluate.

It looks like you want the keys for a column named "Enrolled11". The issue is evaluateExpression doesn't know what "Enrolled11" is, but getQKeysInNumericRange expects it to be an IAttributeColumn.

So let's say Enrolled11 is a column inside a tool. You need to give the object path to Enrolled11 as the first argument to evaluateExpression, then you can simply pass "this" (without quotes) as the first parameter to getQKeysInNumericRange.

For example, let's say Enrolled11 is a column inside the DataTableTool.

var ColumnPath = ['DataTableTool', 'columns', 'DynamicColumn'];  

'DynamicColumn' may not be the name of the column inside the columns LinkableHashMap. Then if we give columnPath as the first parameter to evaluateExpression and pass this as the first parameter to getQKeysInNumericRange, then getQKeysInNumericRange will have the IAttributeColumn to do its work.
var ColumnPath = ['DataTableTool', 'columns', 'DynamicColumn']; 
var keys = weave.evaluateExpression(
                    ColumnPath,
                    'getQKeysInNumericRange(this, 300, 500),
                    null,
                    ['weave.utils::ColumnUtils']
           );

Then you can take a certain key and call getNumber(this, qkey) where qkey is the generic object from the keys array above and "this" is the object specified by objectPath.

var key = keys[0];
var data = weave.evaluateExpression(
                    columnPath,
                    'getNumber(this, myQKey)',
                    {myQKey : key},
                    ['weave.utils::ColumnUtils']
                 );

Two things to note:
1. The ColumnPath variable above may be much longer if it's a column used in a bar chart, for example.
2. The API cannot handle a generic object representation of an IAttributeColumn (but it can for QKeys). That's why the column must be provided as the object path for the this pointer, but the key may be a symbol for a generic object.

Hope this helps.

#20 Updated by Chris Stefanich over 5 years ago

Got it, thanks for the explanation. I am using the probed column to get the enrollment keys, works great.

#21 Updated by Kyle Monico over 5 years ago

  • Status changed from Awaiting Feedback to Resolved

Also available in: Atom PDF