Vertical Bar Chart with Labels placed Outside-End

by duarteleao

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.19/require.min.js"></script>
<script src="//webdetails.github.io/ccc/charts/lib/amd/require.config.js"></script>
<script src="//webdetails.github.io/ccc/charts/lib/q01-01.js"></script>
<div id="cccExample"></div>

JavaScript

require([
  "ccc/pvc", 
  "ccc/def", 
  "ccc/protovis"
], function(pvc, def, pv) {

  // debug layout
  //def.setDebug(15);

  // Calculates best label placement: outside or inside,
  // according to label.text(), label.font() and label.textMargin().
  // Assumes label.textAngle() is 0.
  // Assumes chart is not Stacked.
  // Assumes chart is vertical.
  
  new pvc.BarChart({
    canvas: "cccExample",
    width:   500,
    height:  450,
    title: "Vertical Bar Chart with labels placed Outside-End",
    animate:    false,
    selectable: true,
    hoverable:  true,
    valuesVisible: true,
    valuesFont: 'bold 11px sans-serif',
    
    // TODO: valuesOverflow should not be taking effect when 
    // valuesAnchor/label_name is a function. 
    // Or, at least, the dynamic value of `label_name` 
    // should be being used...
    // So need to turn this off for now.
    valuesOverflow: 'show',

    // Change labels' colors according to bg color.
		valuesOptimizeLegibility: true,
    
    // Adjusts bottom and top plot paddings to 10% of domain
    // so that labels have some reserved space outside bars.
    // orthoAxisOffset: 0.1,

    // Turn off tick domain rounding, to better see
    // the effect.
    //orthoAxisDomainRoundMode: 'none',

    // Test FixedMax, FixedMin
    //orthoAxisFixedMax: 95,

    label_call: function() {
      this
      .localProperty('labelLayoutInfo')
      .labelLayoutInfo(function(scene) {
      
        var cccContext = this.getContext();
        
        var placeAtTop = scene.getValue() >= 0;

        // TODO: accessing private stuff :-(
        var paddings = cccContext.panel._layoutInfo.paddings;
        var panelRange = cccContext.panel.axes.ortho.scale.range();
        var barMark = cccContext.sign.getAnchoredToMark();

        // Expand the range with the padding,
        // because labels are allowed to overflow the client area.
        // May result in a negative bottom.
        var panelRangePadded = {
          bottom:...