Skip to content

Commit 3f6938e

Browse files
committed
enhance labelling Bar
1 parent b69438b commit 3f6938e

File tree

2 files changed

+62
-20
lines changed

2 files changed

+62
-20
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,7 @@ sgplot(
276276
group=:Ruling,
277277
grouporder=:data,
278278
baselineresponse=:baseline,
279-
baselinestat=IMD.sum,
280279
orderresponse=:baseline,
281-
orderstat=IMD.sum,
282280
outlinethickness=0.1,
283281
legend = :bar_leg,
284282
x2axis=true
@@ -330,7 +328,9 @@ sgplot(
330328

331329
headercolname = false,
332330
headersize=12,
333-
headerfontweight=900,
331+
headerfontweight=900,
332+
333+
height=400,
334334
)
335335
```
336336

src/charts/bar.jl

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ BAR_DEFAULT = Dict{Symbol,Any}(:x => 0, :y => 0, :group => nothing,
2323
:groupdisplay => :stack, #:stack, :cluster, :step (i.e. stacked and cluster), or :none
2424
:grouporder => :ascending, # :data, :ascending, :descending, userdefined order (by giving a vector of group level) - having a group column in panelby can cause some issues
2525
:orderresponse => nothing, # by default axis order control it, but it can be controlled by a column
26-
:orderstat => freq, # freq is default aggregator, however, it can be any other function
26+
:orderstat => nothing, # freq is default aggregator, however, it can be any other function
2727
:baseline => 0,
2828
:baselineresponse => nothing, # each bar (or each group when groupped) can have its own baseline
2929
:baselinestat => nothing, # same rule as :stat
@@ -45,6 +45,7 @@ BAR_DEFAULT = Dict{Symbol,Any}(:x => 0, :y => 0, :group => nothing,
4545
:labeld3format=>"",
4646
:labelopacity=>1,
4747
:labelalign=>nothing,
48+
:labelalternate=>true, # if true, it automatically change the baseline, align and offset of the label text
4849
:tooltip => false, # it can be true, only if labelresponse is provided
4950

5051

@@ -65,15 +66,21 @@ mutable struct Bar <: SGMarks
6566
length(cp_BAR_DEFAULT[:barcorner]) != 4 && throw(ArgumentError("the barcorner option must be a single value or a vector of length four of values"))
6667
end
6768
!(cp_BAR_DEFAULT[:groupdisplay] in (:stack, :none, :cluster, :step)) && throw(ArgumentError("the groupdisplay option can be one of :stack, :cluster, :step, or :none"))
68-
if cp_BAR_DEFAULT[:x] == 0
69-
cp_BAR_DEFAULT[:labelbaseline] = something(cp_BAR_DEFAULT[:labelbaseline], :middle)
70-
_tmp_align = Dict(:end=>:right, :start=>:left, :middle=>:center)
71-
cp_BAR_DEFAULT[:labelalign] = something(cp_BAR_DEFAULT[:labelalign], _tmp_align[cp_BAR_DEFAULT[:labelpos]])
72-
73-
else
74-
_tmp_align = Dict(:end=>:top, :start=>:bottom, :middle=>:middle)
75-
cp_BAR_DEFAULT[:labelbaseline] = something(cp_BAR_DEFAULT[:labelbaseline], _tmp_align[cp_BAR_DEFAULT[:labelpos]])
76-
cp_BAR_DEFAULT[:labelalign] = something(cp_BAR_DEFAULT[:labelalign], :center)
69+
70+
if cp_BAR_DEFAULT[:colorresponse] !== nothing
71+
cp_BAR_DEFAULT[:colorstat] = something(cp_BAR_DEFAULT[:colorstat], IMD.sum)
72+
end
73+
if cp_BAR_DEFAULT[:baselineresponse] !== nothing
74+
cp_BAR_DEFAULT[:baselinestat] = something(cp_BAR_DEFAULT[:baselinestat], IMD.sum)
75+
end
76+
if cp_BAR_DEFAULT[:orderresponse] !== nothing
77+
cp_BAR_DEFAULT[:orderstat] = something(cp_BAR_DEFAULT[:orderstat], IMD.sum)
78+
end
79+
if isequal(cp_BAR_DEFAULT[:label], true)
80+
cp_BAR_DEFAULT[:label] = :height
81+
end
82+
if isequal(cp_BAR_DEFAULT[:label], false)
83+
cp_BAR_DEFAULT[:label] = :none
7784
end
7885
new(cp_BAR_DEFAULT)
7986
end
@@ -240,7 +247,7 @@ function _push_plots!(vspec, plt::Bar, all_args; idx=1)
240247
push!(vspec[:marks], s_spec)
241248
if opts[:label] in (:height, :category)
242249
whole_mk = deepcopy(s_spec)
243-
_segment_label!(whole_mk[:marks][1], _var_, _var_2_, all_args, opts)
250+
_segment_label!(whole_mk[:marks][1], _var_, _var_2_, all_args, opts, idx)
244251
push!(vspec[:marks], whole_mk)
245252
end
246253

@@ -319,6 +326,12 @@ function _check_and_normalize!(plt::Bar, all_args)
319326
base_stat = opts[:baselinestat]
320327
end
321328

329+
if opts[:orderresponse] === nothing
330+
opts[:orderstat] = freq
331+
else
332+
opts[:orderstat] = opts[:orderstat]
333+
end
334+
322335
if all_args.mapformats
323336
_f = getformat(ds, col)
324337
else
@@ -512,7 +525,21 @@ function _add_legends!(plt::Bar, all_args, idx)
512525
end
513526

514527

515-
function _segment_label!(mk, cat, var, all_args, opts)
528+
function _segment_label!(mk, cat, var, all_args, opts, idx)
529+
530+
if opts[:x] == 0
531+
opts[:labelbaseline] = something(opts[:labelbaseline], :middle)
532+
_tmp_align = Dict(:end=>:right, :start=>:left, :middle=>:center)
533+
opts[:labelalign] = something(opts[:labelalign], _tmp_align[opts[:labelpos]])
534+
535+
else
536+
_tmp_align = Dict(:end=>:top, :start=>:bottom, :middle=>:middle)
537+
opts[:labelbaseline] = something(opts[:labelbaseline], _tmp_align[opts[:labelpos]])
538+
opts[:labelalign] = something(opts[:labelalign], :center)
539+
end
540+
# if opts[:labelalternate] is passed this can help to adjust text position
541+
_opp = Dict(:top=>:bottom, :bottom=>:top, :middle=>:middle, :left=>:right, :right=>:left, :center=>:center, :alphabetic=>:alphabetic)
542+
516543
mk[:type] = "text"
517544

518545
mk_encode = mk[:encode][:enter]
@@ -524,6 +551,8 @@ function _segment_label!(mk, cat, var, all_args, opts)
524551
mk_encode[:opacity] = Dict{Symbol, Any}(:value => opts[:labelopacity])
525552
if opts[:labelcolor] == :auto && opts[:group] !== nothing
526553
mk_encode[:fill] = Dict{Symbol, Any}(:signal => "isValid(datum['__height__bar__']) ? contrast('black', scale('group_scale', datum['$(opts[:group])'])) > contrast('white', scale('group_scale', datum['$(opts[:group])'])) ? 'black' : 'white' : 'transparent'" )
554+
elseif opts[:labelcolor] == :auto && opts[:colorresponse] !== nothing
555+
mk_encode[:fill] = Dict{Symbol, Any}(:signal => "isValid(datum['__height__bar__']) ? contrast('black', scale('color_scale_$idx', datum['__color__value__'])) > contrast('white', scale('color_scale_$idx', datum['__color__value__'])) ? 'black' : 'white' : 'transparent'" )
527556
else
528557
if opts[:labelcolor] == :auto
529558
opts[:labelcolor] = :black
@@ -545,8 +574,11 @@ function _segment_label!(mk, cat, var, all_args, opts)
545574
end
546575
end
547576

548-
549-
mk_encode[var][:offset] = opts[:labeloffset]
577+
if opts[:labelalternate]
578+
mk_encode[var][:offset] = Dict{Symbol, Any}(:signal => "(datum['__height__bar__'] - datum['__height__bar__start__']) < 0 ? -1*$(opts[:labeloffset]) : $(opts[:labeloffset])")
579+
else
580+
mk_encode[var][:offset] = opts[:labeloffset]
581+
end
550582
if opts[:labelpos] == :end
551583
mk_encode[var][:field] = "__height__bar__"
552584
elseif opts[:labelpos] == :start
@@ -559,12 +591,22 @@ function _segment_label!(mk, cat, var, all_args, opts)
559591
mk_encode[cat][:band] = opts[:labelloc]
560592

561593
if opts[:labelangle] !== nothing
562-
mk_encode[:angle] = Dict{Symbol, Any}(:value => opts[:labelangle])
594+
if opts[:labelalternate]
595+
mk_encode[:angle] = Dict{Symbol, Any}(:signal => "(datum['__height__bar__'] - datum['__height__bar__start__']) < 0 ? -1*$(opts[:labelangle]) : $(opts[:labelangle])")
596+
else
597+
mk_encode[:angle] = Dict{Symbol, Any}(:value => opts[:labelangle])
598+
end
563599
end
564-
if opts[:labelalign] !== nothing
600+
if opts[:labelalternate] && opts[:y] != 0
601+
mk_encode[:align] = Dict{Symbol, Any}(:signal => "(datum['__height__bar__'] - datum['__height__bar__start__']) < 0 ? '$(_opp[opts[:labelalign]])' : '$(opts[:labelalign])'")
602+
else
565603
mk_encode[:align] = Dict{Symbol, Any}(:value => opts[:labelalign])
566604
end
567-
mk_encode[:baseline] = Dict{Symbol, Any}(:value => opts[:labelbaseline])
605+
if opts[:labelalternate] && opts[:x] != 0
606+
mk_encode[:baseline] = Dict{Symbol, Any}(:signal => "(datum['__height__bar__'] - datum['__height__bar__start__']) < 0 ? '$(_opp[opts[:labelbaseline]])' : '$(opts[:labelbaseline])'")
607+
else
608+
mk_encode[:baseline] = Dict{Symbol, Any}(:value => opts[:labelbaseline])
609+
end
568610
mk_encode[:font] = Dict{Symbol, Any}(:value => something(opts[:labelfont], all_args.opts[:font]))
569611
mk_encode[:fontWeight] = Dict{Symbol, Any}(:value => something(opts[:labelfontweight], all_args.opts[:fontweight]))
570612
mk_encode[:fontStyle] = Dict{Symbol, Any}(:value => something(opts[:labelitalic], all_args.opts[:italic] ? "italic" : "normal"))

0 commit comments

Comments
 (0)