Skip to content

Commit 06ef085

Browse files
committed
use Tables.jl interface
and ag-grid
1 parent f911076 commit 06ef085

File tree

2 files changed

+63
-106
lines changed

2 files changed

+63
-106
lines changed

REQUIRE

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
julia 0.6
1+
julia 0.7
22
WebIO
33
JSExpr
4-
JuliaDB
5-
DataValues
4+
Tables
5+
JSON

src/TableView.jl

Lines changed: 60 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,76 @@
11
module TableView
2+
using Tables, WebIO, JSExpr, JSON, Dates
23

3-
using WebIO
4-
using JSExpr
5-
using JuliaDB
6-
using DataValues
4+
function showtable(x; dark = false)
5+
w = Scope(imports=["https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js",
6+
"https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css",
7+
"https://unpkg.com/ag-grid-community/dist/styles/ag-theme-balham$(dark ? "-dark" : "").css",])
78

8-
import JuliaDB: DNDSparse, DNextTable, NextTable
9+
schema = Tables.schema(x)
10+
names = schema.names
11+
types = schema.types
912

10-
function JuliaDB.subtable(t::DNextTable, r)
11-
table(collect(rows(t)[r]), pkey=t.pkey)
12-
end
13-
14-
showna(xs) = xs
15-
function showna(xs::AbstractArray{T}) where {T<:DataValue}
16-
map(xs) do x
17-
isnull(x) ? "NA" : get(x)
18-
end
19-
end
20-
21-
function showna(xs::Columns)
22-
rows(map(showna, columns(xs)))
23-
end
24-
25-
function showtable(t::Union{DNextTable, NextTable}; rows=1:100, colopts=Dict(), kwargs...)
26-
w = Scope(imports=["https://cdnjs.cloudflare.com/ajax/libs/handsontable/0.34.0/handsontable.full.js",
27-
"https://cdnjs.cloudflare.com/ajax/libs/handsontable/0.34.0/handsontable.full.css"])
28-
29-
trunc_rows = max(1, first(rows)):min(length(t), last(rows))
30-
subt = JuliaDB.subtable(t, trunc_rows)
31-
32-
headers = colnames(subt)
33-
cols = [merge(Dict(:data=>n), get(colopts, n, Dict())) for n in headers]
13+
coldefs = [(
14+
headerName = n,
15+
field = n,
16+
type = types[i] <: Union{Missing, T where T <: Number} ? "numericColumn" : nothing,
17+
filter = types[i] <: Union{Missing, T where T <: Dates.Date} ? "agDateColumnFilter" :
18+
types[i] <: Union{Missing, T where T <: Number} ? "agNumberColumnFilter" : nothing
19+
) for (i, n) in enumerate(names)]
3420

3521
options = Dict(
36-
:data => showna(collect(JuliaDB.rows(subt))),
37-
:colHeaders => headers,
38-
:modifyColWidth => @js(w -> w > 300 ? 300 : w),
39-
:modifyRowHeight => @js(h -> h > 60 ? 50 : h),
40-
:manualColumnResize => true,
41-
:manualRowResize => true,
42-
:columns => cols,
43-
:width => 800,
44-
:height => 400,
22+
:rowData => table2json(x),
23+
:columnDefs => coldefs,
24+
:enableSorting => true,
25+
:enableFilter => true,
26+
:enableColResize => true,
27+
:multiSortKey => "ctrl"
4528
)
46-
if (length(t.pkey) > 0 && t.pkey == [1:length(t.pkey);])
47-
options[:fixedColumnsLeft] = length(t.pkey)
48-
end
4929

50-
merge!(options, Dict(kwargs))
51-
52-
handler = @js function (Handsontable)
53-
@var sizefix = document.createElement("style");
54-
sizefix.textContent = """
55-
.htCore td {
56-
white-space:nowrap
57-
}
58-
"""
59-
this.dom.appendChild(sizefix)
60-
this.hot = @new Handsontable(this.dom, $options);
30+
handler = @js function (agGrid)
31+
gridOptions = $options
32+
gridOptions.rowData = JSON.parse(gridOptions.rowData)
33+
this.table = @new agGrid.Grid(this.dom.querySelector("#grid"), gridOptions)
34+
gridOptions.columnApi.autoSizeColumns($names)
6135
end
6236
onimport(w, handler)
63-
w.dom = dom"div"()
37+
w.dom = dom"div#grid"(className = "ag-theme-balham$(dark ? "-dark" : "")",
38+
style=Dict(:position => "absolute",
39+
:top => "0",
40+
:left => "0",
41+
:width => "100%",
42+
:height => "100%",
43+
:minHeight => "200px"))
6444
w
6545
end
6646

67-
function showtable(t::Union{DNDSparse, NDSparse}; rows=1:100, colopts=Dict(), kwargs...)
68-
w = Scope(imports=["https://cdnjs.cloudflare.com/ajax/libs/handsontable/0.34.0/handsontable.full.js",
69-
"https://cdnjs.cloudflare.com/ajax/libs/handsontable/0.34.0/handsontable.full.css"])
70-
data = Observable{Any}(w, "data", [])
71-
72-
trunc_rows = max(1, first(rows)):min(length(t), last(rows))
73-
74-
ks = keys(t)[trunc_rows]
75-
vs = values(t)[trunc_rows]
76-
77-
if !isa(keys(t), Columns)
78-
ks = collect(ks)
79-
vs = collect(vs)
47+
# directly write JSON instead of allocating temporary dicts etc
48+
function table2json(table)
49+
names = Tables.schema(table).names
50+
51+
io = IOBuffer()
52+
print(io, '[')
53+
for row in Tables.rows(table)
54+
print(io, '{')
55+
i = 1
56+
for col in Tables.eachcolumn(row)
57+
JSON.print(io, names[i])
58+
i += 1
59+
print(io, ':')
60+
if col isa Number
61+
JSON.print(io, col)
62+
else
63+
JSON.print(io, sprint(print, col))
64+
end
65+
print(io, ',')
66+
end
67+
skip(io, -1)
68+
print(io, '}')
69+
print(io, ',')
8070
end
71+
skip(io, -1)
72+
print(io, ']')
8173

82-
subt = NDSparse(showna(ks), showna(vs))
83-
84-
headers = colnames(subt)
85-
cols = [merge(Dict(:data=>n), get(colopts, n, Dict())) for n in headers]
86-
87-
options = Dict(
88-
:data => JuliaDB.rows(subt),
89-
:colHeaders => headers,
90-
:fixedColumnsLeft => ndims(t),
91-
:modifyColWidth => @js(w -> w > 300 ? 300 : w),
92-
:modifyRowHeight => @js(h -> h > 60 ? 50 : h),
93-
:manualColumnResize => true,
94-
:manualRowResize => true,
95-
:columns => cols,
96-
:width => 800,
97-
:height => 400,
98-
)
99-
100-
merge!(options, Dict(kwargs))
101-
102-
handler = @js function (Handsontable)
103-
@var sizefix = document.createElement("style");
104-
sizefix.textContent = """
105-
.htCore td {
106-
white-space:nowrap
107-
}
108-
"""
109-
this.dom.appendChild(sizefix)
110-
this.hot = @new Handsontable(this.dom, $options);
111-
end
112-
onimport(w, handler)
113-
w.dom = dom"div"()
114-
w
74+
String(take!(io))
75+
end
11576
end
116-
117-
showtable(t; kwargs...) = showtable(table(t); kwargs...)
118-
119-
end # module

0 commit comments

Comments
 (0)