golang.org/x/build@v0.0.0-20240506185731-218518f32b70/perf/app/dashboard/static/range.js (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 function Range(low, center, high, min, max, width, height, unit, higherIsBetter) { 6 const margin = 40; 7 const svg = d3.create("svg") 8 .attr("width", width) 9 .attr("height", height) 10 .attr("viewBox", [0, 0, width, height]) 11 .attr("style", "max-width: 100%; height: auto; height: intrinsic;"); 12 13 const goodColor = "#005AB5"; 14 const badColor = "#DC3220"; 15 const pickColor = function(n) { 16 if (higherIsBetter) { 17 if (n > 0) { 18 return goodColor; 19 } 20 return badColor; 21 } 22 if (n < 0) { 23 return goodColor; 24 } 25 return badColor; 26 }; 27 28 const xScale = d3.scaleLinear([min, max], [margin, width-margin]); 29 const yBaseline = 3*height/4; 30 31 // Draw zero line. 32 const tick = d3.line() 33 .x(d => xScale(d[0])) 34 .y(d => d[1]) 35 36 svg.append("path") 37 .attr("fill", "none") 38 .attr("stroke", "#cccccc") 39 .attr("stroke-width", 1) 40 .attr("d", tick([[0, 0], [0, height]])) 41 42 // Draw line. 43 const line = d3.line() 44 .x(d => xScale(d)) 45 .y(yBaseline) 46 47 const partialStroke = function() { 48 return svg.append("path") 49 .attr("fill", "none") 50 .attr("stroke-width", 3.5); 51 } 52 if (high < 0) { 53 partialStroke().attr("stroke", pickColor(high)) 54 .attr("d", line([low, high])); 55 } else if (low < 0 && high > 0) { 56 partialStroke().attr("stroke", pickColor(low)) 57 .attr("d", line([low, 0])); 58 partialStroke().attr("stroke", pickColor(high)) 59 .attr("d", line([0, high])); 60 } else { 61 partialStroke().attr("stroke", pickColor(low)) 62 .attr("d", line([low, high])); 63 } 64 65 const xTicks = [low, center, high]; 66 for (const i in xTicks) { 67 svg.append("path") 68 .attr("fill", "none") 69 .attr("stroke", pickColor(xTicks[i])) 70 .attr("stroke-width", 2.5) 71 .attr("d", tick([[xTicks[i], yBaseline-4], [xTicks[i], yBaseline+4]])) 72 } 73 74 svg.append("text") 75 .attr("x", xScale(low)-4) 76 .attr("y", yBaseline+3) 77 .attr("fill", pickColor(low)) 78 .attr("text-anchor", "end") 79 .attr("font-size", "11px") 80 .text(Intl.NumberFormat([], { 81 style: 'percent', 82 signDisplay: 'always', 83 minimumFractionDigits: 2, 84 }).format(low)); 85 86 svg.append("text") 87 .attr("x", xScale(center)) 88 .attr("y", height/2) 89 .attr("fill", pickColor(center)) 90 .attr("text-anchor", "middle") 91 .attr("font-size", "16px") 92 .text(Intl.NumberFormat([], { 93 style: 'percent', 94 signDisplay: 'always', 95 minimumFractionDigits: 2, 96 }).format(center)); 97 98 svg.append("text") 99 .attr("x", xScale(high)+4) 100 .attr("y", yBaseline+3) 101 .attr("fill", pickColor(high)) 102 .attr("text-anchor", "start") 103 .attr("font-size", "11px") 104 .text(Intl.NumberFormat([], { 105 style: 'percent', 106 signDisplay: 'always', 107 minimumFractionDigits: 2, 108 }).format(high)); 109 110 return svg.node(); 111 }