{
"extension": ".js",
"source": "import tinygradient from \"tinygradient\"\n\n// An internal function to help with easily creating SVG elements with an object of attributes\nexport const svgElem = (type, attrs) => {\n const elem = document.createElementNS(\"http://www.w3.org/2000/svg\", type),\n attributes = Object.keys(attrs)\n\n for (let i = 0; i < attributes.length; i++) {\n const attr = attributes[i]\n\n elem.setAttribute(attr, attrs[attr])\n }\n\n return elem\n}\n\n// An internal function to help with the repetition of adding fill, stroke, and stroke-width attributes\nexport const styleAttrs = (fill, stroke, strokeWidth, progress, animation) => {\n const determineColor = (type, progress) =>\n typeof type === \"string\" ? type : tinygradient(type).rgbAt(progress)\n\n const attrs = {}\n\n if (stroke) {\n attrs[\"stroke\"] = determineColor(stroke, progress)\n attrs[\"stroke-width\"] = strokeWidth\n }\n\n if (fill) {\n attrs[\"fill\"] = determineColor(fill, progress)\n }\n\n if (animation?.name) {\n // TODO: add animation-direction support\n\n const duration = animation.duration || 5\n\n attrs[\"style\"] = `\n animation-name: ${animation?.name}; \n animation-delay: ${progress * duration - duration}s;\n animation-duration: ${duration}s; \n animation-iteration-count: infinite; \n animation-timing-function: linear;`\n }\n\n return attrs\n}\n\n// An internal function to convert any array of samples into a \"d\" attribute to be passed to an SVG path\nexport const segmentToD = (samples) => {\n let d = \"\"\n\n for (let i = 0; i < samples.length; i++) {\n const { x, y } = samples[i],\n prevSample = i === 0 ? null : samples[i - 1]\n\n if (i === 0 && i !== samples.length - 1) {\n d += `M${x},${y}`\n } else if (x !== prevSample.x && y !== prevSample.y) {\n d += `L${x},${y}`\n } else if (x !== prevSample.x) {\n d += `H${x}`\n } else if (y !== prevSample.y) {\n d += `V${y}`\n }\n\n if (i === samples.length - 1) {\n d += \"Z\"\n }\n }\n\n return d\n}\n\n// An internal function for getting the colors of a segment, we need to get middle most sample (sorted by progress along the path)\nexport const getMiddleSample = (samples) => {\n const sortedSamples = [...samples].sort((a, b) => a.progress - b.progress)\n\n return sortedSamples[(sortedSamples.length / 2) | 0]\n}\n\n// An internal function for converting any D3 selection or DOM-like element into a DOM node\nexport const convertPathToNode = (path) =>\n path instanceof Element || path instanceof HTMLDocument ? path : path.node()\n",
"review": "8\n\n### Bugs\n- None found in the provided code snippet.\n\n### Optimizations\n- Use modern ES6+ features like `for...of` instead of traditional `for` loops for better readability.\n- Inline comments can be added for better clarity in complex logical parts, especially within loops.\n- Make use of `let` and `const` consistently to avoid any potential re-assignment issues by using `const` where variables are not reassigned.\n\n### Good points\n- The code is well-structured with each function performing a specific task.\n- Use of ternary operators and modern JavaScript features like destructuring and spread operators.\n- Proper usage of self-explanatory function and variable names.\n- Handles complex SVG attribute manipulations efficiently.\n\n### Summary\nThe provided code is of high quality, demonstrating good use of modern JavaScript practices and a helper library, `tinygradient`, for gradient manipulations. It is concise, making effective use of ES6+ features such as destructuring, spread/rest operators, and ternary operations for clean code. There are no apparent bugs. The code could be made slightly more readable using newer loop constructs and clarifying comments.\n\n### Open source alternatives\n- [Snap.svg](http://snapsvg.io/) is an open-source library for working with SVG.\n- [D3.js](https://d3js.org/) provides powerful capabilities for data visualization using SVG.\n- [Rapha\u00ebl](http://raphaeljs.com/) is a small JavaScript library that should simplify your work with vector graphics on the web.",
"filename": "_utils.js",
"path": "remix/app/gp/_utils.js",
"directory": "gp",
"grade": 8,
"size": 2502,
"line_count": 85
}