Advertisement
NTahmid

title_scatter_v2

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