0

I am making an indexed chart and I would like to be able to calculate the rate change between the previous data value, and the one that is currently being hovered over. What do you suggest is the best way to do this in a multiline chart? I saw some of the previous posts, but they are 4-6 years old, and furthermore didn't work for me.

    const dateParser = d3.timeParse('%Y');
    const formatYear = d3.timeFormat('%Y');
    const xAccessor = d => dateParser(d.time.substring(0, 4));
   


    const y0Accessor = d => d.vr;
    const y1Accessor = d => d.unemp;

    const colorValue = d => d.className;
    const colorScale = d3.scaleOrdinal()
        .range(d3.schemeSet1);

    const xScale = d3.scaleTime()
        .domain(d3.extent(data, xAccessor))
        .range([0, boundedWidth]);


    const yScale = d3.scaleLinear()
        .domain([50, 200])
        .range([boundedHeight, 0]);
  
    const previousData = d3.local();
        
    function drawData(g, accessor, color, id){ 
        // draw circles
        g.attr('class', 'line');

        g.selectAll('circle').data(data).enter() .append('circle')
            .attr('r', 4)
            .attr('cx', d => xScale(xAccessor(d)))
            .attr('cy', accessor)
            .attr('class', `data-point ${id.replace(/\s/g, '')}`)
            .style('fill', colorScale(id))


            .on('mouseover', function() {
                d3.select(this)
                    .transition()
                    .attr('r', 6);
            })

            
            .on('mouseout', function() {
                d3.select(this)
                    .transition()
                    .attr('r', 4);
            })
            .style('cursor', 'pointer')
            .attr('fill', color);

  // draw lines
        const lineGenerator = d3.line()
            .curve(d3.curveMonotoneX) 
            .x(d=>xScale(xAccessor(d)))
            .y(accessor);
        g.append('path')
            .attr('fill', 'none')
            .attr('d', lineGenerator(data))
            .attr('stroke', color)
            .attr('class', `data-point ${id.replace(/\s/g, '')}`)

            .style('stroke-width', '3px');
    }

    const g1 = bounds.append('g');
    const g2 = bounds.append('g');
    
    drawData(g1, d=> yScale(y0Accessor(d)), '#e41a1c', 'Vacancy Rate');
    drawData(g2, d => yScale(y1Accessor(d)), '#377eb8', 'Unemployment Rate');
    
  
    //Create the axis
  
    const y0AxisGenerator = d3.axisLeft()
        .scale(yScale)
        .ticks(5);
        
 

    const yAxisLabel = yAxis.append('text')
        .attr('class', 'y-axis-label')
        .attr('x', -boundedHeight / 2)
        .attr('y', -dimensions.margin.left + 50)
        .html('Difference Rate');

    const xAxisGenerator = d3.axisBottom(xScale);

        
    const xAxis = bounds.append('g')
        .attr('class', 'x-axis')
        .style('transform', `translateY(${boundedHeight}px)`)
        .call(xAxisGenerator);
    


//interactions


    const tooltip = d3.select('#tooltip');


        //gets all the key names
    // color.domain(d3.keys(data[0]).filter(function(key) { return key !== 'label'; }));


    g1.selectAll('circle')
        .on('mouseenter', function(event) {
            const value = d3.select(this).data()[0];
  
            tooltip.call(onMouseEnter, yScale, y0Accessor, value);
        })
        .on('mouseleave', onMouseLeave);
  
    g2.selectAll('circle')
        .on('mouseenter', function(event, i) {
            const value = d3.select(this).data()[0];
            tooltip.call(onMouseEnter, yScale, y1Accessor, value, i);
            
        })
        .on('mouseleave', onMouseLeave);
        
    function onMouseEnter(g, yScale, accessor, data, i) {
        g.select('#value')
            .text(       
                `${accessor(data)}%`
            );
        const x = xScale(xAccessor(data)) + dimensions.margin.left;
        const y = yScale(accessor(data)) + dimensions.margin.top;

        g.style('transform', `translate(`
      + `calc(-50% + ${x}px),`
      + `calc(-100% + ${y}px)`
      + `)`);
    
        g.style('opacity', .8);
    }

    function onMouseLeave() {
        tooltip.style('opacity', 0);
    }

  • Does this answer your question? [Compare/Diff new data with previous data on d3.js update](https://stackoverflow.com/questions/23409250/compare-diff-new-data-with-previous-data-on-d3-js-update) why the approaches from 4-6 years ago didn't work? – Rodrigo Divino Jan 12 '21 at 10:01
  • I was looking at that but I don't want to introduce a new dataset - I just want the previous point before, and only during a mouseover so that I can calculate the difference. Thanks! – Maxene Graze Jan 12 '21 at 15:54

0 Answers0