Skip to content

indicator: position delta using drawing.bBox #4007

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

Merged
merged 1 commit into from
Jul 2, 2019
Merged
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
2 changes: 1 addition & 1 deletion src/snapshot/tosvg.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module.exports = function toSVG(gd, format, scale) {
// fill whatever container it's displayed in regardless of plot size.
svg.node().style.background = '';

svg.selectAll('text,tspan')
svg.selectAll('text')
.attr({'data-unformatted': null, 'data-math': null})
.each(function() {
var txt = d3.select(this);
Expand Down
3 changes: 2 additions & 1 deletion src/traces/indicator/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ module.exports = {
bulletPadding: 0.025,
innerRadius: 0.75,
valueThickness: 0.5, // thickness of value bars relative to full thickness,
titlePadding: 5
titlePadding: 5,
horizontalPadding: 10
};
108 changes: 59 additions & 49 deletions src/traces/indicator/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ module.exports = function plot(gd, cdModule, transitionOpts, makeOnCompleteCallb
var centerX = size.l + size.w / 2;
var centerY = size.t + size.h / 2;


// Angular gauge size
var radius = Math.min(size.w / 2, size.h); // fill domain
var innerRadius = cn.innerRadius * radius;
Expand Down Expand Up @@ -519,59 +518,31 @@ function drawNumbers(gd, plotGroup, cd, opts) {
var trace = cd[0].trace;
var numbersX = opts.numbersX;
var numbersY = opts.numbersY;
var numbersAnchor = anchor[trace.align || 'center'];
var numbersAlign = trace.align || 'center';
var numbersAnchor = anchor[numbersAlign];

var hasTransition = opts.hasTransition;
var transitionOpts = opts.transitionOpts;
var onComplete = opts.onComplete;

var bignumberFontSize, deltaFontSize;
if(trace._hasNumber) bignumberFontSize = trace.number.font.size;
if(trace._hasDelta) deltaFontSize = trace.delta.font.size;

// Position delta relative to bignumber
var deltaDy = 0;
var deltaX = 0;
var bignumberY = 0;

if(trace._hasDelta && trace._hasNumber) {
if(trace.delta.position === 'bottom') {
deltaDy = deltaFontSize * 1.5;
}
if(trace.delta.position === 'top') {
deltaDy = -bignumberFontSize + MID_SHIFT * deltaFontSize;
}
if(trace.delta.position === 'right') {
deltaX = undefined;
}
if(trace.delta.position === 'left') {
deltaX = undefined;
bignumberY = MID_SHIFT * bignumberFontSize / 2;
}
}
deltaDy -= MID_SHIFT * deltaFontSize;

var numbers = Lib.ensureSingle(plotGroup, 'text', 'numbers');
var numbers = Lib.ensureSingle(plotGroup, 'g', 'numbers');
var bignumberbBox, deltabBox;

var data = [];
if(trace._hasNumber) data.push('number');
if(trace._hasDelta) {
data.push('delta');
if(trace.delta.position === 'left') data.reverse();
}
var sel = numbers.selectAll('tspan').data(data);
sel.enter().append('tspan');
var sel = numbers.selectAll('text').data(data);
sel.enter().append('text');
sel
.attr('text-anchor', function() {return numbersAnchor;})
.attr('class', function(d) { return d;})
.attr('dx', function(d, i) {
// Add padding to the second tspan when it's a one-liner
if(i === 1) {
var pos = trace.delta.position;
if(pos === 'left' || pos === 'right') return 10;
}
return null;
});
.attr('x', null)
.attr('y', null)
.attr('dx', null)
.attr('dy', null);
sel.exit().remove();

function drawBignumber() {
Expand All @@ -581,11 +552,9 @@ function drawNumbers(gd, plotGroup, cd, opts) {
var bignumberSuffix = trace.number.suffix;
var bignumberPrefix = trace.number.prefix;

var number = numbers.select('tspan.number');
var number = numbers.select('text.number');
number
.call(Drawing.font, trace.number.font)
.attr('x', null)
.attr('dy', bignumberY);
.call(Drawing.font, trace.number.font);

if(hasTransition) {
number
Expand All @@ -604,6 +573,11 @@ function drawNumbers(gd, plotGroup, cd, opts) {
} else {
number.text(bignumberPrefix + fmt(cd[0].y) + bignumberSuffix);
}

number.attr('data-unformatted', bignumberPrefix + fmt(cd[0].y) + bignumberSuffix);
bignumberbBox = Drawing.bBox(number.node());

return number;
}

function drawDelta() {
Expand All @@ -622,12 +596,10 @@ function drawNumbers(gd, plotGroup, cd, opts) {
var deltaFill = function(d) {
return d.delta >= 0 ? trace.delta.increasing.color : trace.delta.decreasing.color;
};
var delta = numbers.select('tspan.delta');
var delta = numbers.select('text.delta');
delta
.call(Drawing.font, trace.delta.font)
.call(Color.fill, deltaFill(cd[0]))
.attr('x', deltaX)
.attr('dy', deltaDy);
.call(Color.fill, deltaFill(cd[0]));

if(hasTransition) {
delta
Expand All @@ -650,11 +622,46 @@ function drawNumbers(gd, plotGroup, cd, opts) {
return deltaFormatText(deltaValue(cd[0]));
});
}

delta.attr('data-unformatted', deltaFormatText(deltaValue(cd[0])));
deltabBox = Drawing.bBox(delta.node());

return delta;
}

if(trace._hasDelta) drawDelta();
// Position delta relative to bignumber
var delta;
if(trace._hasDelta) delta = drawDelta();
if(trace._hasNumber) drawBignumber();

if(trace._hasDelta && trace._hasNumber) {
var bignumberCenter = [
(bignumberbBox.left + bignumberbBox.right) / 2,
(bignumberbBox.top + bignumberbBox.bottom) / 2
];
var deltaCenter = [
(deltabBox.left + deltabBox.right) / 2,
(deltabBox.top + deltabBox.bottom) / 2
];

if(trace.delta.position === 'left') {
delta.attr('dx', bignumberbBox.left - deltabBox.right - cn.horizontalPadding);
delta.attr('dy', bignumberCenter[1] - deltaCenter[1]);
}
if(trace.delta.position === 'right') {
delta.attr('dx', bignumberbBox.right - deltabBox.left + cn.horizontalPadding);
delta.attr('dy', bignumberCenter[1] - deltaCenter[1]);
}
if(trace.delta.position === 'bottom') {
delta.attr('dx', null);
delta.attr('dy', deltabBox.height);
}
if(trace.delta.position === 'top') {
delta.attr('dx', null);
delta.attr('dy', bignumberbBox.top);
}
}

// Resize numbers to fit within space and position
numbers.attr('transform', function() {
var m = opts.numbersScaler(numbers);
Expand All @@ -677,7 +684,10 @@ function drawNumbers(gd, plotGroup, cd, opts) {
// Stash the top position of numbersbBox for title positioning
trace._numbersTop = scaleRatio * (numbersbBox.top) + translateY;

return strTranslate(numbersX, translateY) + ' scale(' + scaleRatio + ')';
var ref = numbersbBox[numbersAlign];
if(numbersAlign === 'center') ref = (numbersbBox.left + numbersbBox.right) / 2;
var translateX = numbersX - scaleRatio * ref;
return strTranslate(translateX, translateY) + ' scale(' + scaleRatio + ')';
});
}

Expand Down
Binary file modified test/image/baselines/gl3d_indicator_scatter3d.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_bignumber.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_bullet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_datacard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_datacard2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/image/baselines/indicator_datacard3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_gauge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_grid_template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/indicator_scatter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 0 additions & 4 deletions test/image/mocks/indicator_datacard.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"type": "indicator",
"mode": "number+delta",
"number": {
"align": "middle",
"suffix": " km/h"
},
"value": 43,
Expand All @@ -17,7 +16,6 @@
"type": "indicator",
"mode": "number+delta",
"number": {
"align": "middle",
"suffix": " km/h"
},
"value": 43,
Expand All @@ -30,7 +28,6 @@
"type": "indicator",
"mode": "number+delta",
"number": {
"align": "middle",
"suffix": " km/h"
},
"value": 43,
Expand All @@ -43,7 +40,6 @@
"type": "indicator",
"mode": "number+delta",
"number": {
"align": "middle",
"suffix": " km/h"
},
"value": 43,
Expand Down
140 changes: 140 additions & 0 deletions test/image/mocks/indicator_datacard3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
"data": [{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice mock!

For reference, on master this mock looks like

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks fine on master but if you change the font-size of delta or number, the alignment might break.

"type": "indicator",
"domain": {"row": 0, "column": 0},
"delta": {"position": "left"},
"align": "left"
}, {
"type": "indicator",
"domain": {"x": [0.05, 0.5], "y": [0.15, 0.35]},
"domain": {"row": 0, "column": 1},
"delta": {"position": "top"},
"align": "left"
}, {
"type": "indicator",
"domain": {"row": 0, "column": 2},
"delta": {"position": "right"},
"align": "left"
}, {
"type": "indicator",
"domain": {"row": 0, "column": 3},
"delta": {"position": "bottom"},
"align": "left"
},

{
"type": "indicator",
"domain": {"row": 1, "column": 0},
"delta": {"position": "left"},
"align": "center"
}, {
"type": "indicator",
"domain": {"x": [0.05, 0.5], "y": [0.15, 0.35]},
"domain": {"row": 1, "column": 1},
"delta": {"position": "top"},
"align": "center"
}, {
"type": "indicator",
"domain": {"row": 1, "column": 2},
"delta": {"position": "right"},
"align": "center"
}, {
"type": "indicator",
"domain": {"row": 1, "column": 3},
"delta": {"position": "bottom"},
"align": "center"
},

{
"type": "indicator",
"domain": {"row": 2, "column": 0},
"delta": {"position": "left"},
"align": "right"
}, {
"type": "indicator",
"domain": {"x": [0.05, 0.5], "y": [0.15, 0.35]},
"domain": {"row": 2, "column": 1},
"delta": {"position": "top"},
"align": "right"
}, {
"type": "indicator",
"domain": {"row": 2, "column": 2},
"delta": {"position": "right"},
"align": "right"
}, {
"type": "indicator",
"domain": {"row": 2, "column": 3},
"delta": {"position": "bottom"},
"align": "right"
}
],
"layout": {
"width": 1000,
"height": 200,
"margin": {"t": 0, "b": 0, "l": 0, "r": 0},
"grid": {"rows": 3, "columns": 4, "pattern": "independent", "xgap": 0, "ygap": 0},
"shapes": [{
"type": "line",
"x0": 0,
"x1": 1,
"y0": 0.33,
"y1": 0.33,
"line": {
"color": "rgba(0, 0, 0, 0.35)",
"width": 1
}
},
{
"type": "line",
"x0": 0,
"x1": 1,
"y0": 0.66,
"y1": 0.66,
"line": {
"color": "rgba(0, 0, 0, 0.35)",
"width": 1
}
},
{
"type": "line",
"x0": 0.25,
"x1": 0.25,
"y0": 0,
"y1": 1,
"line": {
"color": "rgba(0, 0, 0, 0.35)",
"width": 1
}
},
{
"type": "line",
"x0": 0.5,
"x1": 0.5,
"y0": 0,
"y1": 1,
"line": {
"color": "rgba(0, 0, 0, 0.35)",
"width": 1
}
},{
"type": "line",
"x0": 0.75,
"x1": 0.75,
"y0": 0,
"y1": 1,
"line": {
"color": "rgba(0, 0, 0, 0.35)",
"width": 1
}
}],
"template": {
"data": {
"indicator": [{
"mode": "number+delta",
"delta": {"reference": 60},
"value": 120
}]
}
}
}
}
Loading