@@ -408,6 +408,7 @@ void drawChart(
408408 final legendWidth = 20 ;
409409 final legendHeight = 8 ;
410410
411+ final linePaths = < SVGPathElement > [];
411412 for (int i = 0 ; i < lines.length; i++ ) {
412413 // We add the lines in reverse order so that the newest versions get the
413414 // main colors.
@@ -416,6 +417,7 @@ void drawChart(
416417 path.setAttribute ('class' , '${strokeColorClass (i )} downloads-chart-line ' );
417418 path.setAttribute ('d' , '$line ' );
418419 path.setAttribute ('clip-path' , 'url(#clipRect)' );
420+ linePaths.add (path);
419421 chart.append (path);
420422
421423 if (displayMode == DisplayMode .stacked ||
@@ -475,11 +477,17 @@ void drawChart(
475477
476478 // Setup mouse handling
477479
478- DateTime ? lastSelectedDay;
479480 void hideCursor (_) {
480481 cursor.setAttribute ('style' , 'opacity:0' );
481482 toolTip.setAttribute ('style' , 'opacity:0;position:absolute;' );
482- lastSelectedDay = null ;
483+ }
484+
485+ void resetHighlights () {
486+ for (int i = 0 ; i < linePaths.length; i++ ) {
487+ final l = linePaths[i];
488+ l.removeAttribute ('class' );
489+ l.setAttribute ('class' , '${strokeColorClass (i )} downloads-chart-line' );
490+ }
483491 }
484492
485493 hideCursor (1 );
@@ -491,13 +499,16 @@ void drawChart(
491499 e.y < boundingRect.y + yMax ||
492500 e.y > boundingRect.y + yZero) {
493501 // We are outside the actual chart area
502+ resetHighlights ();
494503 hideCursor (1 );
495504 return ;
496505 }
497506
498507 cursor.setAttribute ('style' , 'opacity:1' );
508+ final yPosition = e.y - boundingRect.y;
509+ final xPosition = e.x - boundingRect.x;
510+ final pointPercentage = (xPosition - xZero) / chartWidth;
499511
500- final pointPercentage = (e.x - boundingRect.x - xZero) / chartWidth;
501512 final horizontalPosition =
502513 e.x + toolTip.getBoundingClientRect ().width > width
503514 ? 'left:${e .x - toolTip .getBoundingClientRect ().width }px;'
@@ -508,7 +519,14 @@ void drawChart(
508519 final nearestIndex = ((values.length - 1 ) * pointPercentage).round ();
509520 final selectedDay =
510521 computeDateForWeekNumber (newestDate, values.length, nearestIndex);
511- if (selectedDay == lastSelectedDay) return ;
522+
523+ // Determine if we are close enough to highlight one or more version ranges
524+ final highlightRangeIndices = < int > {};
525+ for (int i = 0 ; i < lines.length; i++ ) {
526+ if (isPointOnPathWithTolerance (lines[i], (xPosition, yPosition), 5 )) {
527+ highlightRangeIndices.add (i);
528+ }
529+ }
512530
513531 final coords = computeCoordinates (selectedDay, 0 );
514532 cursor.setAttribute ('transform' , 'translate(${coords .$1 }, 0)' );
@@ -528,10 +546,6 @@ void drawChart(
528546 ..setAttribute (
529547 'class' , 'downloads-chart-tooltip-square ${squareColorClass (i )}' );
530548 final rangeText = HTMLSpanElement ()..text = '${ranges [rangeIndex ]}: ' ;
531- final tooltipRange = HTMLDivElement ()
532- ..setAttribute ('class' , 'downloads-chart-tooltip-row' )
533- ..append (square)
534- ..append (rangeText);
535549
536550 final suffix = (displayMode == DisplayMode .percentage)
537551 ? ' (${(downloads [rangeIndex ] * 100 / totals [nearestIndex ]).toStringAsPrecision (2 )}%)'
@@ -541,15 +555,38 @@ void drawChart(
541555 final downloadsText = HTMLSpanElement ()
542556 ..setAttribute ('class' , 'downloads-chart-tooltip-downloads' )
543557 ..text = text;
558+
559+ linePaths[i].removeAttribute ('class' );
560+
561+ if (highlightRangeIndices.contains (rangeIndex)) {
562+ rangeText.setAttribute ('class' , 'downloads-chart-tooltip-highlight' );
563+ downloadsText.setAttribute (
564+ 'class' , 'downloads-chart-tooltip-highlight' );
565+ linePaths[i].setAttribute (
566+ 'class' , '${strokeColorClass (i )} downloads-chart-line' );
567+ } else if (highlightRangeIndices.isNotEmpty) {
568+ linePaths[i].setAttribute (
569+ 'class' , '${strokeColorClass (i )} downloads-chart-line-faded' );
570+ } else {
571+ linePaths[i].setAttribute (
572+ 'class' , '${strokeColorClass (i )} downloads-chart-line' );
573+ }
574+ final tooltipRange = HTMLDivElement ()
575+ ..setAttribute ('class' , 'downloads-chart-tooltip-row' )
576+ ..append (square)
577+ ..append (rangeText);
578+
544579 final tooltipRow = HTMLDivElement ()
545580 ..setAttribute ('class' , 'downloads-chart-tooltip-row' )
546581 ..append (tooltipRange)
547582 ..append (downloadsText);
548583 toolTip.append (tooltipRow);
549584 }
550585 }
551- lastSelectedDay = selectedDay;
552586 });
553587
554- svg.onMouseLeave.listen (hideCursor);
588+ svg.onMouseLeave.listen ((e) {
589+ resetHighlights ();
590+ hideCursor (1 );
591+ });
555592}
0 commit comments