diff --git a/stockscope/src/main/java/com/sharecomparison/presentation/WebPageController.java b/stockscope/src/main/java/com/sharecomparison/presentation/WebPageController.java index 38e313c..f859a02 100644 --- a/stockscope/src/main/java/com/sharecomparison/presentation/WebPageController.java +++ b/stockscope/src/main/java/com/sharecomparison/presentation/WebPageController.java @@ -4,8 +4,11 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -81,7 +84,26 @@ public String compare( if (maxPrice == minPrice) maxPrice += 1.0; double priceRange = maxPrice - minPrice; - int n = Math.min(data1.size(), data2.size()); + // Align series by date: only plot dates present in both data sets + Map map1 = data1.stream() + .collect(Collectors.toMap(PriceData::getDate, p -> p, (existing, replacement) -> existing)); + Map map2 = data2.stream() + .collect(Collectors.toMap(PriceData::getDate, p -> p, (existing, replacement) -> existing)); + + Set commonDates = new LinkedHashSet<>(map1.keySet()); + commonDates.retainAll(map2.keySet()); + List sortedDates = new ArrayList<>(commonDates); + sortedDates.sort(Comparator.naturalOrder()); + + int n = sortedDates.size(); + if (n == 0) { + model.addAttribute("error", "No overlapping trading dates found for the two symbols in this range."); + model.addAttribute("symbol1", symbol1); + model.addAttribute("symbol2", symbol2); + model.addAttribute("startDate", start.toString()); + model.addAttribute("endDate", end.toString()); + return "index"; + } double xStep = n > 1 ? chartWidth / (n - 1) : 0; StringBuilder path1 = new StringBuilder(); @@ -91,16 +113,17 @@ public String compare( for (int i = 0; i < n; i++) { double x = left + i * xStep; + LocalDate date = sortedDates.get(i); - PriceData p1 = data1.get(i); + PriceData p1 = map1.get(date); double y1 = bottom - ((p1.getClosingPrice() - minPrice) / priceRange) * chartHeight; path1.append(i == 0 ? "M" : "L").append(x).append(",").append(y1).append(" "); - points1.add(Map.of("x", x, "y", y1, "value", p1.getClosingPrice())); + points1.add(Map.of("x", x, "y", y1, "value", p1.getClosingPrice(), "date", date.toString())); - PriceData p2 = data2.get(i); + PriceData p2 = map2.get(date); double y2 = bottom - ((p2.getClosingPrice() - minPrice) / priceRange) * chartHeight; path2.append(i == 0 ? "M" : "L").append(x).append(",").append(y2).append(" "); - points2.add(Map.of("x", x, "y", y2, "value", p2.getClosingPrice())); + points2.add(Map.of("x", x, "y", y2, "value", p2.getClosingPrice(), "date", date.toString())); } Map chartData = new HashMap<>();