@@ -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)
512525end
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