Skip to content

Commit

Permalink
Downloads chart: highlight line chart and tooltip row on hover (dart-…
Browse files Browse the repository at this point in the history
  • Loading branch information
szakarias authored Feb 28, 2025
1 parent 818f473 commit 31ff721
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 10 deletions.
57 changes: 47 additions & 10 deletions pkg/web_app/lib/src/widget/downloads_chart/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ void drawChart(
final legendWidth = 20;
final legendHeight = 8;

final linePaths = <SVGPathElement>[];
for (int i = 0; i < lines.length; i++) {
// We add the lines in reverse order so that the newest versions get the
// main colors.
Expand All @@ -416,6 +417,7 @@ void drawChart(
path.setAttribute('class', '${strokeColorClass(i)} downloads-chart-line ');
path.setAttribute('d', '$line');
path.setAttribute('clip-path', 'url(#clipRect)');
linePaths.add(path);
chart.append(path);

if (displayMode == DisplayMode.stacked ||
Expand Down Expand Up @@ -475,11 +477,17 @@ void drawChart(

// Setup mouse handling

DateTime? lastSelectedDay;
void hideCursor(_) {
cursor.setAttribute('style', 'opacity:0');
toolTip.setAttribute('style', 'opacity:0;position:absolute;');
lastSelectedDay = null;
}

void resetHighlights() {
for (int i = 0; i < linePaths.length; i++) {
final l = linePaths[i];
l.removeAttribute('class');
l.setAttribute('class', '${strokeColorClass(i)} downloads-chart-line');
}
}

hideCursor(1);
Expand All @@ -491,13 +499,16 @@ void drawChart(
e.y < boundingRect.y + yMax ||
e.y > boundingRect.y + yZero) {
// We are outside the actual chart area
resetHighlights();
hideCursor(1);
return;
}

cursor.setAttribute('style', 'opacity:1');
final yPosition = e.y - boundingRect.y;
final xPosition = e.x - boundingRect.x;
final pointPercentage = (xPosition - xZero) / chartWidth;

final pointPercentage = (e.x - boundingRect.x - xZero) / chartWidth;
final horizontalPosition =
e.x + toolTip.getBoundingClientRect().width > width
? 'left:${e.x - toolTip.getBoundingClientRect().width}px;'
Expand All @@ -508,7 +519,14 @@ void drawChart(
final nearestIndex = ((values.length - 1) * pointPercentage).round();
final selectedDay =
computeDateForWeekNumber(newestDate, values.length, nearestIndex);
if (selectedDay == lastSelectedDay) return;

// Determine if we are close enough to highlight one or more version ranges
final highlightRangeIndices = <int>{};
for (int i = 0; i < lines.length; i++) {
if (isPointOnPathWithTolerance(lines[i], (xPosition, yPosition), 5)) {
highlightRangeIndices.add(i);
}
}

final coords = computeCoordinates(selectedDay, 0);
cursor.setAttribute('transform', 'translate(${coords.$1}, 0)');
Expand All @@ -528,10 +546,6 @@ void drawChart(
..setAttribute(
'class', 'downloads-chart-tooltip-square ${squareColorClass(i)}');
final rangeText = HTMLSpanElement()..text = '${ranges[rangeIndex]}: ';
final tooltipRange = HTMLDivElement()
..setAttribute('class', 'downloads-chart-tooltip-row')
..append(square)
..append(rangeText);

final suffix = (displayMode == DisplayMode.percentage)
? ' (${(downloads[rangeIndex] * 100 / totals[nearestIndex]).toStringAsPrecision(2)}%)'
Expand All @@ -541,15 +555,38 @@ void drawChart(
final downloadsText = HTMLSpanElement()
..setAttribute('class', 'downloads-chart-tooltip-downloads')
..text = text;

linePaths[i].removeAttribute('class');

if (highlightRangeIndices.contains(rangeIndex)) {
rangeText.setAttribute('class', 'downloads-chart-tooltip-highlight');
downloadsText.setAttribute(
'class', 'downloads-chart-tooltip-highlight');
linePaths[i].setAttribute(
'class', '${strokeColorClass(i)} downloads-chart-line');
} else if (highlightRangeIndices.isNotEmpty) {
linePaths[i].setAttribute(
'class', '${strokeColorClass(i)} downloads-chart-line-faded');
} else {
linePaths[i].setAttribute(
'class', '${strokeColorClass(i)} downloads-chart-line');
}
final tooltipRange = HTMLDivElement()
..setAttribute('class', 'downloads-chart-tooltip-row')
..append(square)
..append(rangeText);

final tooltipRow = HTMLDivElement()
..setAttribute('class', 'downloads-chart-tooltip-row')
..append(tooltipRange)
..append(downloadsText);
toolTip.append(tooltipRow);
}
}
lastSelectedDay = selectedDay;
});

svg.onMouseLeave.listen(hideCursor);
svg.onMouseLeave.listen((e) {
resetHighlights();
hideCursor(1);
});
}
14 changes: 14 additions & 0 deletions pkg/web_css/lib/src/_pkg.scss
Original file line number Diff line number Diff line change
Expand Up @@ -342,13 +342,20 @@
padding-left: 10px;
}

.downloads-chart-tooltip-highlight {
font-weight: bold;
color:var(--pub-neutral-textColor);
}


.downloads-chart-tooltip-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
font-size: small;
color: var(--pub-score_label-text-color);
padding-right: 4px;
}

.downloads-chart-cursor {
Expand Down Expand Up @@ -448,6 +455,13 @@
stroke-linejoin: round;
}

.downloads-chart-line-faded {
fill: none;
stroke-width: 2;
stroke-linejoin: round;
opacity: 0.3;
}

.downloads-chart-area {
opacity: 0.3;
}
Expand Down

0 comments on commit 31ff721

Please sign in to comment.