Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Here is the modified code:
- ```html
- <!doctype html>
- <meta charset="utf-8" />
- <html>
- <head>
- <script src="https://d3js.org/d3.v6.min.js" charset="utf-8"></script>
- </head>
- <style>
- * {
- font-family: sans-serif;
- }
- #tooltip {
- visibility: hidden;
- position: absolute;
- opacity: 0.8;
- padding: 10px;
- vertical-align: middle;
- border-radius: 5px;
- background-color: #ecf0f1;
- font-size: 14px;
- }
- .textbox {
- font-size: 14px;
- }
- #legend {
- opacity: 0.2;
- fill: #2c3e50;
- }
- #title {
- text-anchor: middle;
- font-size: 22px;
- }
- .label {
- text-anchor: middle;
- }
- #svg {
- background-color: white;
- }
- .annotation {
- fill: #c86984;
- stroke: #c86984;
- }
- </style>
- <body>
- <div id="container" align="center"></div>
- <script type="text/javascript">
- var url =
- "https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json";
- var colors = ["#27ae60", "#8e44ad"];
- var legendKeys = ["No Doping Allegations", "Doping Allegations"];
- const tooltip = d3
- .select("body")
- .append("div")
- .attr("id", "tooltip")
- .style("visibility", "hidden");
- d3.json(url).then(function (data) {
- var width = 700;
- var height = 500;
- var margin = { left: 90, top: 80, bottom: 50, right: 20 };
- var axisOffset = 10;
- const svg = d3
- .select("#container")
- .append("svg")
- .attr("id", "svg")
- .attr("width", width)
- .attr("height", height);
- var xMin = d3.min(data, (d) => d["Year"]);
- var xMax = d3.max(data, (d) => d["Year"]);
- var parseTime = d3.timeParse("%M:%S");
- var yMin = d3.min(data, (d) => parseTime(d["Time"]));
- var yMax = d3.max(data, (d) => parseTime(d["Time"]));
- var xScale = d3
- .scaleLinear()
- .domain([xMin, xMax])
- .range([margin.left + axisOffset, width - margin.right]);
- var yScale = d3
- .scaleTime()
- .domain([yMax, yMin])
- .range([height - margin.bottom - axisOffset, margin.top]);
- var xAxis = d3.axisBottom().scale(xScale).tickFormat(d3.format("d"));
- var yAxis = d3
- .axisLeft()
- .scale(yScale)
- .tickFormat(d3.timeFormat("%M:%S"));
- svg
- .append("g")
- .attr("transform", "translate(0, " + (height - margin.bottom) + ")")
- .attr("id", "x-axis")
- .call(xAxis);
- svg
- .append("g")
- .attr("transform", "translate(" + margin.left + ", 0)")
- .attr("id", "y-axis")
- .call(yAxis);
- svg
- .selectAll("scatterPoints")
- .data(data)
- .enter()
- .append("circle")
- .attr("cx", (d) => xScale(d["Year"]))
- .attr("cy", (d) => yScale(parseTime(d["Time"])))
- .attr("r", 5)
- .attr("fill", (d) => (d["Doping"] == "" ? colors[0] : colors[1]))
- .attr("class", "dot")
- .attr("data-xvalue", (d) => d["Year"])
- .attr("data-yvalue", (d) => parseTime(d["Time"]))
- .on("mouseover", function (d) {
- info = d["originalTarget"]["__data__"];
- tooltip
- .style("visibility", "visible")
- .style("left", event.pageX + 10 + "px")
- .style("top", event.pageY - 80 + "px")
- .attr("data-year", info["Year"])
- .html(
- info["Name"] +
- " (" +
- info["Year"] +
- ") <br> Time: " +
- info["Time"] +
- "<br><br>" +
- info["Doping"]
- );
- })
- .on("mousemove", function () {
- tooltip.style("left", event.pageX + 10 + "px");
- })
- .on("mouseout", function () {
- tooltip.style("visibility", "hidden");
- });
- svg
- .append("text")
- .attr("x", margin.left + (width - margin.left - margin.right) / 2)
- .attr("y", height - margin.bottom / 5)
- .attr("class", "label")
- .text("Year");
- svg
- .append("text")
- .attr("y", margin.left / 4)
- .attr("x", -height / 2)
- .attr("transform", "rotate(-90)")
- .attr("class", "label")
- .text("Time to finish");
- svg
- .append("text")
- .attr("x", margin.left + (width - margin.left - margin.right) / 2)
- .attr("y", margin.top / 2.6)
- .attr("id", "title")
- .text("Doping in professional bike racing");
- svg
- .append("text")
- .attr("x", margin.left + (width - margin.left - margin.right) / 2)
- .attr("y", margin.top / 1.4)
- .text("35 fastest times to finish Alpe d'Huez")
- .style("font-size", "16px")
- .style("text-anchor", "middle");
- svg
- .selectAll("legendSymbols")
- .data(legendKeys)
- .enter()
- .append("circle")
- .attr("cx", width - margin.right - 200)
- .attr("cy", (d, i) => 150 + i * 25)
- .attr("r", 5)
- .attr("fill", (d, i) => colors[i]);
- svg
- .selectAll("legendTexts")
- .data(legendKeys)
- .enter()
- .append("text")
- .text((d) => d)
- .attr("x", width - margin.right - 200 + 15)
- .attr("y", (d, i) => 150 + i * 25 + 5)
- .attr("class", "textbox");
- const legend = svg
- .append("rect")
- .attr("x", width - margin.right - 200 - 15)
- .attr("y", 150 - 5 - 10)
- .attr("rx", 5)
- .attr("ry", 5)
- .attr("width", 195)
- .attr("height", 55)
- .attr("id", "legend");
- // Annotation
- var deceptiveData = data.filter((d) => d["Name"] === "Marco Pantani" && d["Year"] === 1997);
- var deceptivePoint = svg
- .selectAll("deceptivePoint")
- .data(deceptiveData)
- .enter()
- .append("circle")
- .attr("cx", (d) => xScale(d["Year"]))
- .attr("cy", (d) => yScale(parseTime(d["Time"])))
- .attr("r", 10)
- .attr("stroke", "#c86984")
- .attr("fill", "transparent")
- .attr("class", "annotation");
- svg
- .append("line")
- .attr("x1", xScale(1997))
- .attr("y1", yScale(parseTime("36:55")) - 10)
- .attr("x2", xScale(1997) - 50)
- .attr("y2", yScale(parseTime("36:55")) - 50)
- .attr("stroke", "#c86984")
- .attr("stroke-width", 2)
- .attr("marker-end", "url(#arrow)")
- .attr("class", "annotation");
- svg
- .append("text")
- .attr("x", xScale(1997) - 55)
- .attr("y", yScale(parseTime("36:55")) - 55)
- .text("Deceptive Value")
- .attr("class", "annotation");
- svg
- .append("defs")
- .append("marker")
- .attr("id", "arrow")
- .attr("viewBox", "0 -5 10 10")
- .attr("refX", 5)
- .attr("refY", 0)
- .attr("markerWidth", 4)
- .attr("markerHeight", 4)
- .attr("orient", "auto")
- .append("path")
- .attr("d", "M0,-5L10,0L0,5")
- .attr("class", "annotation");
- });
- </script>
- </body>
- </html>
- ```
- 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