Skip to content

Commit 22cd2cd

Browse files
committed
ensure type stability of dataframe columns during parsing (except allowmissing)
1 parent 306101c commit 22cd2cd

1 file changed

Lines changed: 45 additions & 15 deletions

File tree

src/StippleActiveTables.jl

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ module StippleActiveTables
22

33
using Stipple
44
using Stipple: flexgrid_kwargs
5-
import Stipple.Genie
65
import Stipple.Genie.Renderer.Html: normal_element, register_normal_element, script
76

87
using DataFrames
@@ -12,40 +11,71 @@ export ActiveTable, activetable
1211
const assets_config = Genie.Assets.AssetsConfig(package = "StippleActiveTables.jl")
1312

1413
function deps() :: Vector{String}
15-
[script(type = "module", src = Genie.Assets.asset_path(assets_config, :js, file="activeTable.bundle"))]
14+
[script(type = "module", src = Genie.Assets.asset_path(assets_config, :js, file = "activeTable.bundle"))]
1615
end
1716

1817
function deps_routes(; basedir = @__DIR__) :: Nothing
1918
if !Genie.Assets.external_assets(assets_config)
20-
Genie.Assets.add_fileroute(assets_config, "activeTable.bundle.js"; basedir = joinpath(dirname(basedir), "assets"))
19+
Genie.Assets.add_fileroute(assets_config, "activeTable.bundle.js"; basedir = normpath(joinpath(@__DIR__, "..")))
2120
end
2221

2322
nothing
2423
end
2524

26-
function __init__()
27-
deps_routes()
28-
end
29-
3025
mutable struct ActiveTable
3126
data::DataFrame
3227
end
3328

34-
function Stipple.stipple_parse(::Type{ActiveTable}, v::Vector)
35-
isempty(v) && return DataFrame
36-
matrix = reduce(hcat, v[2:end])
37-
ActiveTable(DataFrame([[matrix[i, :]...] for i in 1:size(matrix, 1)], v[1]))
29+
register_normal_element("active__table", context = @__MODULE__)
30+
31+
function activetable(data::Symbol, args...; kwargs...)
32+
kwargs = Stipple.attributes(flexgrid_kwargs(; data, kwargs...))
33+
active__table(args...; kwargs...)
3834
end
3935

4036
function Stipple.render(at::ActiveTable)
4137
vcat([names(at.data)], [Matrix(at.data)[i, :] for i in 1:nrow(at.data)])
4238
end
4339

44-
register_normal_element("active__table", context = @__MODULE__)
40+
function Stipple.stipple_parse(::Type{ActiveTable}, v::Vector)
41+
ActiveTable(DataFrame(permutedims(reduce(hcat, v[2:end])), v[1]))
42+
end
4543

46-
function activetable(data::Symbol, args...; kwargs...)
47-
kwargs = Stipple.attributes(flexgrid_kwargs(; data, kwargs...))
48-
active__table(:active__table, args...; kwargs...)
44+
function Stipple.convertvalue(activetable::Union{Ref{ActiveTable}, R{ActiveTable}}, v::Vector)
45+
df_new = Stipple.stipple_parse(ActiveTable, v).data
46+
df = activetable[].data
47+
nn = names(df)
48+
nn_new = names(df_new)
49+
nn = intersect(nn, nn_new)
50+
for n in nn
51+
T = nonmissingtype(eltype(df[:, n]))
52+
resize!(df, nrow(df_new))
53+
for i in 1:nrow(df_new)
54+
x = df_new[i, n]
55+
df[i, n] = if T <: AbstractString
56+
x
57+
elseif x === missing || x == ""
58+
allowmissing!(df, n)
59+
missing
60+
else
61+
try
62+
Stipple.stipple_parse(T, x)
63+
catch e
64+
@warn "Failed to parse value to type $T, make sure the value is compatible or modify the underlying DataFrame column type".
65+
missing
66+
end
67+
end
68+
end
69+
end
70+
for n in setdiff(nn_new, nn)
71+
df[!, n] = string.(df_new[:, n])
72+
end
73+
select!(df, nn_new)
74+
activetable
75+
end
76+
77+
function __init__()
78+
deps_routes()
4979
end
5080

5181
end # module StippleActiveTables

0 commit comments

Comments
 (0)