Advertisement
NTahmid

complex_trend_scatter

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