Skip to content

Commit

Permalink
dnd column editing
Browse files Browse the repository at this point in the history
  • Loading branch information
stevewirts committed Feb 15, 2015
1 parent d110c29 commit 7a00b18
Show file tree
Hide file tree
Showing 15 changed files with 438 additions and 98 deletions.
46 changes: 30 additions & 16 deletions behaviors/fin-hypergrid-behavior-qtree.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@
ready: function() {
this.block = {
N: 0,
H: [],
F: [],
G: [],
S: {
cols: [],
rows: []
},
Z_:[{
h_:['']
g_:['']
}]
};
this.readyInit();
Expand All @@ -103,7 +103,7 @@
var provider = document.createElement('fin-hypergrid-cell-provider');
provider.getCell = function(config) {
var cell = provider.cellCache.simpleCellRenderer;
var colId = self.block.H[config.x];
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);
Expand All @@ -122,7 +122,7 @@
//config.font = config.properties.font;
config.fgColor = config.fgSelColor = config.properties.color;
config.bgColor = config.bgSelColor = config.properties.backgroundColor2;
var colId = self.block.H[config.x];
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]);
Expand Down Expand Up @@ -167,6 +167,12 @@
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);
// if (attrName === 'url') {
Expand Down Expand Up @@ -198,7 +204,7 @@
// if (clone.length === 0) {
// return clone;
// }
var hValue = this.block.Z_[0].h_[0];
var hValue = this.block.Z_[0].g_[0];
var clone = ['Hierarchy', '\u25be ' + hValue];
clone[0] = clone[0] + ' ' + sortIndicator;
return clone;
Expand Down Expand Up @@ -232,7 +238,7 @@

//Virtual column scrolling is not necessary with this GridBehavior because we only hold a small amount of vertical data in memory and most tables in Q are timeseries financial data meaning the are very tall and skinny. We know all the columns from the first page from Q.
getColumnCount: function() {
return this.block.H.length
return this.block.F.length
},

//This is overridden from DefaultGridBehavior. This value is set on us by the OFGrid component on user scrolling.
Expand Down Expand Up @@ -296,7 +302,7 @@
var indentPixels = 10;
var blob = this.block.Z_[1];
var transY = Math.max(0, y - this.scrollPositionY);
var data = blob.h_[transY];
var data = blob.g_[transY];
var indent = 5 + indentPixels + (blob.l_[transY] - 1) * indentPixels;
var icon = '';
if (!blob.e_[transY]) {
Expand Down Expand Up @@ -381,7 +387,7 @@
return alignment;
},
getColumnId: function(x) {
var headers = this.block.H;
var headers = this.block.F;
x = this.translateColumnIndex(x);
var col = headers[x];
return col;
Expand Down Expand Up @@ -425,24 +431,32 @@
this.beColumnStyle(hidden.style);
hidden.style.left = '33.3333%';
hidden.label = 'hidden columns';
hidden.list = this.block.H;
hidden.list = this.block.F_;

this.beColumnStyle(visible.style);
visible.style.left = '66.6666%';
visible.label = 'visible columns';
visible.list = this.block.H_;
visible.list = this.block.F;

//attach for later retrieval
div.lists = {
group: group.list,
hidden: hidden.list,
visible: visible.list
};

div.appendChild(container);
return true;
},
closeEditor: function(div) {
// var nodeClick = {
// id: "abc",
// fn: "groups",
// node: nodes
// };
// this.ws.send(JSON.stringify(nodeClick));
var lists = div.lists;
var changeCols = {
id: "abc",
fn: "groups",
groups: lists.group,
visible: lists.visible
};
this.ws.send(JSON.stringify(changeCols));
return true;
},
beColumnStyle: function(style) {
Expand Down
2 changes: 1 addition & 1 deletion demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +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>
<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>
<br>
<core-splitter direction="up"></core-splitter>
Expand Down
6 changes: 4 additions & 2 deletions features/fin-hypergrid-feature-column-moving.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@
},

handleMouseDown: function(grid, event) {
if (this.isFixedRow(grid, event)) {
this.dragArmed = true;
if (grid.getBehavior().isColumnReorderable()) {
if (this.isFixedRow(grid, event)) {
this.dragArmed = true;
}
}
if (this.next) {
this.next.handleMouseDown(grid, event);
Expand Down
4 changes: 2 additions & 2 deletions fin-hypergrid.min.html

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions q/s1/s1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
single-process treetable server
-------------------------------

u.q creates example table, updates price and quantity
t.q computes simple treetable
w.q websocket interface and hypergrid API

start treetable/web process (port 12345):

cd s1
q u.q
108 changes: 36 additions & 72 deletions q/t.q → q/s1/t.q
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,39 @@
\d .tt

/ construct treetable
cons:{[t;p;a;s;g;h]cons_[csub[t]g,h;p;(h inter key a)#a;s]. ungrp[t;g]h}

cons_:{[t;p;a;s;g;h]
d:dat[t;p;rollups[t;g]a;g]h,`s_;
d:1!(0!d)tsort[d]s;
z:get d;z_:ctl[z;d;p]g;
(delete s_ from z;z_)}
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]0!ctl[1!(0!d)tsort[d:dat[t;p;rollups[t;g]a;g]f,`s_]s;p]g}

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

/ column subset
csub:{[t;f]![?[t;();0b;f!f];();0b;(1#`s_)!1#1]}

/ block of rows
rows:{[r;v]take[v]. r`start`end}
take:{[v;s;e]$[s>=count v;0#v;((1+e-s)&count z)#z:s _ v]}

/ data table (serial/parallel)
dat:{[t;p;a;g;h]key[z]!flip h!get[z:1!`n_ xasc$[system"s";pdat;sdat][t;g;a]visible p]h}
sdat:{[t;g;a;p]root[t;g;a]block[t;g;a]/p}
pdat:{[t;g;a;p]root[t;g;a],raze block[t;g;a;()]peach p}

/ control table
ctl:{[z;t;p;g]
c:([]s_:z`s_;n_:key[t]`n_;l_:level t;e_:isleaf[t]g;o_:isopen[t]p);
update p_:.tt.parent n_,h_:.tt.hierarchy'[e_;n_;s_]from c}

/ construct h_
ctl:{[z;p;g]
n_:key[z]`n_;e_:isleaf[n_]g;l_:level n_;o_:isopen[n_]p;p_:parent n_;g_:hierarchy'[e_;n_;get[z]`s_];
update n_:n_,e_:e_,l_:l_,p_:p_,o_:o_,g_:g_ from z}
/ construct g_
hierarchy:{$[x;`;`$string[last y],"[",string[z],"]"]}

/ predicates
isopen:{[t;p](0!p)[`v](get each key[p]`n)?key[t]`n_}
isleaf:{[t;g]level[t]>count g}
isopen:{[n;p](0!p)[`v](get each key[p]`n)?n}
isleaf:{[n;g]level[n]>count g}

/ level of each record
level:{[t]count each key[t]`n_}

/ visible paths
visible:{[p]n where all each(exec v from p)(reverse q scan)each til count q:parent n:exec n from p}
level:{[n]count each n}

/ path-list -> parent-vector
parent:{[n]n?-1_'n}

/ data table (serial/parallel)
dat:{[t;p;a;g;h]key[z]!flip h!get[z:1!`n_ xasc root[t;g;a]block[t;g;a]/visible p]h}

/ visible paths
visible:{[p]n where all each(exec v from p)(reverse q scan)each til count q:parent n:exec n from p}

/ instruction -> constraint
constraint:{[p]flip(=;key p;flip enlist get p)}

Expand Down Expand Up @@ -84,7 +73,7 @@ at:{[b;p;g;n]p,([n:enlist(count[n]#g)!n,()]v:enlist b)}
tsort:{[t;o]
n:exec n_ from t;
i:children[parent n]except enlist();
f:{x((abs;lower)type[y]in 10 11h)y};
f:{x$[not t:type y;::;t in 10 11h;lower;abs]y};
j:msort[0!t;key o;(`a`d`A`D!(iasc;idesc;f iasc;f idesc))get o]each i;
n?pmesh over n j}

Expand All @@ -97,69 +86,39 @@ msort:{[t;c;o;i]i{x y z x}/[til count i;o;flip[t i]c]}
/ mesh nest of paths
pmesh:{i:1+x?-1_first y;(i#x),y,i _ x}

/ first if 1=count else null
/ rollup: first if 1=count else null
nul:{first$[1=count distinct x,();x;0#x]}

/ first if 1=count else (first
fpo:{$[1=count distinct x;first x;`$string[first x],"+"]}
/ rollup: first if 1=count else
seq:{$[1=count distinct x;first x;`$string[first x],"+"]}

/ type -> rollup
A:" bgxhijefcspmdznuvt"!(null;any;null;null;sum;sum;sum;sum;sum;nul;fpo;max;max;max;max;max;max;max;max)
A:" bgxhijefcspmdznuvt"!(nul;any;nul;nul;sum;sum;sum;sum;sum;nul;seq;max;max;max;max;max;max;max;max)

/ default rollups
rollups:{[t;g;a]@[@[a;k;:;A[lower qtype[t]k],'k:cols[t]except g,key a];`s_,g;:;enlist[(sum;`s_)],nul,'g]}
/ rollups
rollups:{[t;g;a]@[rollups_[t]a;`s_,g;:;enlist[(sum;`s_)],nul,'g]}
rollups_:{[t;a]@[a;k;:;A[lower qtype[t]k],'k:cols[t]except key a]}

/ cast <- type
qtype:{exec c!t from meta x}

\d .

// websocket communications

WS:0Ni

$[.z.K<3.3;
[.z.pc:{[w]if[w=WS;WS::0Ni]};
.z.po:{WS::.z.w;.js.set()!()}];
[.z.wc:{[w]if[w=WS;WS::0Ni]};
.z.wo:{WS::.z.w;.js.set()!()}]];

.z.ws:{t:.z.z;.js.snd .js.exe .js.sym a:.j.k x;.js.log[t]a}

/ entry points

.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,'Z_]S;Z@:i;Z_@:i;.js.ret d}
.js.groups:{[d]`H`G set 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
/ block of rows
rows:{[r;v]take[v]. r`start`end}
take:{[v;s;e]$[s>=count v;0#v;((1+e-s)&count z)#z:s _ v]}

.js.log:{0N!(.js.elt x;y);}
.js.snd:{neg[WS].j.j x}
.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.upd:{if[not null WS;t:.z.z;.js.snd .js.set()!();.js.log[t]`upd]}
.js.set:{`Z`Z_ set'.tt.cons[T;P;A;S;G]H;.js.ret x}
.js.sub:{[z]flip each(1#z;.tt.rows[R]1_z)}
.js.obj:{`Z`Z_`G`G_`H`H_`Q`S`R`N!(.js.sub Z;.js.sub Z_;G;where["S"=q]except G;H;cols[T]except G,H;q:.tt.qtype T;`cols`sorts!(key S;get S);R;count Z)}
.js.ret:{x,.js.obj[]}
\d .

// globals

/ group by
G:0#`
G:()

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

/ rollups
A:()!()

/ updates (update, append, delete)
U:(1#sum)!enlist`u`a`d!({x+y-z};+;-)

/ instruction state
P:([n:enlist(0#`)!0#`]v:enlist 1b)

Expand All @@ -168,3 +127,8 @@ R:`start`end!0 100

/ sorts (a,d)
S:()!()

\
/ parallel
dat:{[t;p;a;g;h]key[z]!flip h!get[z:1!`n_ xasc root[t;g;a],raze block[t;g;a;()]peach visible p]h}
40 changes: 40 additions & 0 deletions q/s1/u.q
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/// copyright stevan apter 2004-2015

\e 1
\p 12345
\P 14
\c 25 150
\t 2000

\l t.q
\l w.q

// example

holdingId:`abcde`bcdef`cdefgh`defgh`efghi`fghij`ghijk
symbol:`msft`amat`csco`intc`yhoo`aapl
trader:`chico`harpo`groucho`zeppo`moe`larry`curly`shemp`abbott`costello
sector:`energy`materials`industrials`financials`healthcare`utilities`infotech
strategy:`statarb`pairs`mergerarb`house`chart`indexarb

n:1000000
T:([tradeId:til n]
holdingId:n?holdingId;
symbol:n?symbol;
sector:n?sector;
trader:n?trader;
strategy:n?strategy;
price:50+.23*n?400;
quantity:(100*10+n?20)-2000;
date:2000.01.01+asc n?365;
time:09:30:00.0+n?23000000)

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

/ define Z
.js.set()!();

/ update
.z.ts:{update price:price+-.5+count[T]?1.,quantity:quantity+-5+count[T]?10 from`T;.js.ups`price`quantity;}
Loading

0 comments on commit 7a00b18

Please sign in to comment.