@@ -26,6 +26,7 @@ struct D3Tree
26
26
link_style:: Vector{String}
27
27
title:: String
28
28
options:: Dict{Symbol,Any}
29
+ frender:: NamedTuple{(:text, :tooltip, :style, :link_style)}
29
30
end
30
31
31
32
"""
@@ -92,10 +93,10 @@ Construct a tree to be displayed using D3 in a browser or ipython notebook, spec
92
93
creates a tree with four nodes. Nodes 2 and 3 are children of node 1, and node 4 is the only child of node 3. Nodes 2 and 4 are childless.
93
94
94
95
## Keyword:
95
- - `text::Vector{String} ` - text to appear under each node.
96
- - `tooltip::Vector{String} ` - text to appear when hovering over each node.
97
- - `style::Vector{String} ` - html style for each node.
98
- - `link_style::Vector{String} ` - html style for each link.
96
+ - `text::Union{AbstractVector{<:AbstractString},Base.Callable} ` - text to appear under each node, resp. a function `text(node)` to generate it .
97
+ - `tooltip::Union{AbstractVector{<:AbstractString},Base.Callable} ` - text to appear when hovering over each node or a function .
98
+ - `style::Union{AbstractVector{<:AbstractString},Base.Callable} ` - html style for each node or a function .
99
+ - `link_style::Union{AbstractVector{<:AbstractString},Base.Callable} ` - html style for each link or a function .
99
100
- `title::String` - html title.
100
101
- `init_expand::Integer`: (default `0`) - levels to expand initially.
101
102
- `init_duration::Number`: (default `750`) - duration of the initial animation in ms.
@@ -106,14 +107,64 @@ Construct a tree to be displayed using D3 in a browser or ipython notebook, spec
106
107
function D3Tree (children:: AbstractVector{<:AbstractVector} ; kwargs... )
107
108
kwd = Dict (kwargs)
108
109
n = length (children)
110
+
111
+ v_text, f_text = if haskey (kwd, :text )
112
+ kw_text = kwd[:text ]
113
+ if kw_text isa Base. AbstractVector
114
+ convert (Vector{String}, kw_text), text
115
+ elseif kw_text isa Base. Callable
116
+ fill (" " , n), kw_text
117
+ else
118
+ throw (ArgumentError (" D3Tree kwwarg text must be an AbstractVector{<:AbstractString} or a Base.Callable" ))
119
+ end
120
+ else
121
+ collect (string (i) for i in 1 : n), text
122
+ end
123
+
124
+ v_tooltip, f_tooltip = if haskey (kwd, :tooltip )
125
+ kw_tooltip = kwd[:tooltip ]
126
+ if kw_tooltip isa Base. AbstractVector
127
+ convert (Vector{String}, kw_tooltip), tooltip
128
+ elseif kw_tooltip isa Base. Callable
129
+ fill (" " , n), kw_tooltip
130
+ else throw (ArgumentError (" D3Tree kwwarg tooltip must be an AbstractVector{<:AbstractString} or a Base.Callable" ))
131
+ end
132
+ else
133
+ fill (" " , n), tooltip
134
+ end
135
+
136
+ v_style, f_style = if haskey (kwd, :style )
137
+ kw_style = kwd[:style ]
138
+ if kw_style isa Base. AbstractVector
139
+ convert (Vector{String}, kw_style), style
140
+ elseif kw_style isa Base. Callable
141
+ fill (" " , n), kw_style
142
+ else throw (ArgumentError (" D3Tree kwwarg style must be an AbstractVector{<:AbstractString} or a Base.Callable" ))
143
+ end
144
+ else
145
+ fill (" " , n), style
146
+ end
147
+
148
+ v_link_style, f_link_style = if haskey (kwd, :link_style )
149
+ kw_link_style = kwd[:link_style ]
150
+ if kw_link_style isa Base. AbstractVector
151
+ convert (Vector{String}, kw_link_style), link_style
152
+ elseif kw_link_style isa Base. Callable
153
+ fill (" " , n), kw_link_style
154
+ else throw (ArgumentError (" D3Tree kwwarg link_style must be an AbstractVector{<:AbstractString} or a Base.Callable" ))
155
+ end
156
+ else
157
+ fill (" " , n), link_style
158
+ end
159
+
160
+ frender = (text = f_text, tooltip = f_tooltip, style = f_style, link_style = f_link_style)
161
+
109
162
return D3Tree (children,
110
163
Dict (),
111
- get (kwd, :text , collect (string (i) for i in 1 : n)),
112
- get (kwd, :tooltip , fill (" " , n)),
113
- get (kwd, :style , fill (" " , n)),
114
- get (kwd, :link_style , fill (" " , n)),
164
+ v_text, v_tooltip, v_style, v_link_style,
115
165
get (kwd, :title , " Julia D3Tree" ),
116
166
convert (Dict{Symbol,Any}, kwd),
167
+ frender,
117
168
)
118
169
end
119
170
@@ -183,10 +234,10 @@ function push_node!(t::D3Tree, node, lazy_expand_after_depth::Int, node_dict=not
183
234
end
184
235
185
236
push! (t. children, Int[])
186
- push! (t. text, text (node))
187
- push! (t. tooltip, tooltip (node))
188
- push! (t. style, style (node))
189
- push! (t. link_style, link_style (node))
237
+ push! (t. text, t . frender . text (node))
238
+ push! (t. tooltip, t . frender . tooltip (node))
239
+ push! (t. style, t . frender . style (node))
240
+ push! (t. link_style, t . frender . link_style (node))
190
241
191
242
if lazy_expand_after_depth > 0
192
243
for c in children (node)
@@ -219,7 +270,8 @@ struct D3OffsetSubtree
219
270
subtree. style[2 : end ],
220
271
subtree. link_style[2 : end ],
221
272
subtree. title,
222
- subtree. options
273
+ subtree. options,
274
+ subtree. frender
223
275
)
224
276
new (root_children, offset_subtree, root_id)
225
277
end
@@ -234,7 +286,7 @@ function expand_node!(t::D3Tree, ind::Int, lazy_expand_after_depth::Int)
234
286
node = pop! (t. unexpanded_children, ind)
235
287
236
288
# TODO : also pass other options from t?
237
- subtree = D3Tree (node; lazy_expand_after_depth= lazy_expand_after_depth)
289
+ subtree = D3Tree (node; lazy_expand_after_depth= lazy_expand_after_depth, t . options ... )
238
290
offset = length (t. children) - 1
239
291
240
292
offset_subtree = D3OffsetSubtree (ind, subtree, offset)
0 commit comments