Advertisement
NTahmid

exception_deception_scatter_v2

Feb 22nd, 2024
641
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 7.81 KB | None | 0 0
  1. Here is the modified code:
  2.  
  3. ```html
  4. <!doctype html>
  5. <meta charset="utf-8" />
  6. <html>
  7.   <head>
  8.     <script src="https://d3js.org/d3.v6.min.js" charset="utf-8"></script>
  9.   </head>
  10.  
  11.   <style>
  12.     * {
  13.       font-family: sans-serif;
  14.     }
  15.  
  16.     #tooltip {
  17.       visibility: hidden;
  18.       position: absolute;
  19.       opacity: 0.8;
  20.       padding: 10px;
  21.       vertical-align: middle;
  22.       border-radius: 5px;
  23.       background-color: #ecf0f1;
  24.       font-size: 14px;
  25.     }
  26.  
  27.     .textbox {
  28.       font-size: 14px;
  29.     }
  30.  
  31.     #legend {
  32.       opacity: 0.2;
  33.       fill: #2c3e50;
  34.     }
  35.  
  36.     #title {
  37.       text-anchor: middle;
  38.       font-size: 22px;
  39.     }
  40.  
  41.     .label {
  42.       text-anchor: middle;
  43.     }
  44.  
  45.     #svg {
  46.       background-color: white;
  47.     }
  48.  
  49.     .annotation {
  50.       fill: #c86984;
  51.       stroke: #c86984;
  52.     }
  53.   </style>
  54.  
  55.   <body>
  56.     <div id="container" align="center"></div>
  57.  
  58.     <script type="text/javascript">
  59.       var url =
  60.         "https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json";
  61.  
  62.       var colors = ["#27ae60", "#8e44ad"];
  63.       var legendKeys = ["No Doping Allegations", "Doping Allegations"];
  64.  
  65.       const tooltip = d3
  66.         .select("body")
  67.         .append("div")
  68.         .attr("id", "tooltip")
  69.         .style("visibility", "hidden");
  70.  
  71.       d3.json(url).then(function (data) {
  72.         var width = 700;
  73.         var height = 500;
  74.         var margin = { left: 90, top: 80, bottom: 50, right: 20 };
  75.         var axisOffset = 10;
  76.  
  77.         const svg = d3
  78.           .select("#container")
  79.           .append("svg")
  80.           .attr("id", "svg")
  81.           .attr("width", width)
  82.           .attr("height", height);
  83.  
  84.         var xMin = d3.min(data, (d) => d["Year"]);
  85.         var xMax = d3.max(data, (d) => d["Year"]);
  86.  
  87.         var parseTime = d3.timeParse("%M:%S");
  88.         var yMin = d3.min(data, (d) => parseTime(d["Time"]));
  89.         var yMax = d3.max(data, (d) => parseTime(d["Time"]));
  90.  
  91.         var xScale = d3
  92.           .scaleLinear()
  93.           .domain([xMin, xMax])
  94.           .range([margin.left + axisOffset, width - margin.right]);
  95.  
  96.         var yScale = d3
  97.           .scaleTime()
  98.           .domain([yMax, yMin])
  99.           .range([height - margin.bottom - axisOffset, margin.top]);
  100.  
  101.         var xAxis = d3.axisBottom().scale(xScale).tickFormat(d3.format("d"));
  102.         var yAxis = d3
  103.           .axisLeft()
  104.           .scale(yScale)
  105.           .tickFormat(d3.timeFormat("%M:%S"));
  106.  
  107.         svg
  108.           .append("g")
  109.           .attr("transform", "translate(0, " + (height - margin.bottom) + ")")
  110.           .attr("id", "x-axis")
  111.           .call(xAxis);
  112.  
  113.         svg
  114.           .append("g")
  115.           .attr("transform", "translate(" + margin.left + ", 0)")
  116.           .attr("id", "y-axis")
  117.           .call(yAxis);
  118.  
  119.         svg
  120.           .selectAll("scatterPoints")
  121.           .data(data)
  122.           .enter()
  123.           .append("circle")
  124.           .attr("cx", (d) => xScale(d["Year"]))
  125.           .attr("cy", (d) => yScale(parseTime(d["Time"])))
  126.           .attr("r", 5)
  127.           .attr("fill", (d) => (d["Doping"] == "" ? colors[0] : colors[1]))
  128.           .attr("class", "dot")
  129.           .attr("data-xvalue", (d) => d["Year"])
  130.           .attr("data-yvalue", (d) => parseTime(d["Time"]))
  131.           .on("mouseover", function (d) {
  132.             info = d["originalTarget"]["__data__"];
  133.             tooltip
  134.               .style("visibility", "visible")
  135.               .style("left", event.pageX + 10 + "px")
  136.               .style("top", event.pageY - 80 + "px")
  137.               .attr("data-year", info["Year"])
  138.               .html(
  139.                 info["Name"] +
  140.                   " (" +
  141.                   info["Year"] +
  142.                   ") <br> Time: " +
  143.                   info["Time"] +
  144.                   "<br><br>" +
  145.                   info["Doping"]
  146.               );
  147.           })
  148.           .on("mousemove", function () {
  149.             tooltip.style("left", event.pageX + 10 + "px");
  150.           })
  151.           .on("mouseout", function () {
  152.             tooltip.style("visibility", "hidden");
  153.           });
  154.  
  155.         svg
  156.           .append("text")
  157.           .attr("x", margin.left + (width - margin.left - margin.right) / 2)
  158.           .attr("y", height - margin.bottom / 5)
  159.           .attr("class", "label")
  160.           .text("Year");
  161.  
  162.         svg
  163.           .append("text")
  164.           .attr("y", margin.left / 4)
  165.           .attr("x", -height / 2)
  166.           .attr("transform", "rotate(-90)")
  167.           .attr("class", "label")
  168.           .text("Time to finish");
  169.  
  170.         svg
  171.           .append("text")
  172.           .attr("x", margin.left + (width - margin.left - margin.right) / 2)
  173.           .attr("y", margin.top / 2.6)
  174.           .attr("id", "title")
  175.           .text("Doping in professional bike racing");
  176.  
  177.         svg
  178.           .append("text")
  179.           .attr("x", margin.left + (width - margin.left - margin.right) / 2)
  180.           .attr("y", margin.top / 1.4)
  181.           .text("35 fastest times to finish Alpe d'Huez")
  182.           .style("font-size", "16px")
  183.           .style("text-anchor", "middle");
  184.  
  185.         svg
  186.           .selectAll("legendSymbols")
  187.           .data(legendKeys)
  188.           .enter()
  189.           .append("circle")
  190.           .attr("cx", width - margin.right - 200)
  191.           .attr("cy", (d, i) => 150 + i * 25)
  192.           .attr("r", 5)
  193.           .attr("fill", (d, i) => colors[i]);
  194.  
  195.         svg
  196.           .selectAll("legendTexts")
  197.           .data(legendKeys)
  198.           .enter()
  199.           .append("text")
  200.           .text((d) => d)
  201.           .attr("x", width - margin.right - 200 + 15)
  202.           .attr("y", (d, i) => 150 + i * 25 + 5)
  203.           .attr("class", "textbox");
  204.  
  205.         const legend = svg
  206.           .append("rect")
  207.           .attr("x", width - margin.right - 200 - 15)
  208.           .attr("y", 150 - 5 - 10)
  209.           .attr("rx", 5)
  210.           .attr("ry", 5)
  211.           .attr("width", 195)
  212.           .attr("height", 55)
  213.           .attr("id", "legend");
  214.  
  215.         // Annotation
  216.         var deceptiveData = data.filter((d) => d["Name"] === "Marco Pantani" && d["Year"] === 1997);
  217.         var deceptivePoint = svg
  218.           .selectAll("deceptivePoint")
  219.           .data(deceptiveData)
  220.           .enter()
  221.           .append("circle")
  222.           .attr("cx", (d) => xScale(d["Year"]))
  223.           .attr("cy", (d) => yScale(parseTime(d["Time"])))
  224.           .attr("r", 10)
  225.           .attr("stroke", "#c86984")
  226.           .attr("fill", "transparent")
  227.           .attr("class", "annotation");
  228.  
  229.         svg
  230.           .append("line")
  231.           .attr("x1", xScale(1997))
  232.           .attr("y1", yScale(parseTime("36:55")) - 10)
  233.           .attr("x2", xScale(1997) - 50)
  234.           .attr("y2", yScale(parseTime("36:55")) - 50)
  235.           .attr("stroke", "#c86984")
  236.           .attr("stroke-width", 2)
  237.           .attr("marker-end", "url(#arrow)")
  238.           .attr("class", "annotation");
  239.  
  240.         svg
  241.           .append("text")
  242.           .attr("x", xScale(1997) - 55)
  243.           .attr("y", yScale(parseTime("36:55")) - 55)
  244.           .text("Deceptive Value")
  245.           .attr("class", "annotation");
  246.  
  247.         svg
  248.           .append("defs")
  249.           .append("marker")
  250.           .attr("id", "arrow")
  251.           .attr("viewBox", "0 -5 10 10")
  252.           .attr("refX", 5)
  253.           .attr("refY", 0)
  254.           .attr("markerWidth", 4)
  255.           .attr("markerHeight", 4)
  256.           .attr("orient", "auto")
  257.           .append("path")
  258.           .attr("d", "M0,-5L10,0L0,5")
  259.           .attr("class", "annotation");
  260.       });
  261.     </script>
  262.   </body>
  263. </html>
  264. ```
  265.  
  266. This code adds an annotation to the chart to highlight the deceptive value of Marco Pantani's record for the year 1997. The annotation includes a circle around the data point, an arrowed line pointing to the data point, and a text label "Deceptive Value". The color of the annotation is #c86984.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement