Skip to content

Commit 024f05f

Browse files
committed
add basic cornerradius for bar charts
1 parent 915a52b commit 024f05f

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

src/traces/bar/attributes.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,16 @@ var marker = extendFlat({
4242
editType: 'style',
4343
description: 'Sets the opacity of the bars.'
4444
},
45-
pattern: pattern
45+
pattern: pattern,
46+
cornerradius: {
47+
valType: 'any',
48+
dflt: 0,
49+
editType: 'plot',
50+
description: [
51+
'Sets the rounding of corners. May be an integer number of pixels,',
52+
'or a percentage of bar width(as a string).'
53+
].join(' ')
54+
},
4655
});
4756

4857
module.exports = {

src/traces/bar/plot.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,49 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback)
232232
y1 = fixpx(y1, y0, !isHorizontal);
233233
}
234234

235+
// Here is where bar is drawn
236+
// TODO: Implement rounded corners here
237+
238+
function calcCornerRadius(radiusParam) {
239+
var barWidth = isHorizontal ? Math.abs(y1 - y0) : Math.abs(x1 - x0);
240+
if(!radiusParam) {
241+
return 0;
242+
} else if(typeof radiusParam === "string") { // if it's a percentage string
243+
var rPercent = parseFloat(radiusParam.replace('%', ''));
244+
return barWidth * (rPercent / 100);
245+
} else { // otherwise, it's a number
246+
return Math.min(
247+
radiusParam,
248+
barWidth/2,
249+
);
250+
}
251+
}
252+
var r = calcCornerRadius(trace.marker.cornerradius);
253+
254+
var path;
255+
if(r && isHorizontal) {
256+
path = 'M' + x0 + ',' + y0
257+
+ 'V' + y1
258+
+ 'H' + (x1 - r)
259+
+ 'a ' + r + ',' + r + ' 0 0 1 ' + r + ',' + r
260+
+ 'V' + (y0 - r)
261+
+ 'a ' + r + ',' + r + ' 0 0 1 ' + -r + ',' + r
262+
+ 'Z';
263+
} else if(r) {
264+
path = 'M' + x0 + ',' + y0
265+
+ 'V' + (y1 + r)
266+
+ 'a ' + r + ',' + r + ' 0 0 1 ' + r + ',' + -r
267+
+ 'H' + (x1 - r)
268+
+ 'a ' + r + ',' + r + ' 0 0 1 ' + r + ',' + r
269+
+ 'V' + y0 + 'Z';
270+
} else {
271+
path = 'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z';
272+
}
273+
235274
var sel = transition(Lib.ensureSingle(bar, 'path'), fullLayout, opts, makeOnCompleteCallback);
236275
sel
237276
.style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke')
238-
.attr('d', (isNaN((x1 - x0) * (y1 - y0)) || (isBlank && gd._context.staticPlot)) ? 'M0,0Z' : 'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z')
277+
.attr('d', (isNaN((x1 - x0) * (y1 - y0)) || (isBlank && gd._context.staticPlot)) ? 'M0,0Z' : path)
239278
.call(Drawing.setClipUrl, plotinfo.layerClipId, gd);
240279

241280
if(!fullLayout.uniformtext.mode && withTransition) {
@@ -350,6 +389,7 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCom
350389
if(textPosition === 'auto') {
351390
if(isOutmostBar) {
352391
// draw text using insideTextFont and check if it fits inside bar
392+
// TODO: Need to consider `cornerradius` here
353393
textPosition = 'inside';
354394

355395
font = Lib.ensureUniformFontSize(gd, insideTextFont);

src/traces/bar/style_defaults.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module.exports = function handleStyleDefaults(traceIn, traceOut, coerce, default
2424

2525
coerce('marker.line.width');
2626
coerce('marker.opacity');
27+
coerce('marker.cornerradius');
2728
coercePattern(coerce, 'marker.pattern', markerColor, hasMarkerColorscale);
2829
coerce('selected.marker.color');
2930
coerce('unselected.marker.color');
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"data": [
3+
{
4+
"x": [
5+
"giraffes",
6+
"orangutans",
7+
"monkeys",
8+
"capybaras"
9+
],
10+
"y": [20, 14, 2, 18
11+
],
12+
"type": "bar",
13+
"marker": {"cornerradius": 10}
14+
},
15+
{
16+
"y": [
17+
"giraffes",
18+
"orangutans",
19+
"monkeys",
20+
"capybaras"
21+
],
22+
"x": [20, 14, 2, 18],
23+
"type": "bar",
24+
"marker": {"cornerradius": "30%"},
25+
"orientation": "h",
26+
"xaxis": "x2",
27+
"yaxis": "y2"
28+
}
29+
30+
],
31+
"layout": {"grid": {"rows": 1, "columns": 2, "pattern": "independent"}}
32+
}
33+

0 commit comments

Comments
 (0)