1/* * 2 * 3 * (c) 2010-2024 Torstein Honsi 4 * 5 * License: www.highcharts.com/license 6 * 7 * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!! 8 * 9 * */ 10'use strict'; 11import U from '../../Utilities.js'; 12const { defined, isNumber, pick } = U; 13/* * 14 * 15 * Functions 16 * 17 * */ 18/* eslint-disable require-jsdoc, valid-jsdoc */ 19/** 20 * 21 */ 22function arc(cx, cy, w, h, options) { 23 const arc = []; 24 if (options) { 25 const start = options.start || 0, rx = pick(options.r, w), ry = pick(options.r, h || w), 26 // Subtract a small number to prevent cos and sin of start and end 27 // from becoming equal on 360 arcs (#1561). The size of the circle 28 // affects the constant, therefore the division by `rx`. If the 29 // proximity is too small, the arc disappears. If it is too great, a 30 // gap appears. This can be seen in the animation of the official 31 // bubble demo (#20586). 32 proximity = 0.0002 / (options.borderRadius ? 1 : Math.max(rx, 1)), fullCircle = (Math.abs((options.end || 0) - start - 2 * Math.PI) < 33 proximity), end = (options.end || 0) - (fullCircle ? proximity : 0), innerRadius = options.innerR, open = pick(options.open, fullCircle), cosStart = Math.cos(start), sinStart = Math.sin(start), cosEnd = Math.cos(end), sinEnd = Math.sin(end), 34 // Proximity takes care of rounding errors around PI (#6971) 35 longArc = pick(options.longArc, end - start - Math.PI < proximity ? 0 : 1); 36 let arcSegment = [ 37 'A', // ArcTo 38 rx, // X radius 39 ry, // Y radius 40 0, // Slanting 41 longArc, // Long or short arc 42 pick(options.clockwise, 1), // Clockwise 43 cx + rx * cosEnd, 44 cy + ry * sinEnd 45 ]; 46 arcSegment.params = { start, end, cx, cy }; // Memo for border radius 47 arc.push([ 48 'M', 49 cx + rx * cosStart, 50 cy + ry * sinStart 51 ], arcSegment); 52 if (defined(innerRadius)) { 53 arcSegment = [ 54 'A', // ArcTo 55 innerRadius, // X radius 56 innerRadius, // Y radius 57 0, // Slanting 58 longArc, // Long or short arc 59 // Clockwise - opposite to the outer arc clockwise 60 defined(options.clockwise) ? 1 - options.clockwise : 0, 61 cx + innerRadius * cosStart, 62 cy + innerRadius * sinStart 63 ]; 64 // Memo for border radius 65 arcSegment.params = { 66 start: end, 67 end: start, 68 cx, 69 cy 70 }; 71 arc.push(open ? 72 [ 73 'M', 74 cx + innerRadius * cosEnd, 75 cy + innerRadius * sinEnd 76 ] : [ 77 'L', 78 cx + innerRadius * cosEnd, 79 cy + innerRadius * sinEnd 80 ], arcSegment); 81 } 82 if (!open) { 83 arc.push(['Z']); 84 } 85 } 86 return arc; 87} 88/** 89 * Callout shape used for default tooltips. 90 */ 91function callout(x, y, w, h, options) { 92 const arrowLength = 6, halfDistance = 6, r = Math.min((options && options.r) || 0, w, h), safeDistance = r + halfDistance, anchorX = options && options.anchorX, anchorY = options && options.anchorY || 0; 93 const path = roundedRect(x, y, w, h, { r }); 94 if (!isNumber(anchorX)) { 95 return path; 96 } 97 // Do not render a connector, if anchor starts inside the label 98 if (anchorX < w && anchorX > 0 && anchorY < h && anchorY > 0) { 99 return path; 100 } 101 // Anchor on right side 102 if (x + anchorX > w - safeDistance) { 103 // Chevron 104 if (anchorY > y + safeDistance && 105 anchorY < y + h - safeDistance) { 106 path.splice(3, 1, ['L', x + w, anchorY - halfDistance], ['L', x + w + arrowLength, anchorY], ['L', x + w, anchorY + halfDistance], ['L', x + w, y + h - r]); 107 // Simple connector 108 } 109 else { 110 if (anchorX < w) { // Corner connector 111 const isTopCorner = anchorY < y + safeDistance, cornerY = isTopCorner ? y : y + h, sliceStart = isTopCorner ? 2 : 5;
vendor: 3,479 bytes, lines 112-244
112 path.splice(sliceStart, 0, ['L', anchorX, anchorY], ['L', x + w - r, cornerY]); 113 } 114 else { // Side connector 115 path.splice(3, 1, ['L', x + w, h / 2], ['L', anchorX, anchorY], ['L', x + w, h / 2], ['L', x + w, y + h - r]); 116 } 117 } 118 // Anchor on left side 119 } 120 else if (x + anchorX < safeDistance) { 121 // Chevron 122 if (anchorY > y + safeDistance && 123 anchorY < y + h - safeDistance) { 124 path.splice(7, 1, ['L', x, anchorY + halfDistance], ['L', x - arrowLength, anchorY], ['L', x, anchorY - halfDistance], ['L', x, y + r]); 125 // Simple connector 126 } 127 else { 128 if (anchorX > 0) { // Corner connector 129 const isTopCorner = anchorY < y + safeDistance, cornerY = isTopCorner ? y : y + h, sliceStart = isTopCorner ? 1 : 6; 130 path.splice(sliceStart, 0, ['L', anchorX, anchorY], ['L', x + r, cornerY]); 131 } 132 else { // Side connector 133 path.splice(7, 1, ['L', x, h / 2], ['L', anchorX, anchorY], ['L', x, h / 2], ['L', x, y + r]); 134 } 135 } 136 } 137 else if ( // Replace bottom 138 anchorY > h && 139 anchorX < w - safeDistance) { 140 path.splice(5, 1, ['L', anchorX + halfDistance, y + h], ['L', anchorX, y + h + arrowLength], ['L', anchorX - halfDistance, y + h], ['L', x + r, y + h]); 141 } 142 else if ( // Replace top 143 anchorY < 0 && 144 anchorX > safeDistance) { 145 path.splice(1, 1, ['L', anchorX - halfDistance, y], ['L', anchorX, y - arrowLength], ['L', anchorX + halfDistance, y], ['L', w - r, y]); 146 } 147 return path; 148} 149/** 150 * 151 */ 152function circle(x, y, w, h) { 153 // Return a full arc 154 return arc(x + w / 2, y + h / 2, w / 2, h / 2, { 155 start: Math.PI * 0.5, 156 end: Math.PI * 2.5, 157 open: false 158 }); 159} 160/** 161 * 162 */ 163function diamond(x, y, w, h) { 164 return [ 165 ['M', x + w / 2, y], 166 ['L', x + w, y + h / 2], 167 ['L', x + w / 2, y + h], 168 ['L', x, y + h / 2], 169 ['Z'] 170 ]; 171} 172// #15291 173/** 174 * 175 */ 176function rect(x, y, w, h, options) { 177 if (options && options.r) { 178 return roundedRect(x, y, w, h, options); 179 } 180 return [ 181 ['M', x, y], 182 ['L', x + w, y], 183 ['L', x + w, y + h], 184 ['L', x, y + h], 185 ['Z'] 186 ]; 187} 188/** 189 * 190 */ 191function roundedRect(x, y, w, h, options) { 192 const r = options?.r || 0; 193 return [ 194 ['M', x + r, y], 195 ['L', x + w - r, y], // Top side 196 ['A', r, r, 0, 0, 1, x + w, y + r], // Top-right corner 197 ['L', x + w, y + h - r], // Right side 198 ['A', r, r, 0, 0, 1, x + w - r, y + h], // Bottom-right corner 199 ['L', x + r, y + h], // Bottom side 200 ['A', r, r, 0, 0, 1, x, y + h - r], // Bottom-left corner 201 ['L', x, y + r], // Left side 202 ['A', r, r, 0, 0, 1, x + r, y], 203 ['Z'] // Top-left corner 204 ]; 205} 206/** 207 * 208 */ 209function triangle(x, y, w, h) { 210 return [ 211 ['M', x + w / 2, y], 212 ['L', x + w, y + h], 213 ['L', x, y + h], 214 ['Z'] 215 ]; 216} 217/** 218 * 219 */ 220function triangleDown(x, y, w, h) { 221 return [ 222 ['M', x, y], 223 ['L', x + w, y], 224 ['L', x + w / 2, y + h], 225 ['Z'] 226 ]; 227} 228const Symbols = { 229 arc, 230 callout, 231 circle, 232 diamond, 233 rect, 234 roundedRect, 235 square: rect, 236 triangle, 237 'triangle-down': triangleDown 238}; 239/* * 240 * 241 * Default Export 242 * 243 * */ 244export default Symbols;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.