Advertisement
NTahmid

data_range_v2_scatter

Feb 22nd, 2024
644
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 8.37 KB | None | 0 0
  1. Here is the modified code with annotations for data ranges:
  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.     <script src="https://rawgit.com/susielu/d3-annotation/master/d3-annotation.min.js"></script>
  10.   </head>
  11.  
  12.   <style>
  13.     * {
  14.       font-family: sans-serif;
  15.     }
  16.  
  17.     #tooltip {
  18.       visibility: hidden;
  19.       position: absolute;
  20.       opacity: 0.8;
  21.       padding: 10px;
  22.       vertical-align: middle;
  23.       border-radius: 5px;
  24.       background-color: #ecf0f1;
  25.       font-size: 14px;
  26.     }
  27.  
  28.     .textbox {
  29.       font-size: 14px;
  30.     }
  31.  
  32.     #legend {
  33.       opacity: 0.2;
  34.       fill: #2c3e50;
  35.     }
  36.  
  37.     #title {
  38.       text-anchor: middle;
  39.       font-size: 22px;
  40.     }
  41.  
  42.     .label {
  43.       text-anchor: middle;
  44.     }
  45.  
  46.     #svg {
  47.       background-color: white;
  48.     }
  49.   </style>
  50.  
  51.   <body>
  52.     <div id="container" align="center"></div>
  53.  
  54.     <script type="text/javascript">
  55.       // Url to the input data
  56.       var url =
  57.         "https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json";
  58.  
  59.       // Colors to differentiate riders with and without doping allegations
  60.       var colors = ["#27ae60", "#8e44ad"];
  61.  
  62.       // The attributes of the riders corresponding to the above colors
  63.       var legendKeys = ["No Doping Allegations", "Doping Allegations"];
  64.  
  65.       // Create an invisible div for the tooltip
  66.       const tooltip = d3
  67.         .select("body")
  68.         .append("div")
  69.         .attr("id", "tooltip")
  70.         .style("visibility", "hidden");
  71.  
  72.       // 1. Load the data from external source
  73.       d3.json(url).then(function (data) {
  74.         // 2. Append svg-object for the bar chart to a div in your webpage
  75.         // (here we use a div with id=container)
  76.         var width = 700;
  77.         var height = 500;
  78.         var margin = { left: 90, top: 80, bottom: 50, right: 20 };
  79.         var axisOffset = 10; // How for the axes are moved away from each other
  80.  
  81.         const svg = d3
  82.           .select("#container")
  83.           .append("svg")
  84.           .attr("id", "svg")
  85.           .attr("width", width)
  86.           .attr("height", height);
  87.  
  88.         // 3. Define scales to translate domains of the data to the range of the svg
  89.         var xMin = d3.min(data, (d) => d["Year"]);
  90.         var xMax = d3.max(data, (d) => d["Year"]);
  91.  
  92.         var parseTime = d3.timeParse("%M:%S");
  93.         var yMin = d3.min(data, (d) => parseTime(d["Time"]));
  94.         var yMax = d3.max(data, (d) => parseTime(d["Time"]));
  95.  
  96.         var xScale = d3
  97.           .scaleLinear()
  98.           .domain([xMin, xMax])
  99.           .range([margin.left + axisOffset, width - margin.right]);
  100.  
  101.         var yScale = d3
  102.           .scaleTime()
  103.           .domain([yMax, yMin])
  104.           .range([height - margin.bottom - axisOffset, margin.top]);
  105.  
  106.         // 4. Draw and transform/translate horizontal and vertical axes
  107.         var xAxis = d3.axisBottom().scale(xScale).tickFormat(d3.format("d"));
  108.         var yAxis = d3
  109.           .axisLeft()
  110.           .scale(yScale)
  111.           .tickFormat(d3.timeFormat("%M:%S"));
  112.  
  113.         svg
  114.           .append("g")
  115.           .attr("transform", "translate(0, " + (height - margin.bottom) + ")")
  116.           .attr("id", "x-axis")
  117.           .call(xAxis);
  118.  
  119.         svg
  120.           .append("g")
  121.           .attr("transform", "translate(" + margin.left + ", 0)")
  122.           .attr("id", "y-axis")
  123.           .call(yAxis);
  124.  
  125.         // 5. Draw individual scatter points and define mouse events for the tooltip
  126.         svg
  127.           .selectAll("scatterPoints")
  128.           .data(data)
  129.           .enter()
  130.           .append("circle")
  131.           .attr("cx", (d) => xScale(d["Year"]))
  132.           .attr("cy", (d) => yScale(parseTime(d["Time"])))
  133.           .attr("r", 5)
  134.           .attr("fill", (d) => (d["Doping"] == "" ? colors[0] : colors[1]))
  135.           .attr("class", "dot")
  136.           .attr("data-xvalue", (d) => d["Year"])
  137.           .attr("data-yvalue", (d) => parseTime(d["Time"]))
  138.           .on("mouseover", function (d) {
  139.             info = d["originalTarget"]["__data__"];
  140.             tooltip
  141.               .style("visibility", "visible")
  142.               .style("left", event.pageX + 10 + "px")
  143.               .style("top", event.pageY - 80 + "px")
  144.               .attr("data-year", info["Year"])
  145.               .html(
  146.                 info["Name"] +
  147.                   " (" +
  148.                   info["Year"] +
  149.                   ") <br> Time: " +
  150.                   info["Time"] +
  151.                   "<br><br>" +
  152.                   info["Doping"]
  153.               );
  154.           })
  155.           .on("mousemove", function () {
  156.             tooltip.style("left", event.pageX + 10 + "px");
  157.           })
  158.           .on("mouseout", function () {
  159.             tooltip.style("visibility", "hidden");
  160.           });
  161.  
  162.         // 6. Finalize chart by adding title, axes labels and legend
  163.        
  164.         //X-axis label
  165.         svg
  166.           .append("text")
  167.           .attr("x", margin.left + (width - margin.left - margin.right) / 2)
  168.           .attr("y", height - margin.bottom / 5)
  169.           .attr("class", "label")
  170.           .text("Year");
  171.  
  172.  
  173.         //Y-axis label
  174.         svg
  175.           .append("text")
  176.           .attr("y", margin.left / 4)
  177.           .attr("x", -height / 2)
  178.           .attr("transform", "rotate(-90)")
  179.           .attr("class", "label")
  180.           .text("Time to finish");
  181.  
  182.         //Title of the chart
  183.         svg
  184.           .append("text")
  185.           .attr("x", margin.left + (width - margin.left - margin.right) / 2)
  186.           .attr("y", margin.top / 2.6)
  187.           .attr("id", "title")
  188.           .text("Doping in professional bike racing");
  189.  
  190.         svg
  191.           .append("text")
  192.           .attr("x", margin.left + (width - margin.left - margin.right) / 2)
  193.           .attr("y", margin.top / 1.4)
  194.           .text("35 fastest times to finish Alpe d'Huez")
  195.           .style("font-size", "16px")
  196.           .style("text-anchor", "middle");
  197.  
  198.         //Chart Legends
  199.         svg
  200.           .selectAll("legendSymbols")
  201.           .data(legendKeys)
  202.           .enter()
  203.           .append("circle")
  204.           .attr("cx", width - margin.right - 200)
  205.           .attr("cy", (d, i) => 150 + i * 25)
  206.           .attr("r", 5)
  207.           .attr("fill", (d, i) => colors[i]);
  208.  
  209.         svg
  210.           .selectAll("legendTexts")
  211.           .data(legendKeys)
  212.           .enter()
  213.           .append("text")
  214.           .text((d) => d)
  215.           .attr("x", width - margin.right - 200 + 15)
  216.           .attr("y", (d, i) => 150 + i * 25 + 5)
  217.           .attr("class", "textbox");
  218.  
  219.         const legend = svg
  220.           .append("rect")
  221.           .attr("x", width - margin.right - 200 - 15)
  222.           .attr("y", 150 - 5 - 10)
  223.           .attr("rx", 5)
  224.           .attr("ry", 5)
  225.           .attr("width", 195)
  226.           .attr("height", 55)
  227.           .attr("id", "legend");
  228.  
  229.         // Annotations for data ranges
  230.         const annotations = [
  231.           {
  232.             note: {
  233.               label: "Year data range",
  234.               title: "Data Range",
  235.             },
  236.             x: xScale(xMin),
  237.             y: height - margin.bottom,
  238.             dx: xScale(xMax) - xScale(xMin),
  239.             dy: 0,
  240.             type: d3.annotationCalloutCurve,
  241.             subject: {
  242.               radius: 25,
  243.             },
  244.             color: "#c86984",
  245.           },
  246.           {
  247.             note: {
  248.               label: "Time data range",
  249.               title: "Data Range",
  250.             },
  251.             x: margin.left,
  252.             y: yScale(yMax),
  253.             dx: 0,
  254.             dy: yScale(yMin) - yScale(yMax),
  255.             type: d3.annotationCalloutCurve,
  256.             subject: {
  257.               radius: 25,
  258.             },
  259.             color: "#c86984",
  260.           },
  261.         ];
  262.  
  263.         const makeAnnotations = d3
  264.           .annotation()
  265.           .annotations(annotations)
  266.           .type(d3.annotationLabel);
  267.  
  268.         svg.append("g").call(makeAnnotations);
  269.       });
  270.     </script>
  271.   </body>
  272. </html>
  273. ```
  274.  
  275. This code adds two annotations to the chart, one for the 'Year' data range and another for the 'Time' data range. The annotations are drawn as curved lines with arrows at both ends, and they are colored #c86984 as specified. The labels and titles of the annotations are set to "Year data range" and "Time data range", respectively, and the title of both annotations is "Data Range".
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement