-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
Fix for #3293 #4266
Fix for #3293 #4266
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. @simonbrunel any comments?
// - top-bottom + left-right | ||
// - top + right + bottom + left | ||
return !vm.borderWidth ? [] : | ||
vm.borderWidth instanceof Array && vm.borderWidth.length === 1 ? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] could use helpers.isArray
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also put vm.borderWidth
into a local variable to improve minification
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole block would be more compact and efficient if borderWidth
is an object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice feature but I'm not sure about the public API (using arrays to defines these properties), why not using objects instead:
- doesn't require to specify all values to set the left side
- it works better with the config merge process
- easier to test values:
if (borderSkipped.left)
- it's clearer what value for what side
borderSkipped: true; // shorthand for all sides
borderSkipped: {
left: true,
top: true
};
borderWidth: 1; // << shorthand for all sides
borderWidth: {
left: 2,
right: 1
};
Will need unit tests as well :)
@@ -50,11 +50,106 @@ module.exports = function(Chart) { | |||
} | |||
|
|||
Chart.elements.Rectangle = Chart.Element.extend({ | |||
draw: function() { | |||
getBorderWidth: function(top, right, bottom, left) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be marked @private
// - top-bottom + left-right | ||
// - top + right + bottom + left | ||
return !vm.borderWidth ? [] : | ||
vm.borderWidth instanceof Array && vm.borderWidth.length === 1 ? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole block would be more compact and efficient if borderWidth
is an object.
// - top + right + bottom + left | ||
return !vm.borderWidth ? [] : | ||
vm.borderWidth instanceof Array && vm.borderWidth.length === 1 ? { | ||
top: ceiling(vm.borderWidth[0], barSizeTopBottom), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not using Math.min(vm.borderWidth[0], barSizeLeftRight)
?
left: ceiling(vm.borderWidth, barSizeLeftRight) | ||
}; | ||
}, | ||
drawShape: function(borders) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be marked @private
ctx.lineWidth = 0; | ||
ctx.moveTo(borders.bottom[0][0], borders.bottom[0][1]); | ||
for (var i in borders) { | ||
if (borders.hasOwnProperty(i)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems counter efficient to iterate on this borders
object and have all these hasOwnProperty
useless calls. Since it's an internal variable, why not using an array instead and convert this for..in
loop to a tradition for(var i=0; i<4; ++i)
loop?
}, | ||
adjustBorders: function(borders, borderWidth, borderSkipped) { | ||
// Make sure border lengths are adjusted for border width. | ||
if (!borderSkipped.includes('top') && borderWidth.top > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array.includes
is not supported by IE (though, if borderSkipped
is an object, no need for that call).
borders.right = [[borders.right[0][0], borders.right[0][1] + borderWidth.bottom/2], borders.right[1]]; | ||
} | ||
}, | ||
drawBorders: function(borders, borderWidth, borderSkipped) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be marked @private
|
||
ctx.strokeStyle = vm.borderColor; | ||
for (var i in borders) { | ||
if (borders.hasOwnProperty(i)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, iterating on this borders
object doesn't seem efficient
// Skip drawing the border | ||
continue; | ||
} | ||
ctx.beginPath(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the strokeStyle
doesn't change for each border, beginPath()
and stroke()
should be moved outside the loop:
ctx.strokeStyle = vm.borderColor;
ctx.beginPath();
for (...) {
ctx.moveTo(...)
ctx.lineTo(...)
}
ctx.stroke();
corner = cornerAt(i); | ||
ctx.lineTo(corner[0], corner[1]); | ||
} | ||
var borders = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For performance sake, this internal borders object should be an array of array (properly commented):
var borders = [
[x0, y0, x1, y1], //< top
[x0, y0, x1, y1], //< right
[x0, y0, x1, y1], //< bottom
[x0, y0, x1, y1], //< left
];
Thank you for the feedback; I'll look into optimising the code. I've been thinking
as opposed to
Seems more brief and in line with how CSS handles it. What say you - would it be better to support both syntaxes? What's the project policy on this? |
Arrays are evils when merging configs because they can't be merged (ref. scale configs). The CSS way to define TRBL is brief but not intuitive (at least there is alternatives, for example: That's why I think the first implementation should be entirely based on the object approach (with boolean/int shorthands). The rectangle element defaults should use the object form: Chart.defaults.global.elements.rectangle = {
borderWidth: { }, // undefined/null == 0
}; I agree that other forms are interesting, so we could add support for @etimberg thoughts? |
Agreed. I'm convinced. Just occurred to me, though -- I've just followed through with
it would be clearer to say:
I'm not sure how that would affect compatibility with old code, though. |
That's a very good point and if I correctly understand this config, the answer is: no need for a new config, just deprecate
So I would not add object/array support for |
Interesting point on deprecating |
I've done some initial refactoring -- using |
@bokysan this PR needs a rebase |
@bokysan a reminder that this PR needs to be rebased |
Closing as out of date |
Hello,
please find below an implementation of feature #3293.
You are now able to do the following:
Example of implementation is visible here: https://bokysan.github.io/Chart.js/
Please note that the code also includes the initial "undocumented" support setting the
borderWidth
in the same manner, as suggested in the last comment:However not all user cases have been tested -- especially with the semi-transparent colours -- so I would leave it as undocumented for the time being.
Cheers,
B