* Helper function to fit a radial linear scale with point labels
(scale)
| 47 | * Helper function to fit a radial linear scale with point labels |
| 48 | */ |
| 49 | function fitWithPointLabels(scale) { |
| 50 | |
| 51 | // Right, this is really confusing and there is a lot of maths going on here |
| 52 | // The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 |
| 53 | // |
| 54 | // Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif |
| 55 | // |
| 56 | // Solution: |
| 57 | // |
| 58 | // We assume the radius of the polygon is half the size of the canvas at first |
| 59 | // at each index we check if the text overlaps. |
| 60 | // |
| 61 | // Where it does, we store that angle and that index. |
| 62 | // |
| 63 | // After finding the largest index and angle we calculate how much we need to remove |
| 64 | // from the shape radius to move the point inwards by that x. |
| 65 | // |
| 66 | // We average the left and right distances to get the maximum shape radius that can fit in the box |
| 67 | // along with labels. |
| 68 | // |
| 69 | // Once we have that, we can find the centre point for the chart, by taking the x text protrusion |
| 70 | // on each side, removing that from the size, halving it and adding the left x protrusion width. |
| 71 | // |
| 72 | // This will mean we have a shape fitted to the canvas, as large as it can be with the labels |
| 73 | // and position it in the most space efficient manner |
| 74 | // |
| 75 | // https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif |
| 76 | |
| 77 | // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. |
| 78 | // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points |
| 79 | const orig = { |
| 80 | l: scale.left + scale._padding.left, |
| 81 | r: scale.right - scale._padding.right, |
| 82 | t: scale.top + scale._padding.top, |
| 83 | b: scale.bottom - scale._padding.bottom |
| 84 | }; |
| 85 | const limits = Object.assign({}, orig); |
| 86 | const labelSizes = []; |
| 87 | const padding = []; |
| 88 | const valueCount = scale._pointLabels.length; |
| 89 | const pointLabelOpts = scale.options.pointLabels; |
| 90 | const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0; |
| 91 | |
| 92 | for (let i = 0; i < valueCount; i++) { |
| 93 | const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i)); |
| 94 | padding[i] = opts.padding; |
| 95 | const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle); |
| 96 | const plFont = toFont(opts.font); |
| 97 | const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]); |
| 98 | labelSizes[i] = textSize; |
| 99 | |
| 100 | const angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle); |
| 101 | const angle = Math.round(toDegrees(angleRadians)); |
| 102 | const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); |
| 103 | const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); |
| 104 | updateLimits(limits, orig, angleRadians, hLimits, vLimits); |
| 105 | } |
| 106 |
no test coverage detected