3

I am trying to add the mouseover effect to my line graph. However, the hover circle that appears on the graph does not seem to follow my mouse and it stays still at the end of the line graph.

I followed the below guide to implement my mouseover but not sure what exactly did I do wrong.

https://bl.ocks.org/mbostock/3902569

Below is what I tried:

Data:

const prices = [{
      "data": [
        {
          "open": 9.67,
          "close": 9.98,
          "volume": 17876279,
          "symbol": "WISH",
          "date": "2021-08-05T00:00:00+0000"
        },
        {
          "open": 10.3,
          "close": 9.61,
          "volume": 34099145,
          "symbol": "WISH",
          "date": "2021-08-04T00:00:00+0000"
        },
        {
          "open": 10.36,
          "close": 10.31,
          "volume": 20379283,
          "symbol": "WISH",
          "date": "2021-08-03T00:00:00+0000"
        }
      ]
    }, {
      "data": [
        {
          "open": 27.3,
          "close": 28.33,
          "volume": 2360664,
          "symbol": "CRSR",
          "date": "2021-08-05T00:00:00+0000"
        },
        {
          "open": 26.83,
          "close": 27.4,
          "volume": 4409156,
          "symbol": "CRSR",
          "date": "2021-08-04T00:00:00+0000"
        },
        {
          "open": 26.99,
          "close": 27.13,
          "volume": 8675462,
          "symbol": "CRSR",
          "date": "2021-08-03T00:00:00+0000"
        }
      ]
    }];

Scripts:

d3.selectAll(".company-price")
        .data(prices)
        .each(lineChart);

function lineChart({data}){
        const priceMargin = {top: 10, right: 30, bottom: 30, left: 60};
        const priceWidth = 1000 - priceMargin.left - priceMargin.right;  
        const priceHeight = 400 - priceMargin.top - priceMargin.bottom;
        
        const svg = d3.select(this)
            .append('svg')
                .attr("width", priceWidth + priceMargin.left + priceMargin.right)
                .attr("height", priceHeight + priceMargin.top + priceMargin.bottom)
            .append("g")
                .attr("transform", `translate(${priceMargin.left},${priceMargin.top})`);
        
        const parseDate = d3.timeParse('%Y-%m-%dT%H:%M:%S%Z')

        const x = d3.scaleTime()
            .domain(d3.extent(data, d => parseDate(d.date)))
            .range([0, priceWidth]);

        const y = d3.scaleLinear()
            .domain(d3.extent(data, d => d.close))
            .range([priceHeight, 0]);

        const line = d3.line()
            .x(d => x(parseDate(d.date)))
            .y(d => y(d.close))

        svg.append("path")
            .attr("fill", "none")
            .attr("stroke", "rgba(255, 31, 31)")
            .attr('d', line(data))
            .style("stroke-width", "2px")

        svg.append('g')
            .call(d3.axisLeft(y))
            .attr("class", "d3-axes")

        svg.append('g')
            .attr("transform", `translate(0, ${priceHeight})`)
            .call(d3.axisBottom(x))
            .attr("class", "d3-axes")

        const bisectDate = d3.bisector(function(d) { return d.date; }).left,
            formatValue = d3.format(",.2f"),
            formatCurrency = function(d) { return "$" + formatValue(d); };

        const focus = svg.append('g')
            .attr('class', 'focus')
            .style('display', 'none')
    
        focus.append('circle')
            .attr('r', 4.5);

        focus.append('text')
            .attr('x', 9)
            .attr('dy', '.35em');

        svg.append("rect")
            .attr("class", "overlay")
            .attr("width", priceWidth)
            .attr("height", priceHeight)
            .on("mouseover", function() { focus.style("display", null); })
            .on("mouseout", function() { focus.style("display", "none"); })
            .on("mousemove", mousemove);

        function mousemove() {
            var x0 = x.invert(d3.mouse(this)[0]),
                i = bisectDate(data, x0, 1),
                d0 = data[i - 1],
                d1 = data[i],
                d = x0 - d0.date > d1.date - x0 ? d1 : d0;
                console.log(i)
            focus.attr("transform", "translate(" + x(parseDate(d.date)) + "," + y(d.close) + ")");
            focus.select("text").text(formatCurrency(d.close));
        }
}

CSS:

.d3-axes{
    color: rgb(232, 232, 232);
    font-size: 14px;
}

.overlay {
    fill: none;
    pointer-events: all;
}

.focus circle {
    fill: none;
    stroke: steelblue;
}

Below is a screenshot of my graph. The hover on the graph does not follow my mouse moves and stays still at the end of the line, the value also does not change as I move the mouse along the line. Also in my console log, the "i" that returned from the bisector always seems to be 1 and that "i" never changes

enter image description here

0 Answers0