From bb2d585c6c61a15813abebc13e34fd829b4a90b9 Mon Sep 17 00:00:00 2001 From: Alexander Shutov Date: Fri, 23 Dec 2016 17:39:32 +0300 Subject: [PATCH] Put bar label outside or inside if overflow. --- src/elements/decorators/layer-labels-rules.js | 53 +++++++++++++++++++ src/elements/element.interval.js | 8 +-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/elements/decorators/layer-labels-rules.js b/src/elements/decorators/layer-labels-rules.js index 27c900976..a399f966d 100644 --- a/src/elements/decorators/layer-labels-rules.js +++ b/src/elements/decorators/layer-labels-rules.js @@ -1,3 +1,4 @@ +import {LayerLabelsModel} from './layer-labels-model'; var rules = {}; export class LayerLabelsRules { @@ -211,6 +212,58 @@ LayerLabelsRules }; }) + .regRule('outside-then-inside-horizontal', (prev, args) => { + + var outer = ['r+', 'l-'] + .map(LayerLabelsRules.getRule) + .reduce((p, r) => LayerLabelsModel.compose(p, r(p, args)), prev); + + var inner = ['r-', 'l+', 'hide-by-label-height-horizontal', 'cut-label-horizontal'] + .map(LayerLabelsRules.getRule) + .reduce((p, r) => LayerLabelsModel.compose(p, r(p, args)), prev); + + var overflow = (row) => { + var x = (outer.x(row) + outer.dx(row)); + var half = (outer.w(row) / 2); + return ((x - half < 0) || (x + half > args.maxWidth)); + }; + + return Object.assign( + {}, + outer, + ['x', 'dx', 'hide', 'label'].reduce((obj, prop) => { + obj[prop] = (row) => ((overflow(row) ? inner : outer)[prop](row)); + return obj; + }, {}) + ); + }) + + .regRule('outside-then-inside-vertical', (prev, args) => { + + var outer = ['t+', 'b-'] + .map(LayerLabelsRules.getRule) + .reduce((p, r) => LayerLabelsModel.compose(p, r(p, args)), prev); + + var inner = ['t-', 'b+', 'hide-by-label-height-vertical', 'cut-label-vertical'] + .map(LayerLabelsRules.getRule) + .reduce((p, r) => LayerLabelsModel.compose(p, r(p, args)), prev); + + var overflow = (row) => { + var y = (outer.y(row) + outer.dy(row)); + var half = (outer.h(row) / 2); + return ((y - half < 0) || (y + half > args.maxHeight)); + }; + + return Object.assign( + {}, + outer, + ['y', 'dy', 'hide', 'label'].reduce((obj, prop) => { + obj[prop] = (row) => ((overflow(row) ? inner : outer)[prop](row)); + return obj; + }, {}) + ); + }) + .regRule('hide-by-label-height-horizontal', (prev) => { return { diff --git a/src/elements/element.interval.js b/src/elements/element.interval.js index 9f5e93431..03b906efe 100644 --- a/src/elements/element.interval.js +++ b/src/elements/element.interval.js @@ -31,7 +31,10 @@ const Interval = { (config.guide.label || {}), { position: (config.flip ? + (config.stack ? ['r-', 'l+', 'hide-by-label-height-horizontal', 'cut-label-horizontal'] : + ['outside-then-inside-horizontal'] + ) : (config.stack ? [ 'rotate-on-size-overflow', @@ -43,10 +46,7 @@ const Interval = { ] : [ 'rotate-on-size-overflow', - 't+', - 'b-', - 'hide-by-label-height-vertical', - 'cut-label-vertical', + 'outside-then-inside-vertical', 'auto:hide-on-label-label-overlap' ] )