Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move bar transform functions to bar helpers #4391

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions src/traces/bar/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
var isNumeric = require('fast-isnumeric');
var tinycolor = require('tinycolor2');
var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray;
var TEXTPAD = require('./constants').TEXTPAD;

exports.coerceString = function(attributeDefinition, value, defaultValue) {
if(typeof value === 'string') {
Expand Down Expand Up @@ -74,3 +75,154 @@ exports.getLineWidth = function(trace, di) {

return w;
};

exports.dirSign = function(a, b) {
return (a < b) ? 1 : -1;
};

exports.toMoveInsideBar = function(x0, x1, y0, y1, textBB, opts) {
var isHorizontal = !!opts.isHorizontal;
var constrained = !!opts.constrained;
var angle = opts.angle || 0;
var anchor = opts.anchor || 0;

var textWidth = textBB.width;
var textHeight = textBB.height;
var lx = Math.abs(x1 - x0);
var ly = Math.abs(y1 - y0);

var textpad = (
lx > (2 * TEXTPAD) &&
ly > (2 * TEXTPAD)
) ? TEXTPAD : 0;

lx -= 2 * textpad;
ly -= 2 * textpad;

var autoRotate = (angle === 'auto');
var isAutoRotated = false;
if(autoRotate &&
!(textWidth <= lx && textHeight <= ly) &&
(textWidth > lx || textHeight > ly) && (
!(textWidth > ly || textHeight > lx) ||
((textWidth < textHeight) !== (lx < ly))
)) {
isAutoRotated = true;
}

if(isAutoRotated) {
// don't rotate yet only swap bar width with height
var tmp = ly;
ly = lx;
lx = tmp;
}

var rotate = getRotateFromAngle(angle);
var absSin = Math.abs(Math.sin(Math.PI / 180 * rotate));
var absCos = Math.abs(Math.cos(Math.PI / 180 * rotate));

// compute and apply text padding
var dx = Math.max(lx * absCos, ly * absSin);
var dy = Math.max(lx * absSin, ly * absCos);

var scale = (constrained) ?
Math.min(dx / textWidth, dy / textHeight) :
Math.max(absCos, absSin);

scale = Math.min(1, scale);

// compute text and target positions
var targetX = (x0 + x1) / 2;
var targetY = (y0 + y1) / 2;

if(anchor !== 'middle') { // case of 'start' or 'end'
var targetWidth = scale * (isHorizontal !== isAutoRotated ? textHeight : textWidth);
var targetHeight = scale * (isHorizontal !== isAutoRotated ? textWidth : textHeight);
textpad += 0.5 * (targetWidth * absSin + targetHeight * absCos);

if(isHorizontal) {
textpad *= exports.dirSign(x0, x1);
targetX = (anchor === 'start') ? x0 + textpad : x1 - textpad;
} else {
textpad *= exports.dirSign(y0, y1);
targetY = (anchor === 'start') ? y0 + textpad : y1 - textpad;
}
}

var textX = (textBB.left + textBB.right) / 2;
var textY = (textBB.top + textBB.bottom) / 2;

// lastly apply auto rotation
if(isAutoRotated) rotate += 90;

return {
textX: textX,
textY: textY,
targetX: targetX,
targetY: targetY,
scale: scale,
rotate: rotate
};
};

exports.toMoveOutsideBar = function(x0, x1, y0, y1, textBB, opts) {
var isHorizontal = !!opts.isHorizontal;
var constrained = !!opts.constrained;
var angle = opts.angle || 0;

var textWidth = textBB.width;
var textHeight = textBB.height;
var lx = Math.abs(x1 - x0);
var ly = Math.abs(y1 - y0);

var textpad;
// Keep the padding so the text doesn't sit right against
// the bars, but don't factor it into barWidth
if(isHorizontal) {
textpad = (ly > 2 * TEXTPAD) ? TEXTPAD : 0;
} else {
textpad = (lx > 2 * TEXTPAD) ? TEXTPAD : 0;
}

// compute rotate and scale
var scale = 1;
if(constrained) {
scale = (isHorizontal) ?
Math.min(1, ly / textHeight) :
Math.min(1, lx / textWidth);
}

var rotate = getRotateFromAngle(angle);
var absSin = Math.abs(Math.sin(Math.PI / 180 * rotate));
var absCos = Math.abs(Math.cos(Math.PI / 180 * rotate));

// compute text and target positions
var targetWidth = scale * (isHorizontal ? textHeight : textWidth);
var targetHeight = scale * (isHorizontal ? textWidth : textHeight);
textpad += 0.5 * (targetWidth * absSin + targetHeight * absCos);

var targetX = (x0 + x1) / 2;
var targetY = (y0 + y1) / 2;

if(isHorizontal) {
targetX = x1 - textpad * exports.dirSign(x1, x0);
} else {
targetY = y1 + textpad * exports.dirSign(y0, y1);
}

var textX = (textBB.left + textBB.right) / 2;
var textY = (textBB.top + textBB.bottom) / 2;

return {
textX: textX,
textY: textY,
targetX: targetX,
targetY: targetY,
scale: scale,
rotate: rotate
};
};

function getRotateFromAngle(angle) {
return (angle === 'auto') ? 0 : angle;
}
2 changes: 1 addition & 1 deletion src/traces/bar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = {
crossTraceCalc: require('./cross_trace_calc').crossTraceCalc,
colorbar: require('../scatter/marker_colorbar'),
arraysToCalcdata: require('./arrays_to_calcdata'),
plot: require('./plot').plot,
plot: require('./plot'),
style: require('./style').style,
styleOnSelect: require('./style').styleOnSelect,
hoverPoints: require('./hover').hoverPoints,
Expand Down
Loading