Skip to content

Commit

Permalink
lotsa fixes for qtree example and excel integration docs
Browse files Browse the repository at this point in the history
  • Loading branch information
stevewirts committed Feb 17, 2015
1 parent b218229 commit b671b89
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 81 deletions.
47 changes: 5 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The only file that is necessary to deploy the hypergrid is the webcomponent html
##Q by [kx](http://kx.com/) systems [demo](http://openfin.github.io/fin-hypergrid/components/fin-hypergrid/demo.html) tabs (select either the 'Q' or 'Q Tree' tabs).
1. The Q tabs will not be populated with data until you run a Q server script that is provided.
2. Make sure q 32 bit free version is installed [Q free version](http://kx.com/software-download.php)
3. Startup either ```q bigtable.q```, ```q sorttable.q```, or ```d.q```
3. Startup either ```q bigtable.q```, ```q sorttable.q```, or the analytics examples found in s1.zip and s2.zip
4. Make sure grunt serve is running
5. If you are running locally, the grunt serve process should automatically refresh your web browser with the q driven grid now populated with data

Expand Down Expand Up @@ -121,55 +121,18 @@ The excel-integration demo consists of an OpenFin app, and a C# XLL plugin built

Assumptions
* Windows machine
* .NET framework installed

Steps to Integration Demo

1. Download [excel.zip](http://openfin.github.io/fin-hypergrid/components/fin-hypergrid/excel.zip)
2. Unzip files to a local folder
3. Launch the *FinDesktopAddin* located at
64 Bit <local folder>/desktop-cs-excal/ExcelRtdAddin/bin/x64/Release/
86 Bit <local folder>/desktop-cs-excal/ExcelRtdAddin/bin/x64/Release/
64 Bit <local folder>/FinDesktopAddin64-packed.xll
86 Bit <local folder>/FinDesktopAddin-packed.xll
4. Start Hypergrid
5. Open Hypergrid.xls stored in <local folder>

Steps 3-5 need to be repeated each time you want to run the demo. Alternatively, you can manage this addin so that step 3 does not need to be repeated Excel File -> Options -> Add-Ins -> Manage Addins -> Browse -> Select <local folder>/desktop-cs-excel/ExcelRtdAddin/bin/x64/Release/*FinDesktopAddin*

The Excel-DNA infrastructure provides a C++ XLL plugin which exposes the Excel Object Model to C# dll's and code which can be configured using a manifest file (.dna)

The excel folder ([download excel.zip](http://openfin.github.io/fin-hypergrid/components/fin-hypergrid/excel.zip)) contains the source code and implementation of the OpenFin C# adapter which connects to the OpenFin runtime over WebSockets, and exposes the InterApplicationBus to C# code. Download this zip file and unzip it into a new directory on your machine.

The *desktop-cs-excel* folder contains the Excel-DNA interfaces in the *ExcelRtdAddin/RtdServer.cs* file, and also contains a complete distribution of the DNA source code in the Dna subfolder.

*ExcelRtdAddin/RtdServer.cs* combines the ExcelRtdServer interface with the asynchronous OpenFin DesktopStateListener interfaces to expose a higher level set of classes DesktopRtdServer and SubscriptionRtdServer which can be used to integrate Excel functionality with OpenFin. The SelectionRtdServer class implements the grid specifc behavior using a simple JSON serialisation of the selection, and provides updates from Excel using delegates on the ExcelDnaUtil.Application object and its associated worksheets.


Running the Excel Integration Example
=======

To test that the Excel-DNA infrastructure is working on your system first load the appropriate 32bit or 64bit .xll file from the *desktop-cs-excel/Dna/Distribution/* folder. You should be prompted with a security warning to enable the addin, after which you can create a new worksheet and enter the following formula in a cell (as described in ExcelDna.dna):

*=AddThem(5,10)*

You should see 15 as the result.

If this is working then you can proceed to installing the OpenFin runtime and setting up the grid application to be hosted locally. You can also use the default remotely hosted grid if you like, but its better for learning to use the locally hosted version.

Run the hypergrid installer from here [here.](https://dl.openfin.co/services/download?fileName=hypergrid-demo-installer&config=http://openfin.github.io/fin-hypergrid/components/fin-hypergrid/demo.json)

This will add a shortcut to your desktop which will connect to the remote grid using the default url.

Once verified you can launch either the x86 or x64 OpenFin .xll addin:

*desktop-cs-excel/ExcelRtdAddin/bin/x86/Release/FinDesktopAddin.xll*

*desktop-cs-excel/ExcelRtdAddin/bin/x64/Release/FinDesktopAddin64.xll*


Then open the xlsx file 'hypergrid.xlsx' found in the root of the downloaded excel.zip

This will show two worksheets, the first sheet should now show data from the grid when you click a cell or if you hold shift and click multiple cells. You can edit a cell which has a value in Excel and that change will be reflected in the equivalent grid cell.
5. Open Hypergrid.xlsx stored in &lt;local folder&gt;

Steps 3-5 need to be repeated each time you want to run the demo. Alternatively, you can manage this addin so that step 3 does not need to be repeated Excel File -> Options -> Add-Ins -> Manage Addins -> Browse -> Select <local folder>/*FinDesktopAddin*

Excel Integration Links
=====
Expand Down
69 changes: 55 additions & 14 deletions behaviors/fin-hypergrid-behavior-qtree.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
cols: [],
rows: []
},
Z_:[{
Z:[{
g_:['']
}]
};
Expand Down Expand Up @@ -125,7 +125,9 @@
var colId = self.block.F[config.x];
var type = self.block.Q[colId];
var formatter = typeFormatMap[type] || function(v) { return v; };
config.value = formatter(config.value[0]);
if (config.value) {
config.value = formatter(config.value[0]);
}
}
config.value = config.value || '';
return label;
Expand Down Expand Up @@ -167,11 +169,6 @@
return provider;
},

//this is done through the dnd tool for now...
//we can fix this to work both ways later
isColumnReorderable: function() {
return false;
},

attributeChanged: function(attrName, oldVal, newVal) {
// console.log(attrName, 'old: ' + oldVal, 'new:', newVal);
Expand Down Expand Up @@ -204,7 +201,7 @@
// if (clone.length === 0) {
// return clone;
// }
var hValue = this.block.Z_[0].g_[0];
var hValue = this.block.Z[0].g_[0];
var clone = ['Hierarchy', '\u25be ' + hValue];
clone[0] = clone[0] + ' ' + sortIndicator;
return clone;
Expand All @@ -215,7 +212,7 @@
getValue: function(x, y) {
var col = this.getColumnId(x);
var normalized = Math.floor(y - this.scrollPositionY);
if (this.block) {
if (this.block && col) {
var val = this.block.Z[1][col][normalized];
if (val || val === 0) {
return val;
Expand Down Expand Up @@ -300,7 +297,7 @@

getFixedColumnValue: function(x, y) {
var indentPixels = 10;
var blob = this.block.Z_[1];
var blob = this.block.Z[1];
var transY = Math.max(0, y - this.scrollPositionY);
var data = blob.g_[transY];
var indent = 5 + indentPixels + (blob.l_[transY] - 1) * indentPixels;
Expand Down Expand Up @@ -404,7 +401,7 @@

fixedColumnClicked: function(grid, mouse) {
var rowNum = mouse.gridCell.y - this.getFixedRowCount();
var nodes = this.block.Z_[1].n_[rowNum];
var nodes = this.block.Z[1].n_[rowNum];
var nodeClick = {
id: "abc",
fn: "node",
Expand All @@ -413,6 +410,7 @@
this.ws.send(JSON.stringify(nodeClick));
},
openEditor: function(div) {
var self = this;
var container = document.createElement('div');

var group = document.createElement('fin-hypergrid-dnd-list');
Expand All @@ -426,17 +424,29 @@
this.beColumnStyle(group.style);
group.style.left = '0%';
group.label = 'groups';
group.list = this.block.G;
group.list = this.block.G.slice(0);
//can't remove the last item
group.canDragItem = function(list, item, index, e) {
return list.length > 1;
};
//only allow dropping of H fields
group.canDropItem = function(sourceList, myList, sourceIndex, item, e) {
return self.block.H.indexOf(item) > -1;
};

this.beColumnStyle(hidden.style);
hidden.style.left = '33.3333%';
hidden.label = 'hidden columns';
hidden.list = this.block.F_;
hidden.list = this.block.I.slice(0);

this.beColumnStyle(visible.style);
visible.style.left = '66.6666%';
visible.label = 'visible columns';
visible.list = this.block.F;
visible.list = this.block.F.slice(0);
//can't remove the last item
visible.canDragItem = function(list, item, index, e) {
return list.length > 1;
};

//attach for later retrieval
div.lists = {
Expand All @@ -459,6 +469,36 @@
this.ws.send(JSON.stringify(changeCols));
return true;
},

//this is done through the dnd tool for now...
//we can fix this to work both ways later
isColumnReorderable: function() {
return true;
},

swapColumns: function(src, tar) {

var tmp = this.columnIndexes[src];
this.columnIndexes[src] = this.columnIndexes[tar];
this.columnIndexes[tar] = tmp;

var visible = this.block.F.slice(0);
var t = visible[src];
visible[src] = visible[tar];
visible[tar] = t;
var changeCols = {
id: "abc",
fn: "groups",
groups: this.block.G,
visible: visible
};
this.ws.send(JSON.stringify(changeCols));
return true;

var tmp = this.columnIndexes[src];
this.columnIndexes[src] = this.columnIndexes[tar];
this.columnIndexes[tar] = tmp;
},
beColumnStyle: function(style) {
style.top = '5%';
style.position = 'absolute';
Expand Down Expand Up @@ -497,6 +537,7 @@
};
this.ws.onmessage = function(e) {
d = JSON.parse(e.data);
self.initColumnIndexes();
self.block = d;
oldSize = self.block.N - 1;

Expand Down
3 changes: 1 addition & 2 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,7 @@ <h3>To point this example to your data</h3>

<div vertical layout>
<div class="description">
<h3>fin-hypergrid-behavior-qtree</h3> This element is a custom Polymer web component that demonstrates a more complex interface to Q/KDB+ by kx systems. In order for this to work you need to run the provided <a href="https://github.com/openfin/fin-hypergrid/blob/master/q/u.q">u.q script</a> found in the q directory of this project, u.q will load in <a href="https://github.com/openfin/fin-hypergrid/blob/master/q/t.q">t.q</a> and <a href="https://github.com/openfin/fin-hypergrid/blob/master/q/d.q">d.q</a>, so they are required as well. This example shows the powerful dynamic analytic capabilities of an external data engine. This example Q script was based on <a href="http://archive.vector.org.uk/art10500340">code and a paper</a> written by <a href="http://nsl.com/">Stevan Apter.</a> Press the alt/option button for a popup to select the hierarchy columns or select/hide the visible columns.
</div>
<h3>fin-hypergrid-behavior-qtree</h3> This element is a custom Polymer web component that demonstrates a more complex interface to Q/KDB+ by kx systems. In order for this to work you need to run either provided q scripts found in <a href="https://github.com/openfin/fin-hypergrid/blob/master/q/s1.zip">s1.zip scripts (see s1.txt for instructions)</a>, or <a href="https://github.com/openfin/fin-hypergrid/blob/master/q/s2.zip">s2.zip scripts (see s2.txt for instructions)</a>. The s1 example is a +1MM row tree table with static data, while the s2 example has live updates. These examples show the powerful dynamic analytic capabilities of an external data engine. These example Q script are based on <a href="http://archive.vector.org.uk/art10500340">code and a paper</a> written by <a href="http://nsl.com/">Stevan Apter.</a> Press the alt/option button for a popup to select the hierarchy columns or select/hide the visible columns.</div>
<br>
<core-splitter direction="up"></core-splitter>
<div flex class="rel">
Expand Down
Binary file modified excel.zip
Binary file not shown.
6 changes: 6 additions & 0 deletions features/fin-hypergrid-feature-column-moving.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
dragOffset: 0,

initializeOn: function(grid) {
this.isFloatingNow = false;
this.initializeAnimationSupport(grid);
if (this.next) {
this.next.initializeOn(grid);
Expand Down Expand Up @@ -186,6 +187,7 @@
self.doFloaterAnimation(grid);
requestAnimationFrame(function() {
d.style.display = 'none';
self.isFloatingNow = false;
});
}, columnAnimationTime + 50);
};
Expand Down Expand Up @@ -350,6 +352,10 @@
if (draggedToTheRight) {
overCol = overCol - 1;
}
if (this.isFloatingNow) {
return;
}
this.isFloatingNow = true;
this.createFloatColumn(grid, overCol);
this.floatColumnTo(grid, draggedToTheRight);
} else {
Expand Down
4 changes: 2 additions & 2 deletions fin-hypergrid.min.html

Large diffs are not rendered by default.

Binary file added q/s1.zip
Binary file not shown.
16 changes: 13 additions & 3 deletions q/s1/t.q
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
\d .tt

/ construct treetable
cons:{[t;p;a;s;g;f]cons_[csub[t]g,f;p;(f inter key a)#a;s]. ungrp[t;g]f}
cons:{[t;p;a;s;g;f]cons_[csub[csym[t]g]g,f;p;(f inter key a)#a;s]. ungrp[t;g]f}
cons_:{[t;p;a;s;g;f]0!ctl[1!(0!d)tsort[d:dat[t;p;rollups[t;g]a;g]f,`s_]s;p]g}

/ symbolize non-symbolic grouping fields
csym:{[t;g]![t;();0b;h!(`$string@;)each h:.tt.csym_[t]g]}
csym_:{[t;g]exec c from meta?[t;();0b;g!g]where t<>"s"}

/ flatten if keys in G
ungrp:{[t;g;f]if[all keys[t]in g;f:distinct g,f;g:0#`];(g;f)}

Expand Down Expand Up @@ -110,11 +114,17 @@ take:{[v;s;e]$[s>=count v;0#v;((1+e-s)&count z)#z:s _ v]}

// globals

/ visible order
F::cols[T]except G

/ group by
G:()

/ visible order
F::cols[T]except G
/ groupable
H::exec c from meta get T where t in"bhijspmdznuvt"

/ invisible
I::cols[T]except G,F

/ rollups
A:()!()
Expand Down
1 change: 1 addition & 0 deletions q/s1/u.q
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ T:([tradeId:til n]
time:09:30:00.0+n?23000000)

G:`sector`trader`strategy
F:`symbol`price`quantity
A[`price]:(avg;`price)
A[`tradeId]:(.tt.nul;`tradeId)

Expand Down
15 changes: 9 additions & 6 deletions q/s1/w.q
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,22 @@ $[.z.K<3.3;

.js.node:{[d]$[0=count n:d`node;d;count[Z]=r:Z[`n_]?n;d;[`P set .tt.at[not Z[`o_]r;P;G]n;.js.set d]]}
.js.sorts:{[d]`S set d[`cols]!d`sorts;i:.tt.tsort[Z]S;Z@:i;Z_@:i;.js.ret d}
.js.groups:{[d]`F`G set'd`visible`groups;`P set .tt.paths[P]G;.js.set d}
.js.groups:{[d]`F`G set'.js.sym d`visible`groups;`P set .tt.paths[P]G;.js.set d}
.js.get:{[d]`R set`start`end!"j"$d`start`end;.js.ret d}

/ utilities
/ logging

.js.log:{0N!(.js.elt x;y);}
.js.snd:{neg[W].j.j x}
.js.elt:{`time$"z"$.z.z-x}

/ utilities

.js.sym:{$[(t:abs type x)in 0 99h;.z.s each x;10=t;`$x;x]}
.js.exe:{.js[x`fn]x}
.js.upd:{if[not null W;t:.z.z;.js.snd .js.set()!();.js.log[t]`upd]}
.js.ups:{if[not null W;t:.z.z;`Z set 0!(`n_ xkey Z)upsert`n_ xkey .tt.cons[T;P;A;S;G]x;.js.snd .js.ret()!();.js.log[t]`ups]}
.js.set:{`Z set .tt.cons[T;P;A;S;G]F;.js.ret x}
.js.sub:{[f;z]flip each(1#z;.tt.rows[R]1_z:?[z;();0b;{x!x}h where f(h:cols z)like"*_"])}
.js.obj:{`Z`Z_`G`G_`F`F_`Q`S`R`N!(.js.sub[not]Z;.js.sub[::]Z;G;where["S"=q]except G;F;cols[T]except G,F;q:.tt.qtype T;`cols`sorts!(key S;get S);R;count Z)}
.js.sub:{flip each(1#x;.tt.rows[R]1_x)}
.js.obj:{`Z`G`H`F`I`Q`S`R`N!(.js.sub Z;G;H;F;I;.tt.qtype T;`cols`sorts!(key S;get S);R;count Z)}
.js.ret:{x,.js.obj[]}
.js.upd:{if[not null W;t:.z.z;.js.snd .js.set()!();.js.log[t]`upd]}
.js.ups:{if[not null W;t:.z.z;`Z set 0!(`n_ xkey Z)upsert`n_ xkey .tt.cons[T;P;A;S;G]x;.js.snd .js.ret()!();.js.log[t]`ups]}
Binary file added q/s2.zip
Binary file not shown.
16 changes: 13 additions & 3 deletions q/s2/t.q
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
\d .tt

/ construct treetable
cons:{[t;p;a;s;g;f]cons_[csub[t]g,f;p;(f inter key a)#a;s]. ungrp[t;g]f}
cons:{[t;p;a;s;g;f]cons_[csub[csym[t]g]g,f;p;(f inter key a)#a;s]. ungrp[t;g]f}
cons_:{[t;p;a;s;g;f]0!ctl[1!(0!d)tsort[d:dat[t;p;rollups[t;g]a;g]f,`s_]s;p]g}

/ symbolize non-symbolic grouping fields
csym:{[t;g]![t;();0b;h!(`$string@;)each h:.tt.csym_[t]g]}
csym_:{[t;g]exec c from meta?[t;();0b;g!g]where t<>"s"}

/ flatten if keys in G
ungrp:{[t;g;f]if[all keys[t]in g;f:distinct g,f;g:0#`];(g;f)}

Expand Down Expand Up @@ -110,11 +114,17 @@ take:{[v;s;e]$[s>=count v;0#v;((1+e-s)&count z)#z:s _ v]}

// globals

/ visible order
F::cols[T]except G

/ group by
G:()

/ visible order
F::cols[T]except G
/ groupable
H::exec c from meta get T where t in"bhijspmdznuvt"

/ invisible
I::cols[T]except G,F

/ rollups
A:()!()
Expand Down
1 change: 1 addition & 0 deletions q/s2/u.q
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ T:([tradeId:til n]
time:09:30:00.0+n?23000000)

G:`sector`trader`strategy
F:`symbol`price`quantity
A[`price]:(avg;`price)
A[`tradeId]:(.tt.nul;`tradeId)

Expand Down
5 changes: 2 additions & 3 deletions q/s2/w.q
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ W:0Ni

/ utilities

.js.elt:{`time$"z"$.z.z-x}
.js.sym:{$[(t:abs type x)in 0 99h;.z.s each x;10=t;`$x;x]}
.js.exe:{.js[x`fn]x}
.js.set:{`Z set .tt.cons[T;P;A;S;G]F;.js.ret x}
.js.sub:{[f;z]flip each(1#z;.tt.rows[R]1_z:?[z;();0b;{x!x}h where f(h:cols z)like"*_"])}
.js.obj:{`Z`Z_`G`G_`F`F_`Q`S`R`N!(.js.sub[not]Z;.js.sub[::]Z;G;where["S"=q]except G;F;cols[T]except G,F;q:.tt.qtype T;`cols`sorts!(key S;get S);R;count Z)}
.js.sub:{flip each(1#x;.tt.rows[R]1_x)}
.js.obj:{`Z`G`H`F`I`Q`S`R`N!(.js.sub Z;G;H;F;I;.tt.qtype T;`cols`sorts!(key S;get S);R;count Z)}
.js.ret:{x,.js.obj[]}
.js.upd:{if[not null W;neg[W].js.set()!()]}
.js.ups:{if[not null W;`Z set 0!(`n_ xkey Z)upsert`n_ xkey .tt.cons[T;P;A;S;G]x;neg[W].js.ret()!()]}
Loading

0 comments on commit b671b89

Please sign in to comment.