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

Add marker.cornerradius to treemap #6351

Merged
merged 11 commits into from Dec 21, 2022
1 change: 1 addition & 0 deletions draftlogs/6351_add.md
@@ -0,0 +1 @@
- Expose `marker.fillet` attribute for rounded corners in treemap and icicle plots [[#6351](https://github.com/plotly/plotly.js/pull/6351)]
2 changes: 2 additions & 0 deletions src/traces/icicle/attributes.js
Expand Up @@ -61,6 +61,8 @@ module.exports = {

line: sunburstAttrs.marker.line,

fillet: treemapAttrs.marker.fillet,

editType: 'calc'
},
colorScaleAttrs('marker', {
Expand Down
2 changes: 2 additions & 0 deletions src/traces/icicle/defaults.js
Expand Up @@ -62,6 +62,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
var lineWidth = coerce('marker.line.width');
if(lineWidth) coerce('marker.line.color', layout.paper_bgcolor);

coerce('marker.fillet');

coerce('marker.colors');
var withColorscale = traceOut._hasColorscale = (
hasColorscale(traceIn, 'marker', 'colors') ||
Expand Down
14 changes: 13 additions & 1 deletion src/traces/treemap/attributes.js
Expand Up @@ -141,7 +141,19 @@ module.exports = {

line: sunburstAttrs.marker.line,

editType: 'calc'
fillet: {
valType: 'number',
min: 0,
// max: 10, // TODO: Do we need a max?
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like it's possible to make the radius so big that the text or smaller inner boxes poke out of their containers. Here's your mock bumped up to radius 40:
Screen Shot 2022-10-27 at 19 19 21
How about we make a dynamic max? If I did the math right, a safe value would be x+y+sqrt(2*x*y) where x is min(padding.l, padding.r) and y is min(padding.t, padding.b)
Actually might be more user-friendly to leave max undefined, but restrict it during rendering and describe this in the attribute description - since we're restricting the radius anyway if the box gets too small... something like "the actual radius we draw will be limited to half the box size, or smaller if necessary to prevent the box contents from overflowing its edges"

dflt: 0,
editType: 'plot',
description: [
'Sets the rounding of corners (in px).'
].join(' ')
},

editType: 'calc',

},
colorScaleAttrs('marker', {
colorAttr: 'colors',
Expand Down
2 changes: 2 additions & 0 deletions src/traces/treemap/defaults.js
Expand Up @@ -85,6 +85,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('marker.pad.r', headerSize / 4);
coerce('marker.pad.b', bottomText ? headerSize : headerSize / 4);

coerce('marker.fillet');

traceOut._hovered = {
marker: {
line: {
Expand Down
8 changes: 2 additions & 6 deletions src/traces/treemap/plot_one.js
Expand Up @@ -217,12 +217,8 @@ module.exports = function plotOne(gd, cd, element, transitionOpts, drawDescendan
var dy = _y1 - _y0;
if(!dx || !dy) return '';

var FILLET = 0; // TODO: may expose this constant

var r = (
dx > 2 * FILLET &&
dy > 2 * FILLET
) ? FILLET : 0;
var FILLET = trace.marker.fillet;
var r = dx > 2 * FILLET && dy > 2 * FILLET ? FILLET : Math.min(dx, dy) / 2;

var arc = function(rx, ry) { return r ? 'a' + pos(r, r) + ' 0 0 1 ' + pos(rx, ry) : ''; };

Expand Down
Binary file modified test/image/baselines/icicle_packages_colorscale_novalue.png
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/treemap_packages_colorscale_novalue.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test/image/mocks/icicle_packages_colorscale_novalue.json
Expand Up @@ -8,6 +8,7 @@
"line": {
"color": "#777"
},
"fillet": 10,
"colorscale": [[0, "#FFF"], [0.01, "#FF0"], [0.1, "#F00"], [1, "#000"]],
"showscale": true
},
Expand Down
1 change: 1 addition & 0 deletions test/image/mocks/treemap_packages_colorscale_novalue.json
Expand Up @@ -9,6 +9,7 @@
"line": {
"color": "#777"
},
"fillet": 4,
"colorscale": [[0, "#FFF"], [0.01, "#FF0"], [0.1, "#F00"], [1, "#000"]],
"showscale": true
},
Expand Down
33 changes: 33 additions & 0 deletions test/jasmine/tests/icicle_test.js
Expand Up @@ -793,6 +793,39 @@ describe('Test icicle restyle:', function() {
.then(_assert('back to dflt', ['', '0.7', '', '0.7']))
.then(done, done.fail);
});

it('should be able to restyle *marker.fillet*', function(done) {
var mock = {
data: [{
type: 'icicle',
labels: ['Root', 'A', 'B', 'b'],
parents: ['', 'Root', 'Root', 'B']
}]
};

function _assert(msg, exp) {
return function() {
var layer = d3Select(gd).select('.iciclelayer');
layer.selectAll('.surface').each(function() {
var surfaces = d3Select(this);
var path = surfaces[0][0].getAttribute('d');
expect(path.indexOf('a') !== -1).toEqual(exp);
});
};
}

Plotly.newPlot(gd, mock)
.then(_assert('no arcs', false))
.then(function() {
return Plotly.restyle(gd, 'marker.fillet', 10);
})
.then(_assert('has arcs', true))
.then(function() {
return Plotly.restyle(gd, 'marker.fillet', 0);
})
.then(_assert('no arcs', false))
.then(done, done.fail);
});
});

describe('Test icicle texttemplate without `values` should work at root level:', function() {
Expand Down
36 changes: 36 additions & 0 deletions test/jasmine/tests/treemap_test.js
Expand Up @@ -1294,6 +1294,42 @@ describe('Test treemap restyle:', function() {
.then(_assert('back to dflt', ['Root', 'B', 'A\nnode1', 'b\nnode3']))
.then(done, done.fail);
});

it('should be able to restyle *marker.fillet*', function(done) {
var mock = {
data: [{
type: 'treemap',
labels: ['Root', 'A', 'B', 'b'],
parents: ['', 'Root', 'Root', 'B'],
text: ['node0', 'node1', 'node2', 'node3'],
values: [0, 1, 2, 3],
pathbar: { visible: false }
}]
};

function _assert(msg, exp) {
return function() {
var layer = d3Select(gd).select('.treemaplayer');
layer.selectAll('.surface').each(function() {
var surfaces = d3Select(this);
var path = surfaces[0][0].getAttribute('d');
expect(path.indexOf('a') !== -1).toEqual(exp);
});
};
}

Plotly.newPlot(gd, mock)
.then(_assert('no arcs', false))
.then(function() {
return Plotly.restyle(gd, 'marker.fillet', 10);
})
.then(_assert('has arcs', true))
.then(function() {
return Plotly.restyle(gd, 'marker.fillet', 0);
})
.then(_assert('no arcs', false))
.then(done, done.fail);
});
});

describe('Test treemap tweening:', function() {
Expand Down
14 changes: 14 additions & 0 deletions test/plot-schema.json
Expand Up @@ -34113,6 +34113,13 @@
"valType": "string"
},
"editType": "calc",
"fillet": {
"description": "Sets the rounding of corners (in px).",
"dflt": 0,
"editType": "plot",
"min": 0,
"valType": "number"
},
"line": {
"color": {
"arrayOk": true,
Expand Down Expand Up @@ -69182,6 +69189,13 @@
]
},
"editType": "calc",
"fillet": {
"description": "Sets the rounding of corners (in px).",
"dflt": 0,
"editType": "plot",
"min": 0,
"valType": "number"
},
"line": {
"color": {
"arrayOk": true,
Expand Down