-
Notifications
You must be signed in to change notification settings - Fork 12k
Improve radial scale #3625
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
Improve radial scale #3625
Conversation
simonbrunel
left a comment
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.
Some code enhancement suggestions (not tested)
src/scales/scale.radialLinear.js
Outdated
| }; | ||
| } | ||
|
|
||
| return size; |
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.
if (helpers.isArray(label)) {
return {
w: ...
h: ...
};
}
return {
w: ...
h: ...
};
src/scales/scale.radialLinear.js
Outdated
|
|
||
| // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. | ||
| // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points | ||
| var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2), |
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.
Could be normalized with multiple var declarations and grouping uninitialized vars at the end.
src/scales/scale.radialLinear.js
Outdated
| Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2)); | ||
| scale.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom); | ||
| } | ||
| determineReductions(); |
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 a function?
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.
That was to make eslint happy otherwise the function is too long and too complex
src/scales/scale.radialLinear.js
Outdated
| // Add quarter circle to make degree 0 mean top of circle | ||
| var angleRadians = scale.getIndexAngle(i); | ||
| var angle = helpers.toDegrees(angleRadians) % 360; | ||
| determineXLimits(angle); |
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.
Not sure what the benefit to have functions for determineXLimits, determineYLimits and updateLimits, they are called only from that location. determineXLimits and determineYLimits could be refactored and updateLimits inlined:
function determineLimits(angle, pos, size, min, max) {
if (angle == min || angle == max) {
return {
start: pos - (size / 2),
end: pos + (size / 2)
};
}
if (angle < min || angle > max) {
return {
start: pos - size - 5,
end: pos
};
}
return {
start: pos,
end: pos + size + 5
};
}
var valueCount = getValueCount(scale);
for (i = 0; i < valueCount; i++) {
// ... previous code ...
var hlimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
var vlimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
// update limits
if (furthestLeft > hlimit.start) {
furthestLeft = hlimit.start;
furthestLeftAngle = angleRadians;
}
if (furthestRight < hlimit.end) {
furthestRight = hlimit.end;
furthestRightAngle = angleRadians;
}
// ... rest of the updateLimits method ...
}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.
Those functions came to make eslint happy otherwise it complains that fitWithPointLabels is too complex and has too many statements
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 don't think inner functions are a good approach to reduce code complexity, seems just a hack to trick eslint, but that makes the code more complex since these inner methods modify outer variables (also not good for performance to call useless functions in a loop).
determineLimits doesn't refer to outer scope variables, so can live outside fitWithPointLabels.
src/scales/scale.radialLinear.js
Outdated
| textAlign = 'right'; | ||
| } | ||
|
|
||
| return textAlign; |
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.
if (angle === 0 || angle === 180) {
return 'center';
}
if (angle < 180) {
return 'left';
}
return 'right';| } | ||
| } | ||
| ctx.closePath(); | ||
| ctx.stroke(); |
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.
Let's avoid empty path drawing and i === 0 condition in the loop:
var count = getValueCount(scale);
if (count === 0) {
return;
}
ctx.beginPath();
var pos = scale.getPointPosition(0, radius);
ctx.moveTo(pos.x, pos.y);
for (var i = 1; i < count; i++) {
pos = scale.getPointPosition(i, radius);
ctx.lineTo(pos.x, pos.y);
}
ctx.closePath();
ctx.stroke();
src/scales/scale.radialLinear.js
Outdated
| var pointLabelFontSize = helpers.getValueOrDefault(pointLabels.fontSize, globalDefaults.defaultFontSize); | ||
| var pointLabelFontStyle = helpers.getValueOrDefault(pointLabels.fontStyle, globalDefaults.defaultFontStyle); | ||
| var pointLabelFontFamily = helpers.getValueOrDefault(pointLabels.fontFamily, globalDefaults.defaultFontFamily); | ||
| var pointLabelFont = helpers.fontString(pointLabelFontSize, pointLabelFontStyle, pointLabelFontFamily); |
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.
Quite personal, but I'm not a huge fan of long variable names, especially when the scope is obvious: it makes the code harder to read.
function getPointLabelFontOptions(scale) {
var options = scale.options.pointLabels;
var size = helpers.getValueOrDefault(options.fontSize, globalDefaults.defaultFontSize);
var style = helpers.getValueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle);
var family = helpers.getValueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily);
return {
size: size,
style: style,
family: family,
font: helpers.fontString(size, style, family);
};|
@simonbrunel I agree with your comments. i will make updates to the code to fix them |
0507f5d to
e1606f8
Compare
|
@chartjs/maintainers is this good to go? |
simonbrunel
left a comment
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.
Great work!
Clean up radial linear scale. It now supports multiple lines for point labels. Fixes chartjs#3225
A lot of cleanup of the radial scale. I moved a lot of functionality into private functions.
Issues Fixed
Testing Done
Changed Behaviour
getIndexAnglemethod no longer subtracts 90 degrees since we added it back almost all of the time.