diff --git a/.idea/misc.xml b/.idea/misc.xml
index c3f3b0ab1ba765e267b1979ac687f9786d56644c..e42c9ea07099a590458543d35140e277f349c1a2 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,7 +7,7 @@
       </list>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/runConfigurations/App.xml b/.idea/runConfigurations/App.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1616e183f65e8e8d5a0773860b33ed96643df3b7
--- /dev/null
+++ b/.idea/runConfigurations/App.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="App" type="Application" factoryName="Application">
+    <option name="MAIN_CLASS_NAME" value="com.example.App" />
+    <module name="ad-auction-dashboard" />
+    <option name="VM_PARAMETERS" value="--module-path &quot;$USER_HOME$/.m2/repository/org/openjfx/javafx-controls/17.0.2/javafx-controls-17.0.2-win.jar;$USER_HOME$/.m2/repository/org/openjfx/javafx-graphics/17.0.2/javafx-graphics-17.0.2-win.jar;$USER_HOME$/.m2/repository/org/openjfx/javafx-base/17.0.2/javafx-base-17.0.2-win.jar;$USER_HOME$/.m2/repository/org/openjfx/javafx-fxml/17.0.2/javafx-fxml-17.0.2-win.jar&quot; --add-modules javafx.controls,javafx.fxml,javafx.graphics" />
+    <extension name="coverage">
+      <pattern>
+        <option name="PATTERN" value="com.example.*" />
+        <option name="ENABLED" value="true" />
+      </pattern>
+    </extension>
+    <method v="2">
+      <option name="Make" enabled="true" />
+    </method>
+  </configuration>
+</component> 
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 2d59d634e439e2fecef77356edb1d63e371fe32e..65973ee15b99d0cddbf1991674b00f284f0f3d7f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>com.example</groupId>
@@ -12,9 +12,10 @@
     <maven.compiler.source>17</maven.compiler.source>
     <maven.compiler.target>17</maven.compiler.target>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <javafx.version>21.0.2</javafx.version>
+    <javafx.version>17.0.2</javafx.version>
   </properties>
 
+
   <dependencies>
     <dependency>
       <groupId>org.openjfx</groupId>
@@ -46,8 +47,22 @@
       <artifactId>log4j-core</artifactId>
       <version>2.20.0</version>
     </dependency>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>org.jfree.chart.fx</artifactId>
+      <version>2.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+      <version>1.5.3</version>
+    </dependency>
+    <dependency>
+        <groupId>org.xerial</groupId>
+        <artifactId>sqlite-jdbc</artifactId>
+        <version>3.36.0.3</version>
+    </dependency>
   </dependencies>
-
   <build>
     <plugins>
       <plugin>
@@ -73,6 +88,10 @@
         </executions>
         <configuration>
           <mainClass>com.example.App</mainClass>
+          <options>
+            <option>--add-modules</option>
+            <option>javafx.controls,javafx.fxml,javafx.graphics,javafx.web</option>
+          </options>
         </configuration>
       </plugin>
       <plugin>
@@ -82,4 +101,4 @@
       </plugin>
     </plugins>
   </build>
-</project>
\ No newline at end of file
+</project>
diff --git a/src/main/java/com/example/App.java b/src/main/java/com/example/App.java
index 62d96f9c98ecaafdb4d3a8e8bb5eaec3f5446446..e41db8ecd0be6bf48ccad7b938da882fc16644e2 100644
--- a/src/main/java/com/example/App.java
+++ b/src/main/java/com/example/App.java
@@ -14,12 +14,20 @@ public class App extends Application {
   private static final Logger logger = LogManager.getLogger(App.class);
   private Stage stage;
 
-  private ServerLog serverLog;
+  /**
+   * Main method to enter the app.
+   * @param args
+   */
+
   public static void main(String[] args){
     logger.info("Launching app");
     launch();
   }
 
+  /**
+   * Start method called when JavaFX is launched.
+   */
+
   @Override
   public void start(Stage stage) throws Exception {
     instance = this;
@@ -27,10 +35,9 @@ public class App extends Application {
     StackPane root = new StackPane();
     Label welcomeMessage = new Label("Ad Auction");
     root.getChildren().add(welcomeMessage);
-    Label serverStats = new Label("Number of Bounces: " + this.serverLog.getNumberOfBounces() + "\nNumber of Conversions: " + this.serverLog.getNumberOfConversions());
-    root.getChildren().add(serverStats);
     Scene scene = new Scene(root, 800, 600);
     stage.setScene(scene);
+    stage.setTitle("Login");
     stage.show();
     logger.info("App started");
     Login login = new Login(stage);
@@ -38,15 +45,19 @@ public class App extends Application {
     logger.info("Login completed");
   }
 
+  /**
+   * Display input files page after login.
+   */
+
   public void showInputFilesPage(){
     InputFilesPage inputFilesPage = new InputFilesPage(stage);
     inputFilesPage.show();
     logger.info("Input files page");
   }
-  public void init() {
-    this.serverLog = new ServerLog("../../server_log.csv");
-  }
 
+  /**
+   * A getter method to globally access the app instance.
+   */
   public static App getInstance() {
     return instance;
   }
diff --git a/src/main/java/com/example/ChartCreator.java b/src/main/java/com/example/ChartCreator.java
new file mode 100644
index 0000000000000000000000000000000000000000..13680581a67757fbf1ad670712aeabd6efbbb733
--- /dev/null
+++ b/src/main/java/com/example/ChartCreator.java
@@ -0,0 +1,831 @@
+package com.example;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.CategoryAxis;
+import org.jfree.chart.axis.CategoryLabelPositions;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.renderer.category.LineAndShapeRenderer;
+import org.jfree.data.category.DefaultCategoryDataset;
+
+import java.awt.*;
+import java.awt.geom.Ellipse2D;
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
+import java.util.*;
+
+public class ChartCreator {
+
+    private ArrayList<String[]> clicks;
+    private ArrayList<String[]> impressions;
+    private ArrayList<String[]> interactions;
+    private Filter filter;
+
+    public ChartCreator(LogManager logManager) {
+        this.clicks = logManager.getClickData();
+        this.impressions = logManager.getImpressionData();
+        this.interactions = logManager.getServerData();
+        this.filter = new Filter();
+    }
+
+    public void getClicks() {
+        System.out.println(this.clicks);
+    }
+
+    /**
+     * Generates chart for total clicks
+     */
+    public JFreeChart genClickChart(String time,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        ArrayList<String[]> filteredClicks= filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age)[0];
+        if (time.equals("Daily")) {
+            clickMap = getDailyClicks(filteredClicks);
+        } else if (time.equals("Weekly")) {
+            clickMap = getWeeklyClicks(filteredClicks);
+        } else if (time.equals("Monthly")) {
+            clickMap = getMonthlyClicks(filteredClicks);
+        }
+
+        DefaultCategoryDataset dataset = createIntegerDataset(clickMap);
+        System.out.println("Row count: " + dataset.getRowCount());
+        System.out.println("Column count: " + dataset.getColumnCount());
+        return(createChart("Total Clicks","Clicks",dataset));
+    }
+
+    /**
+     * Generates chart for total impressions
+     * @return
+     */
+    public JFreeChart genImpressionChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> impressionMap = new TreeMap<>();
+        ArrayList<String[]> filteredImpressions= filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age)[1];
+
+        if (timeFlag.equals("Daily")) {
+            impressionMap = getDailyImpressions(filteredImpressions);
+        } else if (timeFlag.equals("Weekly")) {
+            impressionMap = getWeeklyImpressions(filteredImpressions);
+        } else if (timeFlag.equals("Monthly")) {
+            impressionMap = getMonthlyImpressions(filteredImpressions);
+        }
+
+        var dataset = createIntegerDataset(impressionMap);
+        return(createChart("Total impressions","Impressions",dataset));
+    }
+
+    /**
+     * Create chart for total uniques
+     * @return
+     */
+    public JFreeChart genUniquesChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        ArrayList<String[]> filteredClicks= filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age)[0];
+
+        if (timeFlag.equals("Daily")) {
+            clickMap = getDailyUniques(filteredClicks);
+        } else if (timeFlag.equals("Weekly")) {
+            clickMap = getWeeklyUniques(filteredClicks);
+        } else if (timeFlag.equals("Monthly")) {
+            clickMap = getMonthlyUniques(filteredClicks);
+        }
+
+        var dataset = createIntegerDataset(clickMap);
+        return(createChart("Total Uniques","Uniques",dataset));
+    }
+
+    /**
+     * Create chart for total bounces
+     * @return
+     */
+    public JFreeChart genBounceChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> interactionMap = new TreeMap<>();
+        ArrayList<String[]> filteredInteractions= filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age)[2];
+
+        if (timeFlag.equals("Daily")) {
+            interactionMap = getDailyBounces(filteredInteractions);
+        } else if (timeFlag.equals("Weekly")) {
+            interactionMap = getWeeklyBounces(filteredInteractions);
+        } else if (timeFlag.equals("Monthly")) {
+            interactionMap = getMonthlyBounces(filteredInteractions);
+        }
+
+        var dataset = createIntegerDataset(interactionMap);
+        return(createChart("Total Bounces","Bounces",dataset));
+    }
+    /**
+     * Create chart for total conversions
+     * @return
+     */
+    public JFreeChart genConversionChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> conversionMap = new TreeMap<>();
+        ArrayList<String[]> filteredInteractions= filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age)[2];
+
+        if (timeFlag.equals("Daily")) {
+            conversionMap = getDailyConversions(filteredInteractions);
+        } else if (timeFlag.equals("Weekly")) {
+            conversionMap = getWeeklyConversions(filteredInteractions);
+        }else if (timeFlag.equals("Monthly")) {
+            conversionMap = getMonthlyConversions(filteredInteractions);
+        }
+
+        var dataset = createIntegerDataset(conversionMap);
+        return(createChart("Total conversions","Conversions",dataset));
+    }
+
+
+    /**
+     * Create chart for total cost
+     * @return
+     */
+    public JFreeChart genCostChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Float> costMap = new TreeMap<>();
+        ArrayList<String[]> [] filteredLogs = filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age);
+        ArrayList<String[]> filteredClicks = filteredLogs[0];
+        ArrayList<String[]> filteredImpressions = filteredLogs[1];
+
+        if (timeFlag.equals("Daily")) {
+            costMap = getDailyCost(filteredClicks,filteredImpressions);
+        } else if (timeFlag.equals("Weekly")) {
+            costMap = getWeeklyCost(filteredClicks,filteredImpressions);
+        } else if (timeFlag.equals("Monthly")) {
+            costMap = getMonthlyCost(filteredClicks,filteredImpressions);
+        }
+
+        var dataset = createFloatDataset(costMap);
+        return(createChart("Total cost","Cost",dataset));
+
+    }
+
+    /**
+     * Create chart for CTR
+     * @return
+     */
+    public JFreeChart genCTRChart(String timeFlag,String gender, String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        Map<String,Integer> impressionMap = new TreeMap<>();
+        Map<String,Float> ctrMap = new TreeMap<>();
+        ArrayList<String[]> [] filteredLogs = filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age);
+        ArrayList<String[]> filteredClicks = filteredLogs[0];
+        ArrayList<String[]> filteredImpressions = filteredLogs[1];
+
+        if(timeFlag.equals("Daily")) {
+            clickMap = getDailyClicks(filteredClicks);
+            impressionMap = getDailyImpressions(filteredImpressions);
+        } else if (timeFlag.equals("Weekly")){
+            clickMap = getWeeklyClicks(filteredClicks);
+            impressionMap = getWeeklyImpressions(filteredImpressions);
+        } else if (timeFlag.equals("Monthly")){
+            clickMap = getMonthlyClicks(filteredClicks);
+            impressionMap = getMonthlyImpressions(filteredImpressions);
+        }
+
+        for(String date : impressionMap.keySet()) {
+            int clicks = clickMap.getOrDefault(date,0);
+            int impressions = impressionMap.get(date);
+            float ctr = (float) clicks/impressions;
+            ctrMap.put(date,ctr);
+        }
+
+        var dataset = createFloatDataset(ctrMap);
+        return(createChart("CTR", "Clicks per impression", dataset));
+    }
+
+    /**
+     * Create chart for CPA
+     * @return
+     */
+    public JFreeChart genCPAChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> conversionMap = new TreeMap<>();
+        Map<String,Float> costMap = new TreeMap<>();
+        Map<String,Float> cpaMap = new TreeMap<>();
+        ArrayList<String[]> [] filteredLogs = filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age);
+        ArrayList<String[]> filteredClicks = filteredLogs[0];
+        ArrayList<String[]> filteredImpressions = filteredLogs[1];
+        ArrayList<String[]> filteredInteractions = filteredLogs[2];
+
+
+        if (timeFlag.equals("Daily")) {
+            conversionMap = getDailyConversions(filteredInteractions);
+            costMap = getDailyCost(filteredClicks, filteredImpressions);
+        } else if (timeFlag.equals("Weekly")) {
+            conversionMap = getWeeklyConversions(filteredInteractions);
+            costMap = getWeeklyCost(filteredClicks,filteredImpressions);
+        } else if (timeFlag.equals("Monthly")) {
+            conversionMap = getMonthlyConversions(filteredInteractions);
+            costMap = getMonthlyCost(filteredClicks,filteredImpressions);
+        }
+
+        for(String date : conversionMap.keySet()) {
+            float cost = costMap.getOrDefault(date,(float) 0);
+            int conversions = conversionMap.get(date);
+            float cpa = cost/conversions;
+            cpaMap.put(date,cpa);
+        }
+
+        var dataset = createFloatDataset(cpaMap);
+        return(createChart("CPA","Cost per conversion",dataset));
+    }
+
+    /**
+     * Create chart for CPC
+     * @return
+     */
+    public JFreeChart genCPCChart(String timeFlag, String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        Map<String,Float> costMap = new TreeMap<>();
+        Map<String,Float> cpcMap = new TreeMap<>();
+        ArrayList<String[]> [] filteredLogs = filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age);
+        ArrayList<String[]> filteredClicks = filteredLogs[0];
+        ArrayList<String[]> filteredImpressions = filteredLogs[1];
+
+
+        if (timeFlag.equals("Daily")) {
+            clickMap = getDailyClicks(filteredClicks);
+            costMap = getDailyCost(filteredClicks, filteredImpressions);
+        } else if (timeFlag.equals("Weekly")) {
+            clickMap = getWeeklyClicks(filteredClicks);
+            costMap = getWeeklyCost(filteredClicks,filteredImpressions);
+        } else if (timeFlag.equals("Monthly")) {
+            clickMap = getMonthlyClicks(filteredClicks);
+            costMap = getMonthlyCost(filteredClicks,filteredImpressions);
+        }
+
+        for(String date : clickMap.keySet()) {
+            float cost = costMap.getOrDefault(date,(float) 0);
+            int clicks = clickMap.get(date);
+            float cpc = cost/clicks;
+            cpcMap.put(date,cpc);
+        }
+
+        var dataset = createFloatDataset(cpcMap);
+        return(createChart("CPC","Cost per click",dataset));
+    }
+
+    /**
+     * Generate chart for CPM
+     * @return
+     */
+    public JFreeChart genCPMChart(String timeFlag,String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> impressionMap = new TreeMap<>();
+        Map<String,Float> costMap = new TreeMap<>();
+        Map<String,Float> cpmMap = new TreeMap<>();
+        ArrayList<String[]> [] filteredLogs = filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age);
+        ArrayList<String[]> filteredClicks = filteredLogs[0];
+        ArrayList<String[]> filteredImpressions = filteredLogs[1];
+
+
+        if (timeFlag.equals("Daily")) {
+            impressionMap = getDailyImpressions(filteredImpressions);
+            costMap = getDailyCost(filteredClicks, filteredImpressions);
+        } else if (timeFlag.equals("Weekly")) {
+            impressionMap = getWeeklyImpressions(filteredImpressions);
+            costMap = getWeeklyCost(filteredClicks,filteredImpressions);
+        } else if (timeFlag.equals("Monthly")) {
+            impressionMap = getMonthlyImpressions(filteredImpressions);
+            costMap = getMonthlyCost(filteredClicks,filteredImpressions);
+        }
+
+        //Convert impressions into thousands
+        Map<String,Float> impressionThousandMap = new TreeMap<>();
+        for (Map.Entry<String,Integer> entry : impressionMap.entrySet()) {
+            impressionThousandMap.put(entry.getKey(),(float) entry.getValue()/1000);
+        }
+
+        for(String date : impressionThousandMap.keySet()) {
+            float cost = costMap.get(date);
+            float thousandImpressions = impressionThousandMap.get(date);
+            float cpm = cost/thousandImpressions;
+            cpmMap.put(date,cpm);
+        }
+
+        var dataset = createFloatDataset(cpmMap);
+        return(createChart("CPM","Cost per thousand impressions",dataset));
+    }
+
+    /**
+     * Create chart for bounce rate
+     * @return
+     */
+    public JFreeChart genBounceRateChart(String timeFlag, String gender,String income,ArrayList<String> context,ArrayList<String> age) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        Map<String,Integer> bounceMap = new TreeMap<>();
+        Map<String,Float> bounceRateMap = new TreeMap<>();
+        ArrayList<String[]> [] filteredLogs = filter.filterPipeline(clicks,impressions,interactions,gender,income,context,age);
+        ArrayList<String[]> filteredClicks = filteredLogs[0];
+        ArrayList<String[]> filteredInteractions = filteredLogs[2];
+
+        if (timeFlag.equals("Daily")) {
+            clickMap = getDailyClicks(filteredClicks);
+            bounceMap = getDailyBounces(filteredInteractions);
+        } else if (timeFlag.equals("Weekly")) {
+            clickMap = getWeeklyClicks(filteredClicks);
+            bounceMap = getWeeklyBounces(filteredInteractions);
+        } else if (timeFlag.equals("Monthly")) {
+            clickMap = getMonthlyClicks(filteredClicks);
+            bounceMap = getMonthlyBounces(filteredInteractions);
+        }
+
+        for (String date : clickMap.keySet()) {
+            int clicks = clickMap.get(date);
+            int bounces = bounceMap.get(date);
+            float bounceRate = (float) bounces/clicks;
+            bounceRateMap.put(date,bounceRate);
+        }
+
+        var dataset = createFloatDataset(bounceRateMap);
+        return(createChart("Bounce Rate","Bounces per click",dataset));
+
+    }
+
+
+    /**
+     * Reusable method for creating chart
+     * @param name
+     * @param metric
+     * @param dataset
+     * @return
+     */
+    public JFreeChart createChart(String name, String metric, DefaultCategoryDataset dataset) {
+        JFreeChart chart = ChartFactory.createLineChart(
+                name,
+                "Date",
+                metric,
+                dataset,
+                PlotOrientation.VERTICAL,
+                false,
+                true,
+                false
+        );
+        // Adjusting font
+        CategoryPlot plot = chart.getCategoryPlot();
+        CategoryAxis xAxis = plot.getDomainAxis();
+        xAxis.setTickLabelFont(new Font("Arial", Font.PLAIN, 9));  // Change font size here
+        xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
+
+        //Creating marker dot at plot points
+        LineAndShapeRenderer renderer = new LineAndShapeRenderer();
+        renderer.setSeriesShapesVisible(0, true);
+        renderer.setSeriesLinesVisible(0, true);
+        Shape dot = new Ellipse2D.Double(-5, -5, 10, 10);
+        renderer.setSeriesShape(0, dot);
+        plot.setRenderer(renderer);
+
+        return chart;
+    }
+
+    /**
+     * Creates dataset with float values
+     * @param map
+     * @return
+     */
+    public DefaultCategoryDataset createFloatDataset(Map<String,Float> map) {
+        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+        for (Map.Entry<String, Float> entry: map.entrySet()) {
+            dataset.addValue(entry.getValue(), "Entry", entry.getKey());
+        }
+        return  dataset;
+    }
+
+    /**
+     * Creates dataset with integer values
+     * @param map
+     * @return
+     */
+    public DefaultCategoryDataset createIntegerDataset(Map<String,Integer> map) {
+        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+        for (Map.Entry<String, Integer> entry: map.entrySet()) {
+            dataset.addValue(entry.getValue(), "Entry", entry.getKey());
+        }
+        return  dataset;
+    }
+
+    /**
+     * Accumulate daily clicks
+     * @param clicks
+     * @return
+     */
+    public Map<String,Integer> getDailyClicks (ArrayList<String[]> clicks) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        for (String[] click : clicks){
+            String date = click[0].split(" ")[0];
+            clickMap.put(date, clickMap.getOrDefault(date, 1) + 1);
+        }
+        return clickMap;
+    }
+
+    /**
+     * Accumulate weekly clicks
+     * @param clicks
+     * @return
+     */
+    public Map<String,Integer> getWeeklyClicks (ArrayList<String[]> clicks) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(clicks);
+        for (String[] click : clicks) {
+            LocalDate date = LocalDate.parse(click[0].split(" ")[0]);
+            int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+            String week = "Week " + Integer.toString(weekNumber);
+            clickMap.put(week,clickMap.getOrDefault(week,1) + 1);
+        }
+
+        return clickMap;
+    }
+
+    /**
+     * Accumulate monthly clicks
+     * @param clicks
+     * @return
+     */
+    public Map<String,Integer> getMonthlyClicks (ArrayList<String[]> clicks) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(clicks);
+        for (String[] click : clicks) {
+            LocalDate date = LocalDate.parse(click[0].split(" ")[0]);
+            int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+            String month = "Month " + Integer.toString(monthNumber);
+            clickMap.put(month,clickMap.getOrDefault(month,1) + 1);
+        }
+
+        return clickMap;
+    }
+
+
+    /**
+     * Accumulate daily impressions
+     * @param impressions
+     * @return
+     */
+    public Map<String,Integer> getDailyImpressions (ArrayList<String[]> impressions) {
+        Map<String,Integer> impressionMap = new TreeMap<>();
+        for (String[] impression : impressions){
+            String date = impression[0].split(" ")[0];
+            impressionMap.put(date, impressionMap.getOrDefault(date, 1) + 1);
+        }
+        return impressionMap;
+    }
+
+    /**
+     * Accumulate weekly impressions
+     * @param impressions
+     * @return
+     */
+    public Map<String,Integer> getWeeklyImpressions (ArrayList<String[]> impressions) {
+        Map<String,Integer> impressionMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(impressions);
+        for (String[] impression : impressions) {
+            LocalDate date = LocalDate.parse(impression[0].split(" ")[0]);
+            int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+            String week = "Week " + Integer.toString(weekNumber);
+            impressionMap.put(week,impressionMap.getOrDefault(week,1) + 1);
+        }
+        return impressionMap;
+    }
+
+    /**
+     * Accumulate monthly impressions
+     * @param impressions
+     * @return
+     */
+    public Map<String,Integer> getMonthlyImpressions (ArrayList<String[]> impressions) {
+        Map<String,Integer> impressionMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(impressions);
+        for (String[] impression : impressions) {
+            LocalDate date = LocalDate.parse(impression[0].split(" ")[0]);
+            int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+            String month = "Month " + Integer.toString(monthNumber);
+            impressionMap.put(month,impressionMap.getOrDefault(month,1) + 1);
+        }
+        return impressionMap;
+    }
+
+
+    /**
+     * Accumulate daily uniques
+     * @param clicks
+     * @return
+     */
+    public Map<String,Integer> getDailyUniques (ArrayList<String[]> clicks) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        Set<String> uniqueIDs = new HashSet<>();
+
+        for(String[] click : clicks) {
+            String dateTime = click[0];
+            String id = click[1];
+
+            if (!uniqueIDs.contains(id)) {
+                uniqueIDs.add(id);
+                String date = dateTime.split(" ")[0];
+
+                clickMap.put(date,clickMap.getOrDefault(date,1)+1);
+            }
+        }
+        return clickMap;
+    }
+
+    /**
+     * Accumulate weekly uniques
+     * @param clicks
+     * @return
+     */
+    public Map<String,Integer> getWeeklyUniques (ArrayList<String[]> clicks) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        Set<String> uniqueIDs = new HashSet<>();
+
+        LocalDate earliestDate = getEarliestDate(clicks);
+
+        for(String[] click : clicks) {
+            LocalDate date = LocalDate.parse(click[0].split(" ")[0]);
+            int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+            String week = "Week " + Integer.toString(weekNumber);
+            String id = click[1];
+
+            if (!uniqueIDs.contains(id)) {
+                uniqueIDs.add(id);
+                clickMap.put(week,clickMap.getOrDefault(week,1)+1);
+            }
+        }
+        return clickMap;
+
+    }
+
+    /**
+     * Accumulate monthly uniques
+     * @param clicks
+     * @return
+     */
+    public Map<String,Integer> getMonthlyUniques (ArrayList<String[]> clicks) {
+        Map<String,Integer> clickMap = new TreeMap<>();
+        Set<String> uniqueIDs = new HashSet<>();
+
+        LocalDate earliestDate = getEarliestDate(clicks);
+
+        for(String[] click : clicks) {
+            LocalDate date = LocalDate.parse(click[0].split(" ")[0]);
+            int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+            String month = "Month " + Integer.toString(monthNumber);
+            String id = click[1];
+
+            if (!uniqueIDs.contains(id)) {
+                uniqueIDs.add(id);
+                clickMap.put(month,clickMap.getOrDefault(month,1)+1);
+            }
+        }
+        return clickMap;
+
+    }
+
+    /**
+     * Accumulate daily conversions
+     * @param interactions
+     * @return
+     */
+    public Map<String,Integer> getDailyConversions (ArrayList<String[]> interactions) {
+        Map<String,Integer> conversionMap = new TreeMap<>();
+        for (String[] interaction : interactions){
+            if (interaction[4].equals("Yes")) {
+                String date = interaction[0].split(" ")[0];
+                conversionMap.put(date, conversionMap.getOrDefault(date, 1) + 1);
+            }
+        }
+        return conversionMap;
+    }
+
+    /**
+     * Accumulate weekly conversions
+     * @param interactions
+     * @return
+     */
+    public Map<String,Integer> getWeeklyConversions(ArrayList<String[]> interactions) {
+        Map<String,Integer> conversionMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(interactions);
+        for (String[] interaction : interactions) {
+            if (interaction[4].equals("Yes")) {
+                LocalDate date = LocalDate.parse(interaction[0].split(" ")[0]);
+                int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+                String week = "Week " + Integer.toString(weekNumber);
+                conversionMap.put(week,conversionMap.getOrDefault(week,1) + 1);
+            }
+        }
+        return conversionMap;
+    }
+
+    /**
+     * Accumulate monthly conversions
+     * @param interactions
+     * @return
+     */
+    public Map<String,Integer> getMonthlyConversions(ArrayList<String[]> interactions) {
+        Map<String,Integer> conversionMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(interactions);
+        for (String[] interaction : interactions) {
+            if (interaction[4].equals("Yes")) {
+                LocalDate date = LocalDate.parse(interaction[0].split(" ")[0]);
+                int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+                String month = "Month " + Integer.toString(monthNumber);
+                conversionMap.put(month,conversionMap.getOrDefault(month,1) + 1);
+            }
+        }
+        return conversionMap;
+    }
+
+
+    /**
+     * Accumulate daily cost
+     * @param clicks
+     * @param impressions
+     * @return
+     */
+    public Map<String,Float> getDailyCost (ArrayList<String[]> clicks, ArrayList<String[]> impressions) {
+        Map<String,Float> costMap = new TreeMap<>();
+
+        for (String[] click : clicks) {
+            String dateTime = click[0];
+            String date = dateTime.split(" ")[0];
+            float cost = Float.parseFloat(click[2]);
+            costMap.put(date,costMap.getOrDefault(date,cost) + cost);
+        }
+
+        for (String[] impression: impressions) {
+            String dateTime = impression[0];
+            String date = dateTime.split(" ")[0];
+            float cost = Float.parseFloat(impression[6]);
+            costMap.put(date,costMap.getOrDefault(date,cost) + cost);
+        }
+
+        return costMap;
+    }
+
+    /**
+     * Accumulate weekly cost
+     * @param clicks
+     * @param impressions
+     * @return
+     */
+    public Map<String,Float> getWeeklyCost (ArrayList<String[]> clicks, ArrayList<String[]> impressions) {
+        Map<String,Float> costMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(impressions);
+        for (String[] click : clicks) {
+            LocalDate date = LocalDate.parse(click[0].split(" ")[0]);
+            int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+            String week = "Week " + Integer.toString(weekNumber);
+            float cost = Float.parseFloat(click[2]);
+            costMap.put(week,costMap.getOrDefault(week,cost) + cost);
+        }
+
+        for (String[] impression : impressions) {
+            LocalDate date = LocalDate.parse(impression[0].split(" ")[0]);
+            int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+            String week = "Week " + Integer.toString(weekNumber);
+            float cost = Float.parseFloat(impression[6]);
+            costMap.put(week,costMap.getOrDefault(week,cost) + cost);
+        }
+        return costMap;
+    }
+
+    /**
+     * Accumulate monthly cost
+     * @param clicks
+     * @param impressions
+     * @return
+     */
+    public Map<String,Float> getMonthlyCost (ArrayList<String[]> clicks, ArrayList<String[]> impressions) {
+        Map<String,Float> costMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(impressions);
+        for (String[] click : clicks) {
+            LocalDate date = LocalDate.parse(click[0].split(" ")[0]);
+            int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+            String month = "Month " + Integer.toString(monthNumber);
+            float cost = Float.parseFloat(click[2]);
+            costMap.put(month,costMap.getOrDefault(month,cost) + cost);
+        }
+
+        for (String[] impression : impressions) {
+            LocalDate date = LocalDate.parse(impression[0].split(" ")[0]);
+            int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+            String month = "Month " + Integer.toString(monthNumber);
+            float cost = Float.parseFloat(impression[6]);
+            costMap.put(month,costMap.getOrDefault(month,cost) + cost);
+        }
+        return costMap;
+    }
+
+    /**
+     * Accumulate daily bounces
+     * @param interactions
+     * @return
+     */
+    public Map<String,Integer> getDailyBounces(ArrayList<String[]> interactions) {
+        Map<String,Integer> interactionMap = new TreeMap<>();
+
+        for (String[] interaction : interactions){
+            if (interaction[3].equals("1")) {
+                String dateTime = interaction[0];
+                String date = dateTime.split(" ")[0];
+
+                interactionMap.put(date, interactionMap.getOrDefault(date, 1) + 1);
+            }
+        }
+        return interactionMap;
+    }
+
+    /**
+     * Accumulate weekly bounces
+     * @param interactions
+     * @return
+     */
+    public Map<String, Integer> getWeeklyBounces(ArrayList<String[]> interactions) {
+        Map<String,Integer> bounceMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(interactions);
+        for (String[] interaction : interactions) {
+            if (interaction[3].equals("1")) {
+                LocalDate date = LocalDate.parse(interaction[0].split(" ")[0]);
+                int weekNumber = (int) ChronoUnit.WEEKS.between(earliestDate,date) + 1;
+                String week = "Week " + Integer.toString(weekNumber);
+                bounceMap.put(week,bounceMap.getOrDefault(week,1) + 1);
+            }
+        }
+        return bounceMap;
+    }
+
+    /**
+     * Accumulate monthly bounces
+     * @param interactions
+     * @return
+     */
+    public Map<String, Integer> getMonthlyBounces(ArrayList<String[]> interactions) {
+        Map<String,Integer> bounceMap = new TreeMap<>();
+
+        LocalDate earliestDate = getEarliestDate(interactions);
+        for (String[] interaction : interactions) {
+            if (interaction[3].equals("1")) {
+                LocalDate date = LocalDate.parse(interaction[0].split(" ")[0]);
+                int monthNumber = (int) ChronoUnit.MONTHS.between(earliestDate,date) + 1;
+                String month = "Month " + Integer.toString(monthNumber);
+                bounceMap.put(month,bounceMap.getOrDefault(month,1) + 1);
+            }
+        }
+        return bounceMap;
+    }
+
+
+
+    /**
+     * Get earliest date from set of data entries
+     * @param data
+     * @return
+     */
+    public LocalDate getEarliestDate(ArrayList<String[]> data) {
+        LocalDate firstDate = null;
+        for(String[] entry : data) {
+            LocalDate date = LocalDate.parse(entry[0].split(" ")[0]);
+            if(firstDate == null || date.isBefore(firstDate)) {
+                firstDate = date;
+            }
+        }
+        return firstDate;
+    }
+
+
+    /**
+     * Updates chart with time filter applied
+     * @param currentChart
+     * @param timeFlag
+     * @return
+     */
+    public JFreeChart updateChart(String currentChart, String timeFlag, String gender,String income, ArrayList<String> context, ArrayList<String> age) {
+        if (currentChart.equals("Clicks")) {
+            return (genClickChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("Impressions")) {
+            return (genImpressionChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("Conversions")) {
+            return (genConversionChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("Bounces")) {
+            return (genBounceChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("Cost")) {
+            return (genCostChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("Uniques")) {
+            return (genUniquesChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("BounceRate")){
+            return (genBounceRateChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("CTR")) {
+            return (genCTRChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("CPA")) {
+            return (genCPAChart(timeFlag,gender,income,context,age));
+        } else if (currentChart.equals("CPC")) {
+            return (genCPCChart(timeFlag,gender,income,context,age));
+        } else {
+            return (genCPMChart(timeFlag,gender,income,context,age));
+        }
+
+    }
+
+}
diff --git a/src/main/java/com/example/ChartPage.java b/src/main/java/com/example/ChartPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ae07bb5cc15e4a8f425c2312da7c351d65c4b11
--- /dev/null
+++ b/src/main/java/com/example/ChartPage.java
@@ -0,0 +1,715 @@
+package com.example;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.layout.Region;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.stage.Stage;
+import org.jfree.chart.fx.ChartViewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChartPage {
+    private Stage stage;
+    private LogManager logManager;
+    private ChartCreator chartCreator;
+    private String timeFlag;
+    private String currentChart;
+
+    private String gender;
+    private ArrayList<String> age;
+    private String income;
+    private ArrayList<String> context;
+
+    // Define style constants
+    private final String BACKGROUND_COLOR = "#f5f5f7";
+    private final String PRIMARY_COLOR = "#4285F4";
+    private final String PRIMARY_DARK_COLOR = "#3367d6";
+    private final String SECTION_BACKGROUND = "white";
+    private final String HEADER_COLOR = "#333333";
+    private final String TEXT_COLOR = "#555555";
+
+    public ChartPage(Stage stage, LogManager logManager) {
+        this.stage = stage;
+        this.logManager = logManager;
+        this.chartCreator = new ChartCreator(logManager);
+        this.timeFlag = "Daily";
+        this.currentChart = "Clicks";
+
+        this.gender = "";
+        this.age = new ArrayList<>();
+        this.income = "";
+        this.context = new ArrayList<>();
+    }
+
+    public void show() {
+        // Create main layout
+        BorderPane root = new BorderPane();
+        root.setStyle("-fx-background-color: " + BACKGROUND_COLOR + ";");
+        
+        // Chart display area
+        ChartViewer chartViewer = new ChartViewer(chartCreator.updateChart(currentChart, timeFlag, gender, income, context, age));
+        chartViewer.setMaxSize(800, 600);
+        
+        // Create a container for the chart, add styling
+        BorderPane chartContainer = new BorderPane();
+        chartContainer.setCenter(chartViewer);
+        chartContainer.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-background-radius: 10; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);");
+        chartContainer.setPadding(new Insets(15));
+        
+        // ===== Top navigation bar =====
+        HBox navBar = createNavigationBar();
+        
+        // ===== Right side metrics and filter panel =====
+        ScrollPane filterPanel = createFilterPanel(chartViewer);
+        
+        // ===== Bottom time granularity selector =====
+        HBox timeGranularityBar = createTimeGranularityBar(chartViewer);
+        
+        // Set layout positions
+        root.setTop(navBar);
+        root.setCenter(chartContainer);
+        root.setRight(filterPanel);
+        root.setBottom(timeGranularityBar);
+        
+        // Set margins
+        BorderPane.setMargin(chartContainer, new Insets(10, 10, 10, 10));
+        BorderPane.setMargin(filterPanel, new Insets(10, 10, 10, 5));
+        BorderPane.setMargin(timeGranularityBar, new Insets(5, 10, 15, 10));
+        
+        // Create scene
+        Scene scene = new Scene(root, 1300, 800);
+        stage.setScene(scene);
+        stage.setTitle("Ad Auction Dashboard - Data Charts");
+        stage.show();
+    }
+    
+    // Create top navigation bar
+    private HBox createNavigationBar() {
+        HBox navBar = new HBox(15);
+        navBar.setAlignment(Pos.CENTER_LEFT);
+        navBar.setPadding(new Insets(15, 20, 15, 20));
+        navBar.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);");
+        
+        Label title = new Label("Data Visualization");
+        title.setFont(Font.font("Arial", FontWeight.BOLD, 20));
+        title.setTextFill(Color.web(HEADER_COLOR));
+        
+        Region spacer = new Region();
+        HBox.setHgrow(spacer, javafx.scene.layout.Priority.ALWAYS);
+        
+        // Button to access overall metrics
+        Button overallMetricsButton = createStyledButton("Overall Metrics", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        
+        // Button to compare multiple charts
+        Button compareChartsButton = createStyledButton("Compare Charts", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        
+        // Logout button
+        Button logOutButton = createStyledButton("Logout", "#757575", "#616161");
+        
+        // File selection button
+        Button fileSelectionButton = createStyledButton("Select Files", "#757575", "#616161");
+        
+        // Set button actions
+        overallMetricsButton.setOnAction(e -> {
+            OverallMetricsPage metricsPage = new OverallMetricsPage(stage, logManager);
+            metricsPage.show();
+        });
+        
+        compareChartsButton.setOnAction(e -> {
+            ArrayList<String> currentCharts = new ArrayList<>();
+            currentCharts.add(this.currentChart);
+            currentCharts.add("Impressions"); // Default second chart
+            
+            ArrayList<String> timeFlags = new ArrayList<>();
+            timeFlags.add(this.timeFlag);
+            timeFlags.add("Daily"); // Default time flag for second chart
+            
+            ArrayList<String> genders = new ArrayList<>();
+            genders.add(this.gender);
+            genders.add(""); // Default gender for second chart
+            
+            ArrayList<String> incomes = new ArrayList<>();
+            incomes.add(this.income);
+            incomes.add(""); // Default income for second chart
+            
+            ArrayList<ArrayList<String>> contexts = new ArrayList<>();
+            contexts.add(this.context);
+            contexts.add(new ArrayList<>()); // Default context for second chart
+            
+            ArrayList<ArrayList<String>> ages = new ArrayList<>();
+            ages.add(this.age);
+            ages.add(new ArrayList<>()); // Default age for second chart
+            
+            MultiChartPage multiChartPage = new MultiChartPage(stage, logManager, currentCharts, timeFlags, genders, incomes, contexts, ages);
+            multiChartPage.show();
+        });
+        
+        logOutButton.setOnAction(e -> {
+            Login login = new Login(stage);
+            login.show();
+        });
+        
+        fileSelectionButton.setOnAction(e -> {
+            InputFilesPage inputFilesPage = new InputFilesPage(stage);
+            inputFilesPage.show();
+        });
+        
+        navBar.getChildren().addAll(title, spacer, fileSelectionButton, overallMetricsButton, compareChartsButton, logOutButton);
+        return navBar;
+    }
+    
+    // Create filter panel
+    private ScrollPane createFilterPanel(ChartViewer chartViewer) {
+        VBox filterPanel = new VBox(20);
+        filterPanel.setPadding(new Insets(20));
+        filterPanel.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-background-radius: 10; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);");
+        
+        // Title for filter panel
+        Label filterTitle = new Label("Chart Settings");
+        filterTitle.setFont(Font.font("Arial", FontWeight.BOLD, 18));
+        filterTitle.setTextFill(Color.web(HEADER_COLOR));
+        
+        // Add different filter sections
+        VBox metricsSection = createMetricsOptions(chartViewer);
+        VBox genderSection = createGenderOptions(chartViewer);
+        VBox incomeSection = createIncomeOptions(chartViewer);
+        VBox contextSection = createContextOptions(chartViewer);
+        VBox ageSection = createAgeOptions(chartViewer);
+        
+        // Add sections to filter panel
+        filterPanel.getChildren().addAll(
+            filterTitle,
+            new Separator(),
+            metricsSection,
+            new Separator(),
+            genderSection,
+            new Separator(),
+            incomeSection,
+            new Separator(),
+            contextSection,
+            new Separator(),
+            ageSection
+        );
+        
+        // Create a scroll pane to hold the filter panel
+        ScrollPane scrollPane = new ScrollPane(filterPanel);
+        scrollPane.setFitToWidth(true);
+        scrollPane.setPrefWidth(300);
+        scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
+        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
+        scrollPane.getStyleClass().add("edge-to-edge");
+        
+        return scrollPane;
+    }
+    
+    // Create time granularity bar
+    private HBox createTimeGranularityBar(ChartViewer chartViewer) {
+        HBox timeBar = new HBox(20);
+        timeBar.setAlignment(Pos.CENTER);
+        timeBar.setPadding(new Insets(15, 20, 15, 20));
+        timeBar.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-background-radius: 10; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);");
+        
+        Label timeLabel = new Label("Time Granularity:");
+        timeLabel.setFont(Font.font("Arial", FontWeight.BOLD, 14));
+        timeLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        ToggleGroup timeToggleGroup = new ToggleGroup();
+        
+        RadioButton dailyButton = createStyledRadioButton("Daily", timeToggleGroup);
+        dailyButton.setSelected(true);
+        
+        RadioButton weeklyButton = createStyledRadioButton("Weekly", timeToggleGroup);
+        RadioButton monthlyButton = createStyledRadioButton("Monthly", timeToggleGroup);
+        
+        // Set action handlers for time granularity buttons
+        dailyButton.setOnAction(e -> {
+            timeFlag = "Daily";
+            updateChart(chartViewer);
+        });
+        
+        weeklyButton.setOnAction(e -> {
+            timeFlag = "Weekly";
+            updateChart(chartViewer);
+        });
+        
+        monthlyButton.setOnAction(e -> {
+            timeFlag = "Monthly";
+            updateChart(chartViewer);
+        });
+        
+        timeBar.getChildren().addAll(timeLabel, dailyButton, weeklyButton, monthlyButton);
+        
+        return timeBar;
+    }
+    
+    // Create metrics options
+    private VBox createMetricsOptions(ChartViewer chartViewer) {
+        VBox metricsBox = new VBox(10);
+        
+        Label metricsLabel = new Label("Metrics");
+        metricsLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        metricsLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        ToggleGroup metricsToggleGroup = new ToggleGroup();
+        
+        RadioButton clicksButton = createStyledRadioButton("Total Clicks", metricsToggleGroup);
+        clicksButton.setSelected(true);
+        
+        RadioButton impressionsButton = createStyledRadioButton("Total Impressions", metricsToggleGroup);
+        RadioButton uniquesButton = createStyledRadioButton("Unique Visitors", metricsToggleGroup);
+        RadioButton bouncesButton = createStyledRadioButton("Bounces", metricsToggleGroup);
+        RadioButton conversionsButton = createStyledRadioButton("Conversions", metricsToggleGroup);
+        RadioButton costButton = createStyledRadioButton("Total Cost", metricsToggleGroup);
+        
+        // Create a separator for ratio metrics
+        Separator separator = new Separator();
+        separator.setPadding(new Insets(5, 0, 5, 0));
+        
+        Label ratioLabel = new Label("Ratio Metrics");
+        ratioLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        ratioLabel.setTextFill(Color.web(HEADER_COLOR));
+        ratioLabel.setPadding(new Insets(5, 0, 5, 0));
+        
+        RadioButton ctrButton = createStyledRadioButton("Click-Through Rate (CTR)", metricsToggleGroup);
+        RadioButton cpaButton = createStyledRadioButton("Cost Per Acquisition (CPA)", metricsToggleGroup);
+        RadioButton cpcButton = createStyledRadioButton("Cost Per Click (CPC)", metricsToggleGroup);
+        RadioButton cpmButton = createStyledRadioButton("Cost Per Mille (CPM)", metricsToggleGroup);
+        RadioButton bounceRateButton = createStyledRadioButton("Bounce Rate", metricsToggleGroup);
+        
+        // Set action handlers for metrics buttons
+        clicksButton.setOnAction(e -> {
+            currentChart = "Clicks";
+            updateChart(chartViewer);
+        });
+        
+        impressionsButton.setOnAction(e -> {
+            currentChart = "Impressions";
+            updateChart(chartViewer);
+        });
+        
+        uniquesButton.setOnAction(e -> {
+            currentChart = "Uniques";
+            updateChart(chartViewer);
+        });
+        
+        bouncesButton.setOnAction(e -> {
+            currentChart = "Bounces";
+            updateChart(chartViewer);
+        });
+        
+        conversionsButton.setOnAction(e -> {
+            currentChart = "Conversions";
+            updateChart(chartViewer);
+        });
+        
+        costButton.setOnAction(e -> {
+            currentChart = "Cost";
+            updateChart(chartViewer);
+        });
+        
+        ctrButton.setOnAction(e -> {
+            currentChart = "CTR";
+            updateChart(chartViewer);
+        });
+        
+        cpaButton.setOnAction(e -> {
+            currentChart = "CPA";
+            updateChart(chartViewer);
+        });
+        
+        cpcButton.setOnAction(e -> {
+            currentChart = "CPC";
+            updateChart(chartViewer);
+        });
+        
+        cpmButton.setOnAction(e -> {
+            currentChart = "CPM";
+            updateChart(chartViewer);
+        });
+        
+        bounceRateButton.setOnAction(e -> {
+            currentChart = "BounceRate";
+            updateChart(chartViewer);
+        });
+        
+        metricsBox.getChildren().addAll(
+            metricsLabel,
+            clicksButton,
+            impressionsButton,
+            uniquesButton,
+            bouncesButton,
+            conversionsButton,
+            costButton,
+            separator,
+            ratioLabel,
+            ctrButton,
+            cpaButton,
+            cpcButton,
+            cpmButton,
+            bounceRateButton
+        );
+        
+        return metricsBox;
+    }
+    
+    // Create gender options
+    private VBox createGenderOptions(ChartViewer chartViewer) {
+        VBox genderBox = new VBox(10);
+        
+        Label genderLabel = new Label("Gender");
+        genderLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        genderLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        ToggleGroup genderToggleGroup = new ToggleGroup();
+        
+        RadioButton allGenderButton = createStyledRadioButton("All", genderToggleGroup);
+        allGenderButton.setSelected(true);
+        
+        RadioButton maleButton = createStyledRadioButton("Male", genderToggleGroup);
+        RadioButton femaleButton = createStyledRadioButton("Female", genderToggleGroup);
+        
+        // Set action handlers for gender buttons
+        allGenderButton.setOnAction(e -> {
+            gender = "";
+            updateChart(chartViewer);
+        });
+        
+        maleButton.setOnAction(e -> {
+            gender = "Male";
+            updateChart(chartViewer);
+        });
+        
+        femaleButton.setOnAction(e -> {
+            gender = "Female";
+            updateChart(chartViewer);
+        });
+        
+        genderBox.getChildren().addAll(genderLabel, allGenderButton, maleButton, femaleButton);
+        
+        return genderBox;
+    }
+    
+    // Create income options
+    private VBox createIncomeOptions(ChartViewer chartViewer) {
+        VBox incomeBox = new VBox(10);
+        
+        Label incomeLabel = new Label("Income");
+        incomeLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        incomeLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        ToggleGroup incomeToggleGroup = new ToggleGroup();
+        
+        RadioButton allIncomeButton = createStyledRadioButton("All", incomeToggleGroup);
+        allIncomeButton.setSelected(true);
+        
+        RadioButton lowButton = createStyledRadioButton("Low", incomeToggleGroup);
+        RadioButton mediumButton = createStyledRadioButton("Medium", incomeToggleGroup);
+        RadioButton highButton = createStyledRadioButton("High", incomeToggleGroup);
+        
+        // Set action handlers for income buttons
+        allIncomeButton.setOnAction(e -> {
+            income = "";
+            updateChart(chartViewer);
+        });
+        
+        lowButton.setOnAction(e -> {
+            income = "Low";
+            updateChart(chartViewer);
+        });
+        
+        mediumButton.setOnAction(e -> {
+            income = "Medium";
+            updateChart(chartViewer);
+        });
+        
+        highButton.setOnAction(e -> {
+            income = "High";
+            updateChart(chartViewer);
+        });
+        
+        incomeBox.getChildren().addAll(incomeLabel, allIncomeButton, lowButton, mediumButton, highButton);
+        
+        return incomeBox;
+    }
+    
+    // Create context options
+    private VBox createContextOptions(ChartViewer chartViewer) {
+        VBox contextBox = new VBox(10);
+        
+        Label contextLabel = new Label("Context");
+        contextLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        contextLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        CheckBox newsCheck = createStyledCheckBox("News");
+        CheckBox shoppingCheck = createStyledCheckBox("Shopping");
+        CheckBox socialMediaCheck = createStyledCheckBox("Social Media");
+        CheckBox blogCheck = createStyledCheckBox("Blog");
+        CheckBox hobbyCheck = createStyledCheckBox("Hobby");
+        CheckBox travelCheck = createStyledCheckBox("Travel");
+        
+        // Button to clear all context filters
+        Button clearContextButton = new Button("Clear All");
+        clearContextButton.setFont(Font.font("Arial", 12));
+        clearContextButton.setStyle("-fx-background-color: #f0f0f0; -fx-text-fill: #333333;");
+        clearContextButton.setOnAction(e -> {
+            newsCheck.setSelected(false);
+            shoppingCheck.setSelected(false);
+            socialMediaCheck.setSelected(false);
+            blogCheck.setSelected(false);
+            hobbyCheck.setSelected(false);
+            travelCheck.setSelected(false);
+            context.clear();
+            updateChart(chartViewer);
+        });
+        
+        // Set action handlers for context checkboxes
+        newsCheck.setOnAction(e -> {
+            if (newsCheck.isSelected()) {
+                context.add("News");
+            } else {
+                context.remove("News");
+            }
+            updateChart(chartViewer);
+        });
+        
+        shoppingCheck.setOnAction(e -> {
+            if (shoppingCheck.isSelected()) {
+                context.add("Shopping");
+            } else {
+                context.remove("Shopping");
+            }
+            updateChart(chartViewer);
+        });
+        
+        socialMediaCheck.setOnAction(e -> {
+            if (socialMediaCheck.isSelected()) {
+                context.add("Social Media");
+            } else {
+                context.remove("Social Media");
+            }
+            updateChart(chartViewer);
+        });
+        
+        blogCheck.setOnAction(e -> {
+            if (blogCheck.isSelected()) {
+                context.add("Blog");
+            } else {
+                context.remove("Blog");
+            }
+            updateChart(chartViewer);
+        });
+        
+        hobbyCheck.setOnAction(e -> {
+            if (hobbyCheck.isSelected()) {
+                context.add("Hobby");
+            } else {
+                context.remove("Hobby");
+            }
+            updateChart(chartViewer);
+        });
+        
+        travelCheck.setOnAction(e -> {
+            if (travelCheck.isSelected()) {
+                context.add("Travel");
+            } else {
+                context.remove("Travel");
+            }
+            updateChart(chartViewer);
+        });
+        
+        HBox clearButtonContainer = new HBox();
+        clearButtonContainer.setAlignment(Pos.CENTER_RIGHT);
+        clearButtonContainer.getChildren().add(clearContextButton);
+        clearButtonContainer.setPadding(new Insets(5, 0, 0, 0));
+        
+        contextBox.getChildren().addAll(
+            contextLabel,
+            newsCheck,
+            shoppingCheck,
+            socialMediaCheck,
+            blogCheck,
+            hobbyCheck,
+            travelCheck,
+            clearButtonContainer
+        );
+        
+        return contextBox;
+    }
+    
+    // Create age options
+    private VBox createAgeOptions(ChartViewer chartViewer) {
+        VBox ageBox = new VBox(10);
+        
+        Label ageLabel = new Label("Age");
+        ageLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        ageLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        CheckBox under25Check = createStyledCheckBox("Under 25");
+        CheckBox age25to34Check = createStyledCheckBox("25-34");
+        CheckBox age35to44Check = createStyledCheckBox("35-44");
+        CheckBox age45to54Check = createStyledCheckBox("45-54");
+        CheckBox over54Check = createStyledCheckBox("Over 54");
+        
+        // Button to clear all age filters
+        Button clearAgeButton = new Button("Clear All");
+        clearAgeButton.setFont(Font.font("Arial", 12));
+        clearAgeButton.setStyle("-fx-background-color: #f0f0f0; -fx-text-fill: #333333;");
+        clearAgeButton.setOnAction(e -> {
+            under25Check.setSelected(false);
+            age25to34Check.setSelected(false);
+            age35to44Check.setSelected(false);
+            age45to54Check.setSelected(false);
+            over54Check.setSelected(false);
+            age.clear();
+            updateChart(chartViewer);
+        });
+        
+        // Set action handlers for age checkboxes
+        under25Check.setOnAction(e -> {
+            if (under25Check.isSelected()) {
+                age.add("<25");
+            } else {
+                age.remove("<25");
+            }
+            updateChart(chartViewer);
+        });
+        
+        age25to34Check.setOnAction(e -> {
+            if (age25to34Check.isSelected()) {
+                age.add("25-34");
+            } else {
+                age.remove("25-34");
+            }
+            updateChart(chartViewer);
+        });
+        
+        age35to44Check.setOnAction(e -> {
+            if (age35to44Check.isSelected()) {
+                age.add("35-44");
+            } else {
+                age.remove("35-44");
+            }
+            updateChart(chartViewer);
+        });
+        
+        age45to54Check.setOnAction(e -> {
+            if (age45to54Check.isSelected()) {
+                age.add("45-54");
+            } else {
+                age.remove("45-54");
+            }
+            updateChart(chartViewer);
+        });
+        
+        over54Check.setOnAction(e -> {
+            if (over54Check.isSelected()) {
+                age.add(">54");
+            } else {
+                age.remove(">54");
+            }
+            updateChart(chartViewer);
+        });
+        
+        HBox clearButtonContainer = new HBox();
+        clearButtonContainer.setAlignment(Pos.CENTER_RIGHT);
+        clearButtonContainer.getChildren().add(clearAgeButton);
+        clearButtonContainer.setPadding(new Insets(5, 0, 0, 0));
+        
+        ageBox.getChildren().addAll(
+            ageLabel,
+            under25Check,
+            age25to34Check,
+            age35to44Check,
+            age45to54Check,
+            over54Check,
+            clearButtonContainer
+        );
+        
+        return ageBox;
+    }
+    
+    // Create a section with title and content
+    private VBox createSection(String title, VBox content) {
+        VBox section = new VBox(10);
+        
+        Label sectionTitle = new Label(title);
+        sectionTitle.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        sectionTitle.setTextFill(Color.web(HEADER_COLOR));
+        
+        Separator separator = new Separator();
+        separator.setStyle("-fx-opacity: 0.3;");
+        
+        section.getChildren().addAll(sectionTitle, separator, content);
+        
+        return section;
+    }
+    
+    // Create styled button
+    private Button createStyledButton(String text, String bgColor, String hoverColor) {
+        Button button = new Button(text);
+        button.setPrefSize(140, 35);
+        button.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        
+        String style = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 2, 0, 0, 1); " +
+                "-fx-cursor: hand;", bgColor);
+        
+        String hoverStyle = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 3, 0, 0, 2); " +
+                "-fx-cursor: hand;", hoverColor);
+        
+        button.setStyle(style);
+        
+        button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
+        button.setOnMouseExited(e -> button.setStyle(style));
+        
+        return button;
+    }
+    
+    // Create styled radio button
+    private RadioButton createStyledRadioButton(String text, ToggleGroup group) {
+        RadioButton radioButton = new RadioButton(text);
+        radioButton.setToggleGroup(group);
+        radioButton.setFont(Font.font("Arial", 13));
+        radioButton.setTextFill(Color.web(TEXT_COLOR));
+        return radioButton;
+    }
+    
+    // Create styled checkbox
+    private CheckBox createStyledCheckBox(String text) {
+        CheckBox checkBox = new CheckBox(text);
+        checkBox.setFont(Font.font("Arial", 13));
+        checkBox.setTextFill(Color.web(TEXT_COLOR));
+        return checkBox;
+    }
+    
+    // Update chart
+    private void updateChart(ChartViewer chartViewer) {
+        chartViewer.setChart(chartCreator.updateChart(currentChart, timeFlag, gender, income, context, age));
+    }
+}
+
diff --git a/src/main/java/com/example/Click.java b/src/main/java/com/example/Click.java
deleted file mode 100644
index 32ac27def8f318685b4a69e2c5b858b09af56f57..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/Click.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.example;
-
-public class Click {
-    private String date;
-    private String id;
-    private double clickCost;
-
-    public Click(String date, String iD, double clickCost) {
-        this.date = date;
-        this.id = iD;
-        this.clickCost = clickCost;
-    }
-
-    @Override
-    public String toString() {
-        return "Click{" +
-                "date='" + date + '\'' +
-                ", id='" + id + '\'' +
-                ", ClickCost='" + clickCost + '\''+"}";
-    }
-}
diff --git a/src/main/java/com/example/ClickLogReader.java b/src/main/java/com/example/ClickLogReader.java
deleted file mode 100644
index 830560f0b72827f7b3c7f4715bc7ce3422a58bb2..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/ClickLogReader.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.example;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ClickLogReader {
-    public List<Click> readCSV(String fileName) {
-        List<Click> clickReport = new ArrayList<>();
-        try (BufferedReader clickLogReader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/" + fileName)))) {
-            String line;
-            boolean firstLine = true;
-            while ((line = clickLogReader.readLine()) != null) {
-                if (firstLine) {
-                    firstLine = false; // Skip header
-                    continue;
-                }
-
-                String[] values = line.split(",");
-                if (values.length == 3) {
-                    clickReport.add(new Click(values[0], values[1], Double.parseDouble(values[2])));
-                }
-            }
-        } catch (IOException | NumberFormatException e) {
-            e.printStackTrace();
-
-        }
-
-        return clickReport;
-    }
-}
diff --git a/src/main/java/com/example/EditPage.java b/src/main/java/com/example/EditPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..259decb6d62f7d345198a65d25f60484134c33b0
--- /dev/null
+++ b/src/main/java/com/example/EditPage.java
@@ -0,0 +1,26 @@
+package com.example;
+
+import javafx.stage.Stage;
+
+import java.util.ArrayList;
+
+public abstract class EditPage {
+    private String timeFlag;
+    private String currentChart;
+    private String gender;
+    private ArrayList<String> age;
+    private String income;
+    private ArrayList<String> context;
+
+    private LogManager logManager;
+    private Stage stage;
+
+
+    public EditPage(){
+    }
+
+    /**
+     * Display method
+     */
+    public abstract void show();
+}
diff --git a/src/main/java/com/example/EditPage1.java b/src/main/java/com/example/EditPage1.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e8d5c51c96317d35fbf242a36a76b419262e095
--- /dev/null
+++ b/src/main/java/com/example/EditPage1.java
@@ -0,0 +1,516 @@
+package com.example;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.layout.Region;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.stage.Stage;
+
+import java.util.ArrayList;
+
+public class EditPage1 extends EditPage {
+
+    private ArrayList<String> timeFlag;
+    private ArrayList<String> currentChart;
+    private ArrayList<String> gender;
+    private ArrayList<ArrayList<String>> age;
+    private ArrayList<String> income;
+    private ArrayList<ArrayList<String>> context;
+
+    private LogManager logManager;
+    private Stage stage;
+    
+    // Define style constants
+    private final String BACKGROUND_COLOR = "#f5f5f7";
+    private final String PRIMARY_COLOR = "#4285F4";
+    private final String PRIMARY_DARK_COLOR = "#3367d6";
+    private final String SECTION_BACKGROUND = "white";
+    private final String HEADER_COLOR = "#333333";
+    private final String TEXT_COLOR = "#555555";
+    
+    public EditPage1(Stage stage, LogManager logManager, ArrayList<String> currentChart,
+                     ArrayList<String> timeFlag, ArrayList<String> gender, ArrayList<String> income,
+                     ArrayList<ArrayList<String>> context, ArrayList<ArrayList<String>> age) {
+        this.currentChart = currentChart;
+        this.timeFlag = timeFlag;
+        this.gender = gender;
+        this.income = income;
+        this.context = context;
+        this.age = age;
+        this.logManager = logManager;
+        this.stage = stage;
+    }
+
+    @Override
+    public void show() {
+        // Create main layout
+        BorderPane root = new BorderPane();
+        root.setStyle("-fx-background-color: " + BACKGROUND_COLOR + ";");
+        
+        // Create top navigation bar
+        HBox navBar = createNavigationBar();
+        
+        // Create central content area
+        GridPane contentPane = createContentPane();
+        
+        // Set layout
+        root.setTop(navBar);
+        root.setCenter(contentPane);
+        
+        // Set margins
+        BorderPane.setMargin(contentPane, new Insets(20, 20, 20, 20));
+        
+        Scene scene = new Scene(root, 1300, 800);
+        stage.setScene(scene);
+        stage.setTitle("Ad Auction Dashboard - Edit Chart 1");
+        stage.show();
+    }
+    
+    // Create top navigation bar
+    private HBox createNavigationBar() {
+        HBox navBar = new HBox(15);
+        navBar.setAlignment(Pos.CENTER_LEFT);
+        navBar.setPadding(new Insets(15, 20, 15, 20));
+        navBar.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);");
+        
+        Label title = new Label("Edit Chart 1");
+        title.setFont(Font.font("Arial", FontWeight.BOLD, 18));
+        title.setTextFill(Color.web(HEADER_COLOR));
+        
+        Region spacer = new Region();
+        HBox.setHgrow(spacer, javafx.scene.layout.Priority.ALWAYS);
+        
+        Button backButton = createStyledButton("Back to Charts", "#757575", "#616161");
+        Button overallMetricsButton = createStyledButton("Overall Metrics", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        Button logOutButton = createStyledButton("Logout", "#757575", "#616161");
+        
+        // Set button events
+        backButton.setOnAction(e -> {
+            MultiChartPage multiChartPage = new MultiChartPage(stage, logManager, currentChart, timeFlag, gender, income, context, age);
+            multiChartPage.show();
+        });
+
+        overallMetricsButton.setOnAction(e -> {
+            OverallMetricsPage metricsPage = new OverallMetricsPage(stage, logManager);
+            metricsPage.show();
+        });
+
+        logOutButton.setOnAction(e -> {
+            Login login = new Login(stage);
+            login.show();
+        });
+        
+        // Add to navigation bar
+        navBar.getChildren().addAll(title, spacer, backButton, overallMetricsButton, logOutButton);
+        
+        return navBar;
+    }
+    
+    // Create central content area
+    private GridPane createContentPane() {
+        GridPane contentPane = new GridPane();
+        contentPane.setHgap(20);
+        contentPane.setVgap(20);
+        contentPane.setAlignment(Pos.CENTER);
+        
+        // Create filter groups
+        VBox metricsSection = createMetricsSection();
+        VBox timeSection = createTimeSection();
+        VBox genderSection = createGenderSection();
+        VBox incomeSection = createIncomeSection();
+        VBox contextSection = createContextSection();
+        VBox ageSection = createAgeSection();
+        
+        // Add groups to grid
+        contentPane.add(metricsSection, 0, 0);
+        contentPane.add(timeSection, 1, 0);
+        contentPane.add(genderSection, 2, 0);
+        contentPane.add(incomeSection, 3, 0);
+        contentPane.add(contextSection, 4, 0);
+        contentPane.add(ageSection, 5, 0);
+        
+        return contentPane;
+    }
+    
+    // Create metrics group
+    private VBox createMetricsSection() {
+        return createSectionBox("Metrics", createMetricsContent());
+    }
+    
+    // Create time group
+    private VBox createTimeSection() {
+        return createSectionBox("Time Granularity", createTimeContent());
+    }
+    
+    // Create gender group
+    private VBox createGenderSection() {
+        return createSectionBox("Gender", createGenderContent());
+    }
+    
+    // Create income group
+    private VBox createIncomeSection() {
+        return createSectionBox("Income", createIncomeContent());
+    }
+    
+    // Create context group
+    private VBox createContextSection() {
+        return createSectionBox("Context", createContextContent());
+    }
+    
+    // Create age group
+    private VBox createAgeSection() {
+        return createSectionBox("Age", createAgeContent());
+    }
+    
+    // Create a generic group box
+    private VBox createSectionBox(String title, VBox content) {
+        VBox sectionBox = new VBox(15);
+        sectionBox.setPadding(new Insets(20));
+        sectionBox.setMinWidth(200);
+        sectionBox.setMaxWidth(200);
+        sectionBox.setMinHeight(400);
+        sectionBox.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                          "-fx-background-radius: 10; " +
+                          "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);");
+        
+        Label titleLabel = new Label(title);
+        titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        titleLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        Separator separator = new Separator();
+        separator.setStyle("-fx-opacity: 0.3;");
+        
+        sectionBox.getChildren().addAll(titleLabel, separator, content);
+        
+        return sectionBox;
+    }
+    
+    // Create metrics content
+    private VBox createMetricsContent() {
+        VBox content = new VBox(10);
+        ToggleGroup metricOptions = new ToggleGroup();
+        
+        // Create radio buttons for different metrics
+        RadioButton clickMetric = createStyledRadioButton("Total Clicks", metricOptions);
+        clickMetric.setSelected(true);
+        clickMetric.setOnAction(e -> {
+            this.currentChart.set(0, "Clicks");
+        });
+        
+        RadioButton impressionMetric = createStyledRadioButton("Total Impressions", metricOptions);
+        impressionMetric.setOnAction(e -> {
+            this.currentChart.set(0, "Impressions");
+        });
+        
+        RadioButton uniqueMetric = createStyledRadioButton("Unique Visitors", metricOptions);
+        uniqueMetric.setOnAction(e -> {
+            this.currentChart.set(0, "Uniques");
+        });
+        
+        RadioButton bouncesMetric = createStyledRadioButton("Bounces", metricOptions);
+        bouncesMetric.setOnAction(e -> {
+            this.currentChart.set(0, "Bounces");
+        });
+        
+        RadioButton conversionMetric = createStyledRadioButton("Conversions", metricOptions);
+        conversionMetric.setOnAction(e -> {
+            this.currentChart.set(0, "Conversions");
+        });
+        
+        RadioButton costMetric = createStyledRadioButton("Total Cost", metricOptions);
+        costMetric.setOnAction(e -> {
+            this.currentChart.set(0, "Cost");
+        });
+        
+        RadioButton ctrMetric = createStyledRadioButton("Click-Through Rate (CTR)", metricOptions);
+        ctrMetric.setOnAction(e -> {
+            this.currentChart.set(0, "CTR");
+        });
+        
+        RadioButton cpaMetric = createStyledRadioButton("Cost Per Acquisition (CPA)", metricOptions);
+        cpaMetric.setOnAction(e -> {
+            this.currentChart.set(0, "CPA");
+        });
+        
+        RadioButton cpcMetric = createStyledRadioButton("Cost Per Click (CPC)", metricOptions);
+        cpcMetric.setOnAction(e -> {
+            this.currentChart.set(0, "CPC");
+        });
+        
+        RadioButton cpmMetric = createStyledRadioButton("Cost Per Mille (CPM)", metricOptions);
+        cpmMetric.setOnAction(e -> {
+            this.currentChart.set(0, "CPM");
+        });
+        
+        RadioButton bounceRateMetric = createStyledRadioButton("Bounce Rate", metricOptions);
+        bounceRateMetric.setOnAction(e -> {
+            this.currentChart.set(0, "BounceRate");
+        });
+        
+        content.getChildren().addAll(
+            clickMetric, impressionMetric, uniqueMetric, bouncesMetric, 
+            conversionMetric, costMetric, ctrMetric, cpaMetric, 
+            cpcMetric, cpmMetric, bounceRateMetric
+        );
+        
+        return content;
+    }
+    
+    // Create time content
+    private VBox createTimeContent() {
+        VBox content = new VBox(10);
+        ToggleGroup timeOptions = new ToggleGroup();
+        
+        RadioButton dailyButton = createStyledRadioButton("Daily", timeOptions);
+        dailyButton.setSelected(true);
+        dailyButton.setOnAction(e -> {
+            this.timeFlag.set(0, "Daily");
+        });
+        
+        RadioButton weeklyButton = createStyledRadioButton("Weekly", timeOptions);
+        weeklyButton.setOnAction(e -> {
+            this.timeFlag.set(0, "Weekly");
+        });
+        
+        RadioButton monthlyButton = createStyledRadioButton("Monthly", timeOptions);
+        monthlyButton.setOnAction(e -> {
+            this.timeFlag.set(0, "Monthly");
+        });
+        
+        content.getChildren().addAll(dailyButton, weeklyButton, monthlyButton);
+        
+        return content;
+    }
+    
+    // Create gender content
+    private VBox createGenderContent() {
+        VBox content = new VBox(10);
+        ToggleGroup genderOptions = new ToggleGroup();
+        
+        RadioButton bothGenderButton = createStyledRadioButton("All", genderOptions);
+        bothGenderButton.setSelected(true);
+        bothGenderButton.setOnAction(e -> {
+            this.gender.set(0, "");
+        });
+        
+        RadioButton maleButton = createStyledRadioButton("Male", genderOptions);
+        maleButton.setOnAction(e -> {
+            this.gender.set(0, "Male");
+        });
+        
+        RadioButton femaleButton = createStyledRadioButton("Female", genderOptions);
+        femaleButton.setOnAction(e -> {
+            this.gender.set(0, "Female");
+        });
+        
+        content.getChildren().addAll(bothGenderButton, maleButton, femaleButton);
+        
+        return content;
+    }
+    
+    // Create income content
+    private VBox createIncomeContent() {
+        VBox content = new VBox(10);
+        ToggleGroup incomeOptions = new ToggleGroup();
+        
+        RadioButton anyIncomeButton = createStyledRadioButton("All", incomeOptions);
+        anyIncomeButton.setSelected(true);
+        anyIncomeButton.setOnAction(e -> {
+            this.income.set(0, "");
+        });
+        
+        RadioButton lowButton = createStyledRadioButton("Low", incomeOptions);
+        lowButton.setOnAction(e -> {
+            this.income.set(0, "Low");
+        });
+        
+        RadioButton mediumButton = createStyledRadioButton("Medium", incomeOptions);
+        mediumButton.setOnAction(e -> {
+            this.income.set(0, "Medium");
+        });
+        
+        RadioButton highButton = createStyledRadioButton("High", incomeOptions);
+        highButton.setOnAction(e -> {
+            this.income.set(0, "High");
+        });
+        
+        content.getChildren().addAll(anyIncomeButton, lowButton, mediumButton, highButton);
+        
+        return content;
+    }
+    
+    // Create context content
+    private VBox createContextContent() {
+        VBox content = new VBox(10);
+        
+        CheckBox newsButton = createStyledCheckBox("News");
+        newsButton.setOnAction(e -> {
+            if (newsButton.isSelected()) {
+                this.context.get(0).add("News");
+            } else {
+                this.context.get(0).remove("News");
+            }
+        });
+        
+        CheckBox shoppingButton = createStyledCheckBox("Shopping");
+        shoppingButton.setOnAction(e -> {
+            if (shoppingButton.isSelected()) {
+                this.context.get(0).add("Shopping");
+            } else {
+                this.context.get(0).remove("Shopping");
+            }
+        });
+        
+        CheckBox socialButton = createStyledCheckBox("Social Media");
+        socialButton.setOnAction(e -> {
+            if (socialButton.isSelected()) {
+                this.context.get(0).add("Social Media");
+            } else {
+                this.context.get(0).remove("Social Media");
+            }
+        });
+        
+        CheckBox blogButton = createStyledCheckBox("Blog");
+        blogButton.setOnAction(e -> {
+            if (blogButton.isSelected()) {
+                this.context.get(0).add("Blog");
+            } else {
+                this.context.get(0).remove("Blog");
+            }
+        });
+        
+        CheckBox hobbyButton = createStyledCheckBox("Hobby");
+        hobbyButton.setOnAction(e -> {
+            if (hobbyButton.isSelected()) {
+                this.context.get(0).add("Hobby");
+            } else {
+                this.context.get(0).remove("Hobby");
+            }
+        });
+        
+        CheckBox travelButton = createStyledCheckBox("Travel");
+        travelButton.setOnAction(e -> {
+            if (travelButton.isSelected()) {
+                this.context.get(0).add("Travel");
+            } else {
+                this.context.get(0).remove("Travel");
+            }
+        });
+        
+        content.getChildren().addAll(newsButton, shoppingButton, socialButton, blogButton, hobbyButton, travelButton);
+        
+        return content;
+    }
+    
+    // Create age content
+    private VBox createAgeContent() {
+        VBox content = new VBox(10);
+        
+        CheckBox age1Button = createStyledCheckBox("Under 25");
+        age1Button.setOnAction(e -> {
+            if (age1Button.isSelected()) {
+                this.age.get(0).add("<25");
+            } else {
+                this.age.get(0).remove("<25");
+            }
+        });
+        
+        CheckBox age2Button = createStyledCheckBox("25-34");
+        age2Button.setOnAction(e -> {
+            if (age2Button.isSelected()) {
+                this.age.get(0).add("25-34");
+            } else {
+                this.age.get(0).remove("25-34");
+            }
+        });
+        
+        CheckBox age3Button = createStyledCheckBox("35-44");
+        age3Button.setOnAction(e -> {
+            if (age3Button.isSelected()) {
+                this.age.get(0).add("35-44");
+            } else {
+                this.age.get(0).remove("35-44");
+            }
+        });
+        
+        CheckBox age4Button = createStyledCheckBox("45-54");
+        age4Button.setOnAction(e -> {
+            if (age4Button.isSelected()) {
+                this.age.get(0).add("45-54");
+            } else {
+                this.age.get(0).remove("45-54");
+            }
+        });
+        
+        CheckBox age5Button = createStyledCheckBox("Over 54");
+        age5Button.setOnAction(e -> {
+            if (age5Button.isSelected()) {
+                this.age.get(0).add(">54");
+            } else {
+                this.age.get(0).remove(">54");
+            }
+        });
+        
+        content.getChildren().addAll(age1Button, age2Button, age3Button, age4Button, age5Button);
+        
+        return content;
+    }
+    
+    // Create styled radio button
+    private RadioButton createStyledRadioButton(String text, ToggleGroup group) {
+        RadioButton radioButton = new RadioButton(text);
+        radioButton.setToggleGroup(group);
+        radioButton.setFont(Font.font("Arial", 13));
+        radioButton.setTextFill(Color.web(TEXT_COLOR));
+        radioButton.setPadding(new Insets(3, 0, 3, 0));
+        return radioButton;
+    }
+    
+    // Create styled checkbox
+    private CheckBox createStyledCheckBox(String text) {
+        CheckBox checkBox = new CheckBox(text);
+        checkBox.setFont(Font.font("Arial", 13));
+        checkBox.setTextFill(Color.web(TEXT_COLOR));
+        checkBox.setPadding(new Insets(3, 0, 3, 0));
+        return checkBox;
+    }
+    
+    // Create styled button
+    private Button createStyledButton(String text, String bgColor, String hoverColor) {
+        Button button = new Button(text);
+        button.setPrefSize(120, 35);
+        button.setFont(Font.font("Arial", FontWeight.NORMAL, 13));
+        
+        String style = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 2, 0, 0, 1); " +
+                "-fx-cursor: hand;", bgColor);
+        
+        String hoverStyle = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 3, 0, 0, 2); " +
+                "-fx-cursor: hand;", hoverColor);
+        
+        button.setStyle(style);
+        
+        button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
+        button.setOnMouseExited(e -> button.setStyle(style));
+        
+        return button;
+    }
+}
diff --git a/src/main/java/com/example/EditPage2.java b/src/main/java/com/example/EditPage2.java
new file mode 100644
index 0000000000000000000000000000000000000000..eaf58c0e64d6f5cb84e3ff9fdb401f3b8e2804ce
--- /dev/null
+++ b/src/main/java/com/example/EditPage2.java
@@ -0,0 +1,311 @@
+package com.example;
+
+import javafx.scene.Scene;
+import javafx.scene.control.*;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+
+import java.util.ArrayList;
+
+public class EditPage2 extends EditPage{
+    private ArrayList<String> timeFlag;
+    private ArrayList<String> currentChart;
+    private ArrayList<String> gender;
+    private ArrayList<ArrayList<String>> age;
+    private ArrayList<String> income;
+    private ArrayList<ArrayList<String>> context;
+
+    private LogManager logManager;
+    private Stage stage;
+    public EditPage2(Stage stage, LogManager logManager, ArrayList<String> currentChart,
+                     ArrayList<String> timeFlag, ArrayList<String> gender, ArrayList<String> income,
+                     ArrayList<ArrayList<String>> context, ArrayList<ArrayList<String>> age) {
+        this.currentChart = currentChart;
+        this.timeFlag = timeFlag;
+        this.gender = gender;
+        this.income = income;
+        this.context = context;
+        this.age = age;
+        this.logManager = logManager;
+        this.stage = stage;
+    }
+
+    @Override
+    public void show() {
+
+        //Metric options
+        ToggleGroup metricOptions = new ToggleGroup();
+
+        RadioButton clickMetric = new RadioButton("Total Clicks");
+        clickMetric.setToggleGroup(metricOptions);
+        clickMetric.setSelected(true);
+        clickMetric.setOnAction(e -> {
+            this.currentChart.set(1,"Clicks");
+        });
+        RadioButton impressionMetric = new RadioButton("Total Impressions");
+        impressionMetric.setToggleGroup(metricOptions);
+        impressionMetric.setOnAction(e -> {
+            this.currentChart.set(1,"Impressions");
+        });
+        RadioButton uniqueMetric = new RadioButton("Total uniques");
+        uniqueMetric.setToggleGroup(metricOptions);
+        uniqueMetric.setOnAction(e -> {
+            this.currentChart.set(1,"Uniques");
+        });
+        RadioButton bouncesMetric = new RadioButton("Total bounces");
+        bouncesMetric.setToggleGroup(metricOptions);
+        bouncesMetric.setOnAction(e -> {
+            this.currentChart.set(1,"Bounces");
+        });
+        RadioButton conversionMetric = new RadioButton("Total conversions");
+        conversionMetric.setToggleGroup(metricOptions);
+        conversionMetric.setOnAction(e -> {
+            this.currentChart.set(1,"Conversions");
+        });
+        RadioButton costMetric = new RadioButton("Total cost");
+        costMetric.setToggleGroup(metricOptions);
+        costMetric.setOnAction(e -> {
+            this.currentChart.set(1,"Cost");
+        });
+        RadioButton ctrMetric = new RadioButton("CTR");
+        ctrMetric.setToggleGroup(metricOptions);
+        ctrMetric.setOnAction(e -> {
+            this.currentChart.set(1,"CTR");
+        });
+        RadioButton cpaMetric = new RadioButton("CPA");
+        cpaMetric.setToggleGroup(metricOptions);
+        cpaMetric.setOnAction(e -> {
+            this.currentChart.set(1,"CPA");
+        });
+        RadioButton cpcMetric = new RadioButton("CPC");
+        cpcMetric.setToggleGroup(metricOptions);
+        cpcMetric.setOnAction(e -> {
+            this.currentChart.set(1,"CPC");
+        });
+        RadioButton cpmMetric = new RadioButton("CPM");
+        cpmMetric.setToggleGroup(metricOptions);
+        cpmMetric.setOnAction(e -> {
+            this.currentChart.set(1,"CPM");
+        });
+        RadioButton bounceRateMetric = new RadioButton("Bounce Rate");
+        bounceRateMetric.setToggleGroup(metricOptions);
+        bounceRateMetric.setOnAction(e -> {
+            this.currentChart.set(1,"BounceRate");
+        });
+        var metricHolder = new VBox();
+        var metricLabel = new Label("Metrics");
+        metricHolder.getChildren().addAll(metricLabel,clickMetric,impressionMetric,uniqueMetric,bouncesMetric,conversionMetric,costMetric,ctrMetric,cpaMetric,cpcMetric,cpmMetric,bounceRateMetric);
+
+        //Time granularity buttons
+        ToggleGroup timeOptions = new ToggleGroup();
+
+        RadioButton dailyButton = new RadioButton("Daily");
+        dailyButton.setSelected(true);
+        dailyButton.setToggleGroup(timeOptions);
+        dailyButton.setOnAction(e -> {
+            this.timeFlag.set(1,"Daily");
+        });
+        RadioButton weeklyButton = new RadioButton("Weekly");
+        weeklyButton.setToggleGroup(timeOptions);
+        weeklyButton.setOnAction(e -> {
+            this.timeFlag.set(1,"Weekly");
+        });
+        RadioButton monthlyButton = new RadioButton("Monthly");
+        monthlyButton.setToggleGroup(timeOptions);
+        monthlyButton.setOnAction(e -> {
+            this.timeFlag.set(1,"Monthly");
+        });
+        var timeHolder = new VBox();
+        var timeTabel = new Label("Time");
+        timeHolder.getChildren().addAll(timeTabel,dailyButton,weeklyButton,monthlyButton);
+
+        //Gender Buttons
+        ToggleGroup genderOptions = new ToggleGroup();
+
+        RadioButton bothGenderButton = new RadioButton("Both");
+        bothGenderButton.setSelected(true);
+        bothGenderButton.setToggleGroup(genderOptions);
+        bothGenderButton.setOnAction(e -> {
+            this.gender.set(1,"");
+        });
+        RadioButton maleButton = new RadioButton("Male");
+        maleButton.setToggleGroup(genderOptions);
+        maleButton.setOnAction(e -> {
+            this.gender.set(1,"Male");
+        });
+        RadioButton femaleButton = new RadioButton("Female");
+        femaleButton.setToggleGroup(genderOptions);
+        femaleButton.setOnAction(e -> {
+            this.gender.set(1,"Female");
+        });
+        var genderHolder = new VBox();
+        var genderLabel = new Label("Gender");
+        genderHolder.getChildren().addAll(genderLabel,bothGenderButton,maleButton,femaleButton);
+
+        // Income buttons
+        ToggleGroup incomeOptions = new ToggleGroup();
+
+        RadioButton anyIncomeButton = new RadioButton("Any");
+        anyIncomeButton.setSelected(true);
+        anyIncomeButton.setToggleGroup(incomeOptions);
+        anyIncomeButton.setOnAction(e -> {
+            this.income.set(1,"");
+        });
+        RadioButton lowButton = new RadioButton("Low");
+        lowButton.setToggleGroup(incomeOptions);
+        lowButton.setOnAction(e -> {
+            this.income.set(1,"Low");
+        });
+        RadioButton mediumButton = new RadioButton("Medium");
+        mediumButton.setToggleGroup(incomeOptions);
+        mediumButton.setOnAction(e -> {
+            this.income.set(1,"Medium");
+        });
+        RadioButton highButton = new RadioButton("High");
+        highButton.setToggleGroup(incomeOptions);
+        highButton.setOnAction(e -> {
+            this.income.set(1,"High");
+        });
+        var incomeHolder = new VBox();
+        var incomeLabel = new Label("Income");
+        incomeHolder.getChildren().addAll(incomeLabel,anyIncomeButton,lowButton,mediumButton,highButton);
+
+        // Context checkboxes
+        CheckBox newsButton = new CheckBox("News");
+        CheckBox shoppingButton = new CheckBox("Shopping");
+        CheckBox socialButton = new CheckBox("Social Media");
+        CheckBox blogButton = new CheckBox("Blog");
+        CheckBox hobbyButton = new CheckBox("Hobbies");
+        CheckBox travelButton = new CheckBox("Travel");
+
+        newsButton.setOnAction(e -> {
+            if (newsButton.isSelected()) {
+                this.context.get(1).add("News");
+            } else {
+                this.context.get(1).remove("News");
+            }
+        });
+        shoppingButton.setOnAction(e -> {
+            if (shoppingButton.isSelected()) {
+                this.context.get(1).add("Shopping");
+            } else {
+                this.context.get(1).remove("Shopping");
+            }
+        });
+        socialButton.setOnAction(e -> {
+            if (socialButton.isSelected()) {
+                this.context.get(1).add("Social Media");
+            } else {
+                this.context.get(1).remove("Social Media");
+            }
+        });
+        blogButton.setOnAction(e -> {
+            if (blogButton.isSelected()) {
+                this.context.get(1).add("Blog");
+            } else {
+                this.context.get(1).remove("Blog");
+            }
+        });
+        hobbyButton.setOnAction(e -> {
+            if (hobbyButton.isSelected()) {
+                this.context.get(1).add("Hobby");
+            } else {
+                this.context.get(1).remove("Hobby");
+            }
+        });
+        travelButton.setOnAction(e -> {
+            if (travelButton.isSelected()) {
+                this.context.get(1).add("Travel");
+            } else {
+                this.context.get(1).remove("Travel");
+            }
+        });
+        var contextHolder = new VBox();
+        var contextLabel = new Label("Context");
+        contextHolder.getChildren().addAll(contextLabel,newsButton,socialButton,shoppingButton,blogButton,hobbyButton,travelButton);
+
+
+        // Age checkboxes
+        CheckBox age1Button = new CheckBox("<25");
+        CheckBox age2Button = new CheckBox("25-34");
+        CheckBox age3Button = new CheckBox("35-44");
+        CheckBox age4Button = new CheckBox("45-54");
+        CheckBox age5Button = new CheckBox(">54");
+
+        age1Button.setOnAction(e -> {
+            if (age1Button.isSelected()) {
+                this.age.get(1).add("<25");
+            } else {
+                this.age.get(1).remove("<25");
+            }
+        });
+        age2Button.setOnAction(e -> {
+            if (age2Button.isSelected()) {
+                this.age.get(1).add("25-34");
+            } else {
+                this.age.get(1).remove("25-34");
+            }
+        });
+        age3Button.setOnAction(e -> {
+            if (age3Button.isSelected()) {
+                this.age.get(1).add("35-44");
+            } else {
+                this.age.get(1).remove("35-44");
+            }
+        });
+        age4Button.setOnAction(e -> {
+            if (age4Button.isSelected()) {
+                this.age.get(1).add("45-54");
+            } else {
+                this.age.get(1).remove("45-54");
+            }
+        });
+        age5Button.setOnAction(e -> {
+            if (age5Button.isSelected()) {
+                this.age.get(1).add(">54");
+            } else {
+                this.age.get(1).remove(">54");
+            }
+        });
+        var ageHolder = new VBox();
+        var ageLabel = new Label("Age");
+        ageHolder.getChildren().addAll(ageLabel,age1Button,age2Button,age3Button,age4Button,age5Button);
+
+        //Navigation Buttons
+        var buttonHolder = new HBox();
+        var backButton = new Button("Back");
+        var logOutButton = new Button("Logout");
+        var overallMetricsButton = new Button("Overall Metrics");
+        buttonHolder.getChildren().addAll(backButton, overallMetricsButton, logOutButton);
+
+        backButton.setOnAction(e -> {
+            MultiChartPage multiChartPage = new MultiChartPage(stage,logManager,currentChart,timeFlag,gender,income,context,age);
+            multiChartPage.show();
+        });
+
+        overallMetricsButton.setOnAction(e -> {
+            OverallMetricsPage metricsPage = new OverallMetricsPage(stage, logManager);
+            metricsPage.show();
+        });
+
+        logOutButton.setOnAction(e -> {
+            Login login = new Login(stage);
+            login.show();
+        });
+
+
+        var allOptionHolder = new HBox(20);
+        allOptionHolder.getChildren().addAll(metricHolder,timeHolder,genderHolder,incomeHolder,contextHolder,ageHolder);
+        BorderPane root = new BorderPane();
+        root.setCenter(allOptionHolder);
+        root.setTop(buttonHolder);
+        Scene scene = new Scene(root,1300,800);
+        stage.setScene(scene);
+        stage.setTitle("Edit Chart 2");
+        stage.show();
+
+
+    }
+}
diff --git a/src/main/java/com/example/Filter.java b/src/main/java/com/example/Filter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b18c9c850fde5eec5c2a95bb47976286346fb10b
--- /dev/null
+++ b/src/main/java/com/example/Filter.java
@@ -0,0 +1,137 @@
+package com.example;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class Filter {
+
+    /**
+     * Filters impression data by gender
+     * @param impressions
+     * @param gender
+     * @return
+     */
+    public ArrayList<String[]> genderFilter(ArrayList<String[]> impressions, String gender) {
+        //No gender filters
+        if (gender.equals("")) {
+            return impressions;
+        } else {
+            //Filter impressions
+            ArrayList<String[]> filteredImpressions = new ArrayList<>();
+            for (String[] row : impressions) {
+                if (row[2].equals(gender)) {
+                    filteredImpressions.add(row);
+                }
+            } return filteredImpressions;
+        }
+    }
+
+    /**
+     * Filter impressions by income
+     * @param impressions
+     * @param income
+     * @return
+     */
+    public ArrayList<String[]> incomeFilter(ArrayList<String[]>impressions, String income) {
+        if (income.equals("")) {
+            return impressions;
+        } else {
+            //Filter impressions
+            ArrayList<String[]> filteredImpressions = new ArrayList<>();
+            for (String[] row : impressions) {
+                if (row[4].equals(income)) {
+                    filteredImpressions.add(row);
+                }
+            } return filteredImpressions;
+        }
+    }
+
+    /**
+     * Filter impressions by context
+     * @param impressions
+     * @param context
+     * @return
+     */
+    public ArrayList<String[]> contextFilter(ArrayList<String[]> impressions, ArrayList<String> context) {
+        if (context.size() == 0) {
+            return impressions;
+        } else {
+            ArrayList<String[]> filteredImpressions = new ArrayList<>();
+            for (String[] row : impressions) {
+                if (context.contains(row[5])) {
+                    filteredImpressions.add(row);
+                }
+            } return filteredImpressions;
+        }
+    }
+
+    /**
+     * Filter impressions by age
+     * @param impressions
+     * @param age
+     * @return
+     */
+    public ArrayList<String[]> ageFilter(ArrayList<String[]>  impressions, ArrayList<String> age) {
+        if (age.size() == 0) {
+            return impressions;
+        } else {
+            ArrayList<String[]> filteredImpressions = new ArrayList<>();
+            for (String[] row : impressions) {
+                if (age.contains(row[3])) {
+                    filteredImpressions.add(row);
+                }
+            } return filteredImpressions;
+        }
+    }
+
+
+    /**
+     * Applies all filters to data
+     * @param clicks
+     * @param impressions
+     * @param interactions
+     * @param gender
+     * @param income
+     * @return
+     */
+    public ArrayList<String[]> [] filterPipeline(ArrayList<String[]> clicks, ArrayList<String[]> impressions, ArrayList<String[]> interactions, String gender, String income, ArrayList<String> context,ArrayList<String> age){
+        ArrayList<String[]> [] filteredLogs = new ArrayList[3];
+        HashSet<String> users = new HashSet<>();
+
+        // Get filtered impressions and unique IDs
+        ArrayList<String[]> filteredImpressions = ageFilter(contextFilter(incomeFilter(genderFilter(impressions,gender),income),context),age);
+        for (String [] entry : filteredImpressions) {
+            users.add(entry[1]);
+        }
+
+        //Get associated clicks and interactions
+        ArrayList<String[]> filteredClicks = idMatch(clicks,users);
+        ArrayList<String[]> filteredInteractions = idMatch(interactions,users);
+
+        //Add filtered logs to output list
+        filteredLogs[0] = filteredClicks;
+        filteredLogs[1] = filteredImpressions;
+        filteredLogs[2] = filteredInteractions;
+
+        return filteredLogs;
+    }
+
+    /**
+     * Matches click log or server log to impression log
+     * @param log
+     * @param users
+     * @return
+     */
+    public ArrayList<String[]> idMatch(ArrayList<String[]> log, HashSet<String> users) {
+        ArrayList<String[]> filteredLog = new ArrayList<>();
+        for (String[] entry : log) {
+            if (users.contains(entry[1])) {
+                filteredLog.add(entry);
+            }
+        }
+        return filteredLog;
+    }
+
+
+}
diff --git a/src/main/java/com/example/Impression.java b/src/main/java/com/example/Impression.java
deleted file mode 100644
index 15ecf3eec052dad22495fe9967c540174869bffc..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/Impression.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.example;
-
-/**
- * Represents an individual impression (advertisement view) from the CSV file.
- * Each instance of this class corresponds to one row in the dataset.
- */
-public class Impression {
-  private String date;          // Date when the impression occurred
-  private String id;            // Unique identifier for the impression
-  private String gender;        // Gender of the user who viewed the ad
-  private String age;           // Age group of the user
-  private String income;        // Income level of the user
-  private String context;       // Context in which the ad was displayed (e.g., News, Blog)
-  private double impressionCost;// Cost of this impression in monetary units
-
-  /**
-   * Constructor for creating an Impression object.
-   *
-   * @param date           Date of the impression
-   * @param id             Unique ID of the impression
-   * @param gender         Gender of the viewer
-   * @param age            Age group of the viewer
-   * @param income         Income level of the viewer
-   * @param context        Context where the ad was displayed
-   * @param impressionCost Cost of the impression
-   */
-  public Impression(String date, String id, String gender, String age, String income, String context, double impressionCost) {
-    this.date = date;
-    this.id = id;
-    this.gender = gender;
-    this.age = age;
-    this.income = income;
-    this.context = context;
-    this.impressionCost = impressionCost;
-  }
-
-  /**
-   * Converts the Impression object into a readable string format.
-   *
-   * @return A string representation of the impression details.
-   */
-  @Override
-  public String toString() {
-    return "Impression{" +
-      "date='" + date + '\'' +
-      ", id='" + id + '\'' +
-      ", gender='" + gender + '\'' +
-      ", age='" + age + '\'' +
-      ", income='" + income + '\'' +
-      ", context='" + context + '\'' +
-      ", impressionCost=" + impressionCost +
-      '}';
-  }
-}
diff --git a/src/main/java/com/example/ImpressionLogReader.java b/src/main/java/com/example/ImpressionLogReader.java
deleted file mode 100644
index d2c471071aa21aa9b0f18e70138e77724781313e..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/ImpressionLogReader.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.example;
-
-import java.io.*;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Reads the impression_log.csv file and converts each row into an Impression object.
- * This class is responsible for loading the dataset into a structured format.
- */
-public class ImpressionLogReader {
-  /**
-   * Reads a CSV file and parses its contents into a list of Impression objects.
-   *
-   * @param fileName The name of the CSV file to read.
-   * @return A list of Impression objects containing the parsed data.
-   */
-  public List<Impression> readCSV(String fileName) {
-    List<Impression> impressions = new ArrayList<>();
-
-    // Try to open the file and read its contents
-    try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/" + fileName)))) {
-      String line;
-      boolean firstLine = true; // Flag to skip the header row
-
-      while ((line = br.readLine()) != null) {
-        if (firstLine) {
-          firstLine = false; // Skip the first line (column names)
-          continue;
-        }
-
-        // Split the line by commas to extract individual values
-        String[] values = line.split(",");
-
-        // Ensure the row has the expected number of columns before processing
-        if (values.length == 7) {
-          impressions.add(new Impression(
-            values[0],                 // Date
-            values[1],                 // ID
-            values[2],                 // Gender
-            values[3],                 // Age
-            values[4],                 // Income
-            values[5],                 // Context
-            Double.parseDouble(values[6]) // Impression Cost (converted from String to double)
-          ));
-        }
-      }
-    } catch (IOException | NumberFormatException e) {
-      e.printStackTrace(); // Print error details if file reading fails
-    }
-
-    return impressions; // Return the list of impressions
-  }
-}
diff --git a/src/main/java/com/example/InputFilesPage.java b/src/main/java/com/example/InputFilesPage.java
index bb293b73114f3a1c96575ffbaef11d4237527b14..a06f40a6fbc3751a032b959fa59ddf0466921cac 100644
--- a/src/main/java/com/example/InputFilesPage.java
+++ b/src/main/java/com/example/InputFilesPage.java
@@ -1,10 +1,15 @@
 package com.example;
 
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.Scene;
 import javafx.scene.control.*;
-import javafx.scene.layout.GridPane;
+import javafx.scene.layout.*;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
 import javafx.stage.FileChooser;
 import javafx.stage.Stage;
 
@@ -14,72 +19,124 @@ public class InputFilesPage {
     private Stage stage;
     private Scene scene;
 
-
     private File impressionLogFile;
     private File clickLogFile;
     private File serverLogFile;
 
+    // Log manager to be passed around the system (Use it in constructors for new scenes), essentially containing all the files and data
+    public LogManager logManager = new LogManager();
+
     InputFilesPage(Stage stage) {
         this.stage = stage;
         initialize();
     }
 
     private void initialize() {
-        GridPane grid = new GridPane();
-        grid.setAlignment(Pos.CENTER);
-        grid.setHgap(10);
-        grid.setVgap(10);
-        grid.setPadding(new Insets(25));
-
+        // Use BorderPane as main layout
+        BorderPane mainLayout = new BorderPane();
+        mainLayout.setPadding(new Insets(20));
+        mainLayout.setStyle("-fx-background-color: #f5f5f7;");
+        
+        // Create header section
+        VBox headerBox = new VBox(15);
+        headerBox.setAlignment(Pos.CENTER);
+        headerBox.setPadding(new Insets(20, 0, 40, 0));
+        
         Label titleLabel = new Label("Input Files");
-        titleLabel.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;");
-        grid.add(titleLabel, 0, 0, 2, 1);
-
-        Label impressionLogLabel = new Label("Impression Log:");
-        grid.add(impressionLogLabel, 0, 1);
-        Button impressionLogButton = new Button("Select File");
-        grid.add(impressionLogButton, 1, 1);
-
-        Label clickLogLabel = new Label("Click Log:");
-        grid.add(clickLogLabel, 0, 2);
-        Button clickLogButton = new Button("Select File");
-        grid.add(clickLogButton, 1, 2);
-
-        Label serverLogLabel = new Label("Server Log:");
-        grid.add(serverLogLabel, 0, 3);
-        Button serverLogButton = new Button("Select File");
-        grid.add(serverLogButton, 1, 3);
-
-        Button proceedButton = new Button("Proceed");
-        grid.add(proceedButton, 0, 4);
-        Button logoutButton = new Button("Logout");
-        grid.add(logoutButton, 1, 4);
-
+        titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 28));
+        titleLabel.setTextFill(Color.web("#333333"));
+        
+        Label subtitleLabel = new Label("Please select data files for analysis");
+        subtitleLabel.setFont(Font.font("Arial", 14));
+        subtitleLabel.setTextFill(Color.web("#666666"));
+        
+        headerBox.getChildren().addAll(titleLabel, subtitleLabel);
+        mainLayout.setTop(headerBox);
+        
+        // File selection section using VBox
+        VBox fileSelectionBox = new VBox(20);
+        fileSelectionBox.setAlignment(Pos.CENTER);
+        fileSelectionBox.setPadding(new Insets(10, 30, 30, 30));
+        fileSelectionBox.setStyle("-fx-background-color: white; -fx-background-radius: 10; -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);");
+        
+        // Initialize properties
+        StringProperty impressionProperty = new SimpleStringProperty("");
+        StringProperty clickProperty = new SimpleStringProperty("");
+        StringProperty serverProperty = new SimpleStringProperty("");
+        
+        // Create file selection rows
+        HBox impressionRow = createFileSelectionRow("Impression Log:", impressionProperty);
+        HBox clickRow = createFileSelectionRow("Click Log:", clickProperty);
+        HBox serverRow = createFileSelectionRow("Server Log:", serverProperty);
+        
+        // Create button area
+        HBox buttonBox = new HBox(20);
+        buttonBox.setAlignment(Pos.CENTER);
+        buttonBox.setPadding(new Insets(20, 0, 10, 0));
+        
+        Button proceedButton = createStyledButton("Proceed", "#4285F4", "#3367d6");
+        Button logoutButton = createStyledButton("Logout", "#757575", "#616161");
+        
+        buttonBox.getChildren().addAll(proceedButton, logoutButton);
+        
+        // Add all components to file selection box
+        fileSelectionBox.getChildren().addAll(
+                impressionRow, 
+                createSeparator(), 
+                clickRow, 
+                createSeparator(), 
+                serverRow, 
+                createSeparator(), 
+                buttonBox);
+        
+        mainLayout.setCenter(fileSelectionBox);
+        
+        // File chooser
         FileChooser fileChooser = new FileChooser();
         fileChooser.setTitle("Select Log File");
-
+        
+        // Get buttons and set click handlers
+        Button impressionLogButton = (Button) impressionRow.getChildren().get(1);
+        Button clickLogButton = (Button) clickRow.getChildren().get(1);
+        Button serverLogButton = (Button) serverRow.getChildren().get(1);
+        
+        // Store the impression log in logManager
         impressionLogButton.setOnAction(e -> {
-            clickLogFile = fileChooser.showOpenDialog(stage);
-            if (clickLogFile != null) {
+            impressionLogFile = fileChooser.showOpenDialog(stage);
+            if (impressionLogFile != null) {
+                impressionProperty.set(impressionLogFile.getName());
+                logManager.assignImpressionLog(impressionLogFile);
+                logManager.convertImpressionLog();
                 System.out.println("Impression Log Selected: " + impressionLogFile.getAbsolutePath());
             }
         });
 
+        // Store the click log in LogManager
         clickLogButton.setOnAction(e -> {
             clickLogFile = fileChooser.showOpenDialog(stage);
             if (clickLogFile != null) {
+                clickProperty.set(clickLogFile.getName());
+                logManager.assignClickLog(clickLogFile);
+                logManager.convertClickLog();
                 System.out.println("Click Log Selected: " + clickLogFile.getAbsolutePath());
             }
         });
+
+        // Store the server log in LogManager
         serverLogButton.setOnAction(e -> {
             serverLogFile = fileChooser.showOpenDialog(stage);
             if (serverLogFile != null) {
+                serverProperty.set(serverLogFile.getName());
+                logManager.assignServerLog(serverLogFile);
+                logManager.convertServerLog();
                 System.out.println("Server Log Selected: " + serverLogFile.getAbsolutePath());
             }
         });
 
         proceedButton.setOnAction(e -> {
             System.out.println("Proceed Button clicked");
+            ChartPage chartPage = new ChartPage(stage, logManager);
+            chartPage.show();
         });
 
         logoutButton.setOnAction(e -> {
@@ -88,10 +145,121 @@ public class InputFilesPage {
             login.show();
         });
 
-        scene = new Scene(grid, 600, 400);
-
+        scene = new Scene(mainLayout, 800, 600);
+    }
+    
+    // Create a file selection row
+    private HBox createFileSelectionRow(String labelText, StringProperty fileNameProperty) {
+        HBox row = new HBox(15);
+        row.setAlignment(Pos.CENTER_LEFT);
+        row.setPadding(new Insets(10, 0, 10, 0));
+        
+        Label label = new Label(labelText);
+        label.setMinWidth(120);
+        label.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        label.setTextFill(Color.web("#333333"));
+        
+        Button selectButton = new Button("Select File");
+        selectButton.setPrefSize(120, 35);
+        selectButton.setStyle(
+                "-fx-background-color: #f0f0f0; " +
+                "-fx-text-fill: #333333; " +
+                "-fx-font-weight: normal; " +
+                "-fx-font-size: 13px; " +
+                "-fx-background-radius: 4; " +
+                "-fx-border-radius: 4; " +
+                "-fx-border-color: #d0d0d0; " +
+                "-fx-border-width: 1px; " +
+                "-fx-cursor: hand;");
+        
+        selectButton.setOnMouseEntered(e -> 
+            selectButton.setStyle(
+                "-fx-background-color: #e8e8e8; " +
+                "-fx-text-fill: #333333; " +
+                "-fx-font-weight: normal; " +
+                "-fx-font-size: 13px; " +
+                "-fx-background-radius: 4; " +
+                "-fx-border-radius: 4; " +
+                "-fx-border-color: #c0c0c0; " +
+                "-fx-border-width: 1px; " +
+                "-fx-cursor: hand;"));
+        
+        selectButton.setOnMouseExited(e -> 
+            selectButton.setStyle(
+                "-fx-background-color: #f0f0f0; " +
+                "-fx-text-fill: #333333; " +
+                "-fx-font-weight: normal; " +
+                "-fx-font-size: 13px; " +
+                "-fx-background-radius: 4; " +
+                "-fx-border-radius: 4; " +
+                "-fx-border-color: #d0d0d0; " +
+                "-fx-border-width: 1px; " +
+                "-fx-cursor: hand;"));
+        
+        Label fileNameLabel = new Label();
+        fileNameLabel.textProperty().bind(fileNameProperty);
+        fileNameLabel.setFont(Font.font("Arial", 13));
+        fileNameLabel.setTextFill(Color.web("#666666"));
+        fileNameLabel.setMinWidth(200);
+        fileNameLabel.setMaxWidth(300);
+        
+        // File status indicator
+        Region statusIndicator = new Region();
+        statusIndicator.setPrefSize(8, 8);
+        statusIndicator.setStyle("-fx-background-color: #cccccc; -fx-background-radius: 4;");
+        
+        // Update status indicator when file name changes
+        fileNameProperty.addListener((obs, oldVal, newVal) -> {
+            if (newVal != null && !newVal.isEmpty()) {
+                statusIndicator.setStyle("-fx-background-color: #4CAF50; -fx-background-radius: 4;");
+            } else {
+                statusIndicator.setStyle("-fx-background-color: #cccccc; -fx-background-radius: 4;");
+            }
+        });
+        
+        row.getChildren().addAll(label, selectButton, fileNameLabel, statusIndicator);
+        return row;
+    }
+    
+    // Create separator
+    private Separator createSeparator() {
+        Separator separator = new Separator();
+        separator.setStyle("-fx-opacity: 0.3;");
+        return separator;
+    }
+    
+    // Create styled button
+    private Button createStyledButton(String text, String bgColor, String hoverColor) {
+        Button button = new Button(text);
+        button.setPrefSize(120, 40);
+        button.setFont(Font.font("Arial", FontWeight.BOLD, 14));
+        
+        String style = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: bold; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 3, 0, 0, 1); " +
+                "-fx-cursor: hand;", bgColor);
+        
+        button.setStyle(style);
+        
+        button.setOnMouseEntered(e -> 
+            button.setStyle(String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: bold; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2); " +
+                "-fx-cursor: hand;", hoverColor)));
+        
+        button.setOnMouseExited(e -> button.setStyle(style));
+        
+        return button;
     }
+    
     public void show() {
+        stage.setTitle("File Selection");
         stage.setScene(scene);
         stage.show();
     }
diff --git a/src/main/java/com/example/LogManager.java b/src/main/java/com/example/LogManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..5abbef965d984826a962fd2929318a7be176fda0
--- /dev/null
+++ b/src/main/java/com/example/LogManager.java
@@ -0,0 +1,156 @@
+package com.example;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Responsible for handling csv and data conversions
+ */
+public class LogManager {
+    private File impressionLog;
+    private File clickLog;
+    private File serverLog;
+
+    private ArrayList<String[]> impressionData = new ArrayList<>();
+    private ArrayList<String[]> clickData = new ArrayList<>();
+    private ArrayList<String[]> serverData = new ArrayList<>();
+
+    /**
+     * Stores impression csv
+     * @param impressionLog
+     */
+    public void assignImpressionLog(File impressionLog) {
+        this.impressionLog = impressionLog;
+    }
+
+    /**
+     * Stores click csv
+     * @param clickLog
+     */
+    public void assignClickLog(File clickLog) {
+        this.clickLog = clickLog;
+    }
+
+    /**
+     * Stores server csv
+     * @param serverLog
+     */
+    public void assignServerLog(File serverLog){
+        this.serverLog = serverLog;
+    }
+
+    /**
+     * Convert click csv into list
+     */
+    public void convertClickLog() {
+        String line;
+        String comma = ",";
+        boolean headerLine = true;
+
+        try (BufferedReader br = new BufferedReader(new FileReader(this.clickLog))) {
+            while ((line = br.readLine()) != null) {
+                if (headerLine) {
+                    headerLine = false;
+                    continue;
+                }
+                String[] row = line.split(comma);
+                this.clickData.add(row);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Convert server csv into list
+     */
+    public void convertServerLog() {
+        String line;
+        String comma = ",";
+        boolean headerLine = true;
+
+        try (BufferedReader br = new BufferedReader(new FileReader(this.serverLog))) {
+            while ((line = br.readLine()) != null) {
+                if (headerLine) {
+                    headerLine = false;
+                    continue;
+                }
+                String[] row = line.split(comma);
+                this.serverData.add(row);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Convert impression csv into list
+     */
+    public void convertImpressionLog() {
+        String line;
+        String comma = ",";
+        boolean headerLine = true;
+
+        try (BufferedReader br = new BufferedReader(new FileReader(this.impressionLog))) {
+            while ((line = br.readLine()) != null) {
+                if (headerLine) {
+                    headerLine = false;
+                    continue;
+                }
+                String[] row = line.split(comma);
+                this.impressionData.add(row);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    //BELOW HERE ARE ALL GETTER AND PRINTING METHODS
+    public ArrayList<String[]> getImpressionData(){
+        return this.impressionData;
+    }
+
+    public ArrayList<String[]> getClickData(){
+        return this.clickData;
+    }
+
+    public ArrayList<String[]> getServerData(){
+        return this.serverData;
+    }
+
+    public void printImpressionData() {
+        for (String[] row : this.impressionData) {
+            System.out.println(Arrays.toString(row));
+        }
+    }
+
+    public void printClickData() {
+        for (String[] row : this.clickData) {
+            System.out.println(Arrays.toString(row));
+        }
+    }
+
+    public void printServerData() {
+        for (String[] row : this.serverData) {
+            System.out.println(Arrays.toString(row));
+        }
+    }
+
+
+    public File getClickLog() {
+        return clickLog;
+    }
+
+    public File getServerLog() {
+        return serverLog;
+    }
+
+    public File getImpressionLog() {
+        return impressionLog;
+    }
+}
diff --git a/src/main/java/com/example/Login.java b/src/main/java/com/example/Login.java
index 241ae229779c249148880bc8768e511e1f3a609d..a212b438a8e751835b602f6f2349f519516a33c4 100644
--- a/src/main/java/com/example/Login.java
+++ b/src/main/java/com/example/Login.java
@@ -7,65 +7,212 @@ import javafx.scene.control.Button;
 import javafx.scene.control.Label;
 import javafx.scene.control.PasswordField;
 import javafx.scene.control.TextField;
-import javafx.scene.layout.GridPane;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.TextAlignment;
 import javafx.stage.Stage;
 
-import java.awt.*;
-
 public class Login {
+    /**
+     * Reference to primary stage.
+     * UI for login scene.
+     */
     private Stage stage;
     private Scene loginScene;
 
+    /**
+     * Constructors for primary stage + initializes the login class.
+     * @param stage
+     */
     Login(Stage stage) {
         this.stage = stage;
         initialize();
     }
 
+    /**
+     * Initializing the UI component + Layout.
+     */
     private void initialize() {
-        GridPane grid = new GridPane();
-        grid.setAlignment(Pos.CENTER);
-        grid.setHgap(10);
-        grid.setVgap(10);
-        grid.setPadding(new Insets(25, 25, 25, 25));
-
-        Label userNameLabel = new Label("Username:");
-        grid.add(userNameLabel, 0, 0);
-
+        // Create main layout
+        BorderPane mainLayout = new BorderPane();
+        mainLayout.setStyle("-fx-background-color: #f5f5f7;");
+        
+        // Create title section
+        VBox headerBox = new VBox(15);
+        headerBox.setAlignment(Pos.CENTER);
+        headerBox.setPadding(new Insets(40, 0, 30, 0));
+        
+        Label titleLabel = new Label("Ad Auction Dashboard");
+        titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 32));
+        titleLabel.setTextFill(Color.web("#333333"));
+        
+        Label subtitleLabel = new Label("Please login to access the system");
+        subtitleLabel.setFont(Font.font("Arial", 16));
+        subtitleLabel.setTextFill(Color.web("#666666"));
+        
+        headerBox.getChildren().addAll(titleLabel, subtitleLabel);
+        mainLayout.setTop(headerBox);
+        
+        // Create login form
+        VBox loginBox = new VBox(20);
+        loginBox.setAlignment(Pos.CENTER);
+        loginBox.setPadding(new Insets(30, 40, 40, 40));
+        loginBox.setMaxWidth(400);
+        loginBox.setStyle("-fx-background-color: white; " +
+                "-fx-background-radius: 10; " + 
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);");
+        
+        // Username input area
+        VBox usernameBox = new VBox(8);
+        Label userNameLabel = new Label("Username");
+        userNameLabel.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        userNameLabel.setTextFill(Color.web("#333333"));
+        
         TextField userName = new TextField();
-        grid.add(userName, 1, 0);
-
-        Label passwordLabel = new Label("Password:");
-        grid.add(passwordLabel, 0, 1);
-
+        userName.setPromptText("Enter username");
+        userName.setPrefHeight(40);
+        userName.setStyle("-fx-background-radius: 5; " +
+                "-fx-border-radius: 5; " +
+                "-fx-border-color: #e0e0e0; " +
+                "-fx-border-width: 1px; " +
+                "-fx-font-size: 14px; " +
+                "-fx-padding: 8px;");
+        
+        usernameBox.getChildren().addAll(userNameLabel, userName);
+        
+        // Password input area
+        VBox passwordBox = new VBox(8);
+        Label passwordLabel = new Label("Password");
+        passwordLabel.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        passwordLabel.setTextFill(Color.web("#333333"));
+        
         PasswordField passwordField = new PasswordField();
-        grid.add(passwordField, 1, 1);
-
-
-        Button loginButton = new Button("Login");
-        grid.add(loginButton, 1, 2);
-
+        passwordField.setPromptText("Enter password");
+        passwordField.setPrefHeight(40);
+        passwordField.setStyle("-fx-background-radius: 5; " +
+                "-fx-border-radius: 5; " +
+                "-fx-border-color: #e0e0e0; " +
+                "-fx-border-width: 1px; " +
+                "-fx-font-size: 14px; " +
+                "-fx-padding: 8px;");
+        
+        passwordBox.getChildren().addAll(passwordLabel, passwordField);
+        
+        // Message display area
         Label message = new Label();
-        grid.add(message, 1, 3);
-
+        message.setFont(Font.font("Arial", 14));
+        message.setTextAlignment(TextAlignment.CENTER);
+        message.setAlignment(Pos.CENTER);
+        message.setMinHeight(30);
+        
+        // Login button
+        Button loginButton = new Button("Login");
+        loginButton.setPrefSize(320, 45);
+        loginButton.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        
+        String buttonStyle = "-fx-background-color: #4285F4; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: bold; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 3, 0, 0, 1); " +
+                "-fx-cursor: hand;";
+        
+        String buttonHoverStyle = "-fx-background-color: #3367d6; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: bold; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 5, 0, 0, 2); " +
+                "-fx-cursor: hand;";
+        
+        loginButton.setStyle(buttonStyle);
+        loginButton.setOnMouseEntered(e -> loginButton.setStyle(buttonHoverStyle));
+        loginButton.setOnMouseExited(e -> loginButton.setStyle(buttonStyle));
+        
+        // Tip information
+        Label tipLabel = new Label("Tip: Leave username and password empty to login directly");
+        tipLabel.setFont(Font.font("Arial", 12));
+        tipLabel.setTextFill(Color.web("#888888"));
+        tipLabel.setAlignment(Pos.CENTER);
+        tipLabel.setPadding(new Insets(15, 0, 0, 0));
+        
+        // Add all components to login box
+        loginBox.getChildren().addAll(usernameBox, passwordBox, message, loginButton, tipLabel);
+        
+        // Footer copyright information
+        HBox footerBox = new HBox();
+        footerBox.setAlignment(Pos.CENTER);
+        footerBox.setPadding(new Insets(20, 0, 20, 0));
+        
+        Label footerLabel = new Label("© 2023 Ad Auction Dashboard System");
+        footerLabel.setTextFill(Color.web("#999999"));
+        footerLabel.setFont(Font.font("Arial", 12));
+        
+        footerBox.getChildren().add(footerLabel);
+        
+        // Add components to main layout
+        mainLayout.setCenter(loginBox);
+        mainLayout.setBottom(footerBox);
+        
+        // Login button event handler
         loginButton.setOnAction(event -> {
             String username = userName.getText();
             String password = passwordField.getText();
             if (authenticate(username, password)) {
-                message.setText("Login Successful");
+                message.setText("Login successful!");
+                message.setTextFill(Color.web("#4CAF50"));
                 App.getInstance().showInputFilesPage();
             } else {
-                message.setText("Login Failed");
+                message.setText("Login failed!");
+                message.setTextFill(Color.web("#F44336"));
+                // Add slight shake effect
+                loginBox.setStyle(loginBox.getStyle() + "; -fx-effect: dropshadow(gaussian, rgba(244,67,54,0.1), 10, 0, 0, 2);");
+                // Restore after 1 second
+                new Thread(() -> {
+                    try {
+                        Thread.sleep(1000);
+                        javafx.application.Platform.runLater(() -> {
+                            loginBox.setStyle("-fx-background-color: white; " +
+                                    "-fx-background-radius: 10; " + 
+                                    "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);");
+                        });
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                }).start();
             }
         });
 
-        loginScene = new Scene(grid, 600, 400);
+        // Set Enter key to trigger login button
+        passwordField.setOnAction(loginButton.getOnAction());
+        userName.setOnAction(loginButton.getOnAction());
 
+        /**
+         * Creating a scene containing a grid layout.
+         */
+        loginScene = new Scene(mainLayout, 800, 600);
     }
+
+    /**
+     * Method that checks the correct login info.
+     * @param username set to empty.
+     * @param password set to empty.
+     * @return User & Password if true. Otherwise, false.
+     * Kept the login info as empty for the time being.
+     */
     private boolean authenticate(String username, String password) {
-        return "admin".equals(username) && "password".equals(password);
+        return "".equals(username) && "".equals(password);
     }
+
+    /**
+     * Display login scene.
+     */
     public void show(){
         stage.setScene(loginScene);
+        stage.setTitle("Ad Auction Dashboard - Login");
         stage.show();
     }
 }
diff --git a/src/main/java/com/example/MultiChartPage.java b/src/main/java/com/example/MultiChartPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..d2a01f3d6f6104c375f31356cc45c364bd569e75
--- /dev/null
+++ b/src/main/java/com/example/MultiChartPage.java
@@ -0,0 +1,240 @@
+package com.example;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.layout.Region;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.stage.Stage;
+import org.jfree.chart.fx.ChartViewer;
+
+import java.util.ArrayList;
+
+public class MultiChartPage {
+    private Stage stage;
+    private ArrayList<String> currentCharts;
+    private ArrayList<String> timeFlags;
+    private ArrayList<String> genders;
+    private ArrayList<String> incomes;
+    private ArrayList<ArrayList<String>> contexts;
+    private ArrayList<ArrayList<String>> ages;
+
+    private ChartCreator chartCreator;
+    private LogManager logManager;
+
+    // Define style constants
+    private final String BACKGROUND_COLOR = "#f5f5f7";
+    private final String PRIMARY_COLOR = "#4285F4";
+    private final String PRIMARY_DARK_COLOR = "#3367d6";
+    private final String SECTION_BACKGROUND = "white";
+    private final String HEADER_COLOR = "#333333";
+    private final String TEXT_COLOR = "#555555";
+
+    public MultiChartPage(Stage stage, LogManager logManager, ArrayList<String> currentCharts, ArrayList<String> timeFlags,
+                          ArrayList<String> genders, ArrayList<String> incomes, ArrayList<ArrayList<String>> contexts,
+                          ArrayList<ArrayList<String>> ages) {
+        this.stage = stage;
+        this.logManager = logManager;
+        this.chartCreator = new ChartCreator(logManager);
+
+        this.currentCharts = currentCharts;
+        this.timeFlags = timeFlags;
+        this.genders = genders;
+        this.incomes = incomes;
+        this.contexts = contexts;
+        this.ages = ages;
+    }
+
+    public void show() {
+        // Create main layout
+        BorderPane root = new BorderPane();
+        root.setStyle("-fx-background-color: " + BACKGROUND_COLOR + ";");
+        
+        // Create top navigation bar
+        HBox navBar = createNavigationBar();
+        
+        // Create chart area
+        VBox chartSection = createChartSection();
+        
+        // Create bottom edit button area
+        HBox editBar = createEditButtonBar();
+        
+        // Set layout
+        root.setTop(navBar);
+        root.setCenter(chartSection);
+        root.setBottom(editBar);
+        
+        // Set margins
+        BorderPane.setMargin(chartSection, new Insets(20, 20, 20, 20));
+        BorderPane.setMargin(editBar, new Insets(0, 0, 30, 0));
+        
+        Scene scene = new Scene(root, 1300, 800);
+        stage.setScene(scene);
+        stage.setTitle("Ad Auction Dashboard - Multi-Chart View");
+        stage.show();
+    }
+    
+    // Create top navigation bar
+    private HBox createNavigationBar() {
+        HBox navBar = new HBox(15);
+        navBar.setAlignment(Pos.CENTER_LEFT);
+        navBar.setPadding(new Insets(15, 20, 15, 20));
+        navBar.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 5, 0, 0, 2);");
+        
+        Label title = new Label("Multi-Chart Comparison View");
+        title.setFont(Font.font("Arial", FontWeight.BOLD, 18));
+        title.setTextFill(Color.web(HEADER_COLOR));
+        
+        Region spacer = new Region();
+        HBox.setHgrow(spacer, javafx.scene.layout.Priority.ALWAYS);
+        
+        Button backButton = createStyledButton("Back to Charts", "#757575", "#616161");
+        Button overallMetricsButton = createStyledButton("Overall Metrics", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        Button logOutButton = createStyledButton("Logout", "#757575", "#616161");
+        
+        // Set button events
+        backButton.setOnAction(e -> {
+            ChartPage chartPage = new ChartPage(stage, logManager);
+            chartPage.show();
+        });
+
+        overallMetricsButton.setOnAction(e -> {
+            OverallMetricsPage metricsPage = new OverallMetricsPage(stage, logManager);
+            metricsPage.show();
+        });
+
+        logOutButton.setOnAction(e -> {
+            Login login = new Login(stage);
+            login.show();
+        });
+        
+        // Add to navigation bar
+        navBar.getChildren().addAll(title, spacer, backButton, overallMetricsButton, logOutButton);
+        
+        return navBar;
+    }
+    
+    // Create chart area
+    private VBox createChartSection() {
+        VBox chartSection = new VBox(30);
+        chartSection.setAlignment(Pos.CENTER);
+        
+        // Add description text
+        Label descriptionLabel = new Label("Dual Chart View - Compare different metrics or filter conditions simultaneously");
+        descriptionLabel.setFont(Font.font("Arial", 14));
+        descriptionLabel.setTextFill(Color.web("#666666"));
+        
+        // Create chart container
+        HBox chartContainer = new HBox(30);
+        chartContainer.setAlignment(Pos.CENTER);
+        
+        // Create ChartViewer instance for chart 1
+        ChartViewer chartViewer1 = new ChartViewer(chartCreator.updateChart(currentCharts.get(0), timeFlags.get(0), 
+                                    genders.get(0), incomes.get(0), 
+                                    contexts.get(0), ages.get(0)));
+        
+        // Create ChartViewer instance for chart 2
+        ChartViewer chartViewer2 = new ChartViewer(chartCreator.updateChart(currentCharts.get(1), timeFlags.get(1), 
+                                    genders.get(1), incomes.get(1), 
+                                    contexts.get(1), ages.get(1)));
+        
+        // Create first chart area
+        VBox chart1Box = createChartBox("Chart 1", chartViewer1);
+        
+        // Create second chart area
+        VBox chart2Box = createChartBox("Chart 2", chartViewer2);
+        
+        // Add charts to container
+        chartContainer.getChildren().addAll(chart1Box, chart2Box);
+        
+        // Add all elements to chart section
+        chartSection.getChildren().addAll(descriptionLabel, chartContainer);
+        
+        return chartSection;
+    }
+    
+    // Create single chart box
+    private VBox createChartBox(String title, ChartViewer chartViewer) {
+        VBox chartBox = new VBox(10);
+        chartBox.setAlignment(Pos.CENTER);
+        chartBox.setPadding(new Insets(15));
+        chartBox.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                          "-fx-background-radius: 10; " +
+                          "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);");
+        
+        // Chart title
+        Label titleLabel = new Label(title);
+        titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        titleLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        // Set chart size
+        chartViewer.setMinSize(550, 400);
+        chartViewer.setMaxSize(550, 400);
+        
+        chartBox.getChildren().addAll(titleLabel, chartViewer);
+        
+        return chartBox;
+    }
+    
+    // Create bottom edit button area
+    private HBox createEditButtonBar() {
+        HBox editBar = new HBox(20);
+        editBar.setAlignment(Pos.CENTER);
+        
+        Button editChart1Button = createStyledButton("Edit Chart 1", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        Button editChart2Button = createStyledButton("Edit Chart 2", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        
+        // Set button events
+        editChart1Button.setOnAction(e -> {
+            EditPage1 editPage = new EditPage1(stage, logManager, currentCharts, timeFlags, genders, incomes, contexts, ages);
+            editPage.show();
+        });
+        
+        editChart2Button.setOnAction(e -> {
+            EditPage2 editPage2 = new EditPage2(stage, logManager, currentCharts, timeFlags, genders, incomes, contexts, ages);
+            editPage2.show();
+        });
+        
+        editBar.getChildren().addAll(editChart1Button, editChart2Button);
+        
+        return editBar;
+    }
+    
+    // Create styled button
+    private Button createStyledButton(String text, String bgColor, String hoverColor) {
+        Button button = new Button(text);
+        button.setPrefSize(120, 40);
+        button.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        
+        String style = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 2, 0, 0, 1); " +
+                "-fx-cursor: hand;", bgColor);
+        
+        String hoverStyle = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 3, 0, 0, 2); " +
+                "-fx-cursor: hand;", hoverColor);
+        
+        button.setStyle(style);
+        
+        button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
+        button.setOnMouseExited(e -> button.setStyle(style));
+        
+        return button;
+    }
+}
diff --git a/src/main/java/com/example/OverallMetricsCalculator.java b/src/main/java/com/example/OverallMetricsCalculator.java
new file mode 100644
index 0000000000000000000000000000000000000000..b00a08046b2cf52240edc7c8f5f35b545c8478c2
--- /dev/null
+++ b/src/main/java/com/example/OverallMetricsCalculator.java
@@ -0,0 +1,162 @@
+package com.example;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+
+/**
+ * Does all calculations for overall metric values
+ */
+public class OverallMetricsCalculator {
+
+    /**
+     * Calculate total impressions for campaign
+     * @param impressionData
+     * @return
+     */
+    public int calcImpressions (ArrayList<String[]> impressionData) {
+        int impressions = 0;
+        for (String[] impression : impressionData){
+            impressions += 1;
+        }
+        return impressions;
+    }
+
+    /**
+     * Calculate total clicks for campaign
+     * @param clickData
+     * @return
+     */
+    public int calcClicks (ArrayList<String[]> clickData) {
+        int clicks = 0;
+        for (String[] click : clickData){
+            clicks += 1;
+        }
+        return clicks;
+    }
+
+    /**
+     * Calculate total unique clicks for campaign
+     * @param clickData
+     * @return
+     */
+    public int calcUniques (ArrayList<String[]> clickData) {
+        int uniques;
+        HashSet<String> uniqueID = new HashSet<String>();
+        for (String[] click : clickData) {
+            uniqueID.add(click[1]);
+        }
+        uniques = uniqueID.size();
+        return uniques;
+    }
+
+    /**
+     * Calculate total bounces for campaign
+     * @param serverData
+     * @return
+     */
+    public int calcBounces (ArrayList<String[]> serverData) {
+        int bounces = 0;
+        for (String[] interaction : serverData) {
+            if (interaction[3].equals("1")) {
+                bounces += 1;
+            }
+        }
+        return bounces;
+    }
+
+    /**
+     * Calculate total conversions for campaign
+     * @param serverData
+     * @return
+     */
+    public int calcConversions (ArrayList<String[]> serverData) {
+        int conversions = 0;
+        for (String[] interaction : serverData) {
+            if (interaction[4].equals("Yes")) {
+                conversions += 1;
+            }
+        }
+        return conversions;
+    }
+
+    /**
+     * Calculates total cost for campaign
+     * @param clickData
+     * @param impressionData
+     * @return
+     */
+    public float calcCost (ArrayList<String[]> clickData, ArrayList<String[]> impressionData) {
+        float totalCost = 0;
+        for (String[] click : clickData) {
+            totalCost += Float.parseFloat(click[2]);
+        }
+        for (String[] impression : impressionData) {
+            totalCost += Float.parseFloat(impression[6]);
+        }
+        return totalCost;
+    }
+
+    /**
+     * Returns number of clicks per impression for campaign
+     * @param clickData
+     * @param impressionData
+     * @return
+     */
+    public float calcCTR (ArrayList<String[]> clickData, ArrayList<String[]> impressionData) {
+        int clicks = this.calcClicks(clickData);
+        int impressions = this.calcImpressions(impressionData);
+        return ( (float) clicks/impressions);
+    }
+
+    /**
+     * Calculate cost per conversion for campaign
+     * @param clickData
+     * @param impressionData
+     * @param serverData
+     * @return
+     */
+    public float calcCPA(ArrayList<String[]> clickData, ArrayList<String[]> impressionData, ArrayList<String[]> serverData){
+        int conversions = calcConversions(serverData);
+        float cost = calcCost(clickData,impressionData);
+        return(cost/conversions);
+    }
+
+    /**
+     * Calculate cost per click for campaign
+     * @param clickData
+     * @param impressionData
+     * @return
+     */
+    public float calcCPC(ArrayList<String[]> clickData, ArrayList<String[]> impressionData, ArrayList<String[]> serverData) {
+        int clicks = calcClicks(clickData);
+        float cost = calcCost(clickData,impressionData);
+        return (cost/clicks);
+    }
+
+    /**
+     * Calculate cost per thousand impressions for campaign
+     * @param clickData
+     * @param impressionData
+     * @return
+     */
+    public float calcCPM(ArrayList<String[]> clickData, ArrayList<String[]> impressionData) {
+        float cost = calcCost(clickData,impressionData);
+        float thousandImpressions = (float) this.calcImpressions(impressionData)/1000;
+        return(cost/thousandImpressions);
+    }
+
+
+    /**
+     * Calculate bounce rate for campaign
+     * @param clickData
+     * @param serverData
+     * @return
+     */
+    public float calcBounceRate(ArrayList<String[]> clickData, ArrayList<String[]> serverData){
+        int clicks = this.calcClicks(clickData);
+        int bounces = this.calcBounces(serverData);
+        return ((float) clicks/bounces);
+    }
+
+}
diff --git a/src/main/java/com/example/OverallMetricsPage.java b/src/main/java/com/example/OverallMetricsPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..afa99ec56d1c65008a24908c1f6e94636614ba50
--- /dev/null
+++ b/src/main/java/com/example/OverallMetricsPage.java
@@ -0,0 +1,274 @@
+package com.example;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.Separator;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.layout.Region;
+import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
+import javafx.scene.text.FontWeight;
+import javafx.scene.text.TextAlignment;
+import javafx.stage.Stage;
+
+import java.util.ArrayList;
+
+
+public class OverallMetricsPage {
+    private Stage stage;
+    private Scene scene;
+
+    public LogManager logManager;
+    private ArrayList<String[]> clickData;
+    private ArrayList<String[]> impressionData;
+    private ArrayList<String[]> serverData;
+    private OverallMetricsCalculator metricsCalculator = new OverallMetricsCalculator();
+
+    // Define style constants
+    private final String BACKGROUND_COLOR = "#f5f5f7";
+    private final String PRIMARY_COLOR = "#4285F4";
+    private final String PRIMARY_DARK_COLOR = "#3367d6";
+    private final String SECTION_BACKGROUND = "white";
+    private final String HEADER_COLOR = "#333333";
+    private final String TEXT_COLOR = "#555555";
+    private final String ERROR_COLOR = "#F44336";
+    private final String SUCCESS_COLOR = "#4CAF50";
+
+    OverallMetricsPage(Stage stage, LogManager logManager) {
+        this.stage = stage;
+        this.logManager = logManager;
+        this.clickData = logManager.getClickData();
+        this.impressionData = logManager.getImpressionData();
+        this.serverData = logManager.getServerData();
+        initialize();
+    }
+
+    private void initialize() {
+        // Create main layout
+        BorderPane root = new BorderPane();
+        root.setStyle("-fx-background-color: " + BACKGROUND_COLOR + ";");
+        
+        // Create top title bar
+        HBox topBar = createTopBar();
+        
+        // Create central content area
+        VBox contentBox = createContentBox();
+        
+        // Create bottom button area
+        HBox bottomBar = createBottomBar();
+        
+        // Set layout
+        root.setTop(topBar);
+        root.setCenter(contentBox);
+        root.setBottom(bottomBar);
+        
+        // Set margins
+        BorderPane.setMargin(contentBox, new Insets(20, 30, 20, 30));
+        BorderPane.setMargin(bottomBar, new Insets(0, 0, 20, 0));
+        
+        // Create scene
+        scene = new Scene(root, 600, 650);
+    }
+    
+    private HBox createTopBar() {
+        HBox topBar = new HBox();
+        topBar.setAlignment(Pos.CENTER);
+        topBar.setPadding(new Insets(20, 0, 10, 0));
+        
+        Label titleLabel = new Label("Overall Ad Campaign Metrics");
+        titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 24));
+        titleLabel.setTextFill(Color.web(HEADER_COLOR));
+        
+        topBar.getChildren().add(titleLabel);
+        
+        return topBar;
+    }
+    
+    private VBox createContentBox() {
+        VBox contentBox = new VBox(15);
+        contentBox.setAlignment(Pos.TOP_CENTER);
+        contentBox.setPadding(new Insets(30, 40, 30, 40));
+        contentBox.setMaxWidth(540);
+        contentBox.setStyle("-fx-background-color: " + SECTION_BACKGROUND + "; " +
+                "-fx-background-radius: 10; " + 
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.1), 10, 0, 0, 2);");
+        
+        // Add description text
+        Label descriptionLabel = new Label("Below are the overall ad campaign metrics calculated from uploaded data files");
+        descriptionLabel.setFont(Font.font("Arial", 14));
+        descriptionLabel.setTextFill(Color.web("#666666"));
+        descriptionLabel.setWrapText(true);
+        descriptionLabel.setTextAlignment(TextAlignment.CENTER);
+        
+        Separator separator = new Separator();
+        separator.setOpacity(0.3);
+        separator.setPadding(new Insets(10, 0, 10, 0));
+        
+        // Create metrics grid
+        GridPane metricsGrid = new GridPane();
+        metricsGrid.setHgap(20);
+        metricsGrid.setVgap(15);
+        metricsGrid.setAlignment(Pos.CENTER);
+        
+        // Calculate all metric values
+        int impressionsValue = metricsCalculator.calcImpressions(impressionData);
+        int clicksValue = metricsCalculator.calcClicks(clickData);
+        int uniquesValue = metricsCalculator.calcUniques(clickData);
+        int bouncesValue = metricsCalculator.calcBounces(serverData);
+        int conversionsValue = metricsCalculator.calcConversions(serverData);
+        float costValue = metricsCalculator.calcCost(clickData, impressionData);
+        float ctrValue = metricsCalculator.calcCTR(clickData, impressionData);
+        float cpaValue = metricsCalculator.calcCPA(clickData, impressionData, serverData);
+        float cpcValue = metricsCalculator.calcCPC(clickData, impressionData, serverData);
+        float cpmValue = metricsCalculator.calcCPM(clickData, impressionData);
+        float bounceRateValue = metricsCalculator.calcBounceRate(clickData, serverData);
+        
+        // First column: Basic quantitative metrics
+        Label basicMetricsTitle = new Label("Basic Quantitative Metrics");
+        basicMetricsTitle.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        basicMetricsTitle.setTextFill(Color.web(HEADER_COLOR));
+        
+        VBox basicMetricsBox = new VBox(12);
+        basicMetricsBox.getChildren().addAll(
+            basicMetricsTitle,
+            createMetricItem("Total Impressions", impressionsValue + "", false),
+            createMetricItem("Total Clicks", clicksValue + "", false),
+            createMetricItem("Unique Visitors", uniquesValue + "", false),
+            createMetricItem("Bounces", bouncesValue + "", false),
+            createMetricItem("Conversions", conversionsValue + "", false),
+            createMetricItem("Total Cost", String.format("%.2f", costValue) + " ¥", false)
+        );
+        
+        // Second column: Ratio metrics
+        Label ratioMetricsTitle = new Label("Ratio and Performance Metrics");
+        ratioMetricsTitle.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        ratioMetricsTitle.setTextFill(Color.web(HEADER_COLOR));
+        
+        VBox ratioMetricsBox = new VBox(12);
+        ratioMetricsBox.getChildren().addAll(
+            ratioMetricsTitle,
+            createMetricItem("Click-Through Rate (CTR)", formatPercentage(ctrValue), true),
+            createMetricItem("Cost Per Acquisition (CPA)", String.format("%.2f", cpaValue) + " ¥", true),
+            createMetricItem("Cost Per Click (CPC)", String.format("%.2f", cpcValue) + " ¥", true),
+            createMetricItem("Cost Per Mille (CPM)", String.format("%.2f", cpmValue) + " ¥", true),
+            createMetricItem("Bounce Rate", formatPercentage(bounceRateValue), true)
+        );
+        
+        // Add to metrics grid
+        metricsGrid.add(basicMetricsBox, 0, 0);
+        metricsGrid.add(ratioMetricsBox, 1, 0);
+        
+        // Add all components to content box
+        contentBox.getChildren().addAll(
+            descriptionLabel,
+            separator,
+            metricsGrid
+        );
+        
+        return contentBox;
+    }
+    
+    private HBox createBottomBar() {
+        HBox bottomBar = new HBox(15);
+        bottomBar.setAlignment(Pos.CENTER);
+        
+        Button backButton = createStyledButton("Back to Charts", PRIMARY_COLOR, PRIMARY_DARK_COLOR);
+        Button logoutButton = createStyledButton("Logout", "#757575", "#616161");
+        
+        // Button events
+        backButton.setOnAction(e -> {
+            ChartPage chartPage = new ChartPage(stage, logManager);
+            chartPage.show();
+        });
+        
+        logoutButton.setOnAction(e -> {
+            System.out.println("Logout Button clicked");
+            Login login = new Login(stage);
+            login.show();
+        });
+        
+        bottomBar.getChildren().addAll(backButton, logoutButton);
+        
+        return bottomBar;
+    }
+    
+    // Create metric item
+    private HBox createMetricItem(String label, String value, boolean isRatio) {
+        HBox item = new HBox(10);
+        item.setAlignment(Pos.CENTER_LEFT);
+        
+        Label metricLabel = new Label(label + ":");
+        metricLabel.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        metricLabel.setTextFill(Color.web(TEXT_COLOR));
+        metricLabel.setMinWidth(150);
+        
+        Label valueLabel = new Label(value);
+        valueLabel.setFont(Font.font("Arial", FontWeight.BOLD, 16));
+        
+        // Set text color based on whether it's a ratio metric
+        if (isRatio) {
+            // If value contains NaN, display in red
+            if (value.contains("NaN")) {
+                valueLabel.setTextFill(Color.web(ERROR_COLOR));
+            } else {
+                valueLabel.setTextFill(Color.web(PRIMARY_COLOR));
+            }
+        } else {
+            valueLabel.setTextFill(Color.web(HEADER_COLOR));
+        }
+        
+        item.getChildren().addAll(metricLabel, valueLabel);
+        
+        return item;
+    }
+    
+    // Create styled button
+    private Button createStyledButton(String text, String bgColor, String hoverColor) {
+        Button button = new Button(text);
+        button.setPrefSize(120, 40);
+        button.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
+        
+        String style = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.2), 2, 0, 0, 1); " +
+                "-fx-cursor: hand;", bgColor);
+        
+        String hoverStyle = String.format(
+                "-fx-background-color: %s; " +
+                "-fx-text-fill: white; " +
+                "-fx-font-weight: normal; " +
+                "-fx-background-radius: 5; " +
+                "-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 3, 0, 0, 2); " +
+                "-fx-cursor: hand;", hoverColor);
+        
+        button.setStyle(style);
+        
+        button.setOnMouseEntered(e -> button.setStyle(hoverStyle));
+        button.setOnMouseExited(e -> button.setStyle(style));
+        
+        return button;
+    }
+    
+    // Format percentage display
+    private String formatPercentage(float value) {
+        if (Float.isNaN(value)) {
+            return "NaN";
+        }
+        return String.format("%.2f%%", value * 100);
+    }
+
+    public void show() {
+        stage.setScene(scene);
+        stage.setTitle("Ad Auction Dashboard - Overall Metrics");
+        stage.show();
+    }
+}
diff --git a/src/main/java/com/example/ServerLog.java b/src/main/java/com/example/ServerLog.java
deleted file mode 100644
index 44b2f76e5e5faf5a9928582bfe637d11ee91adb5..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/ServerLog.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.example;
-
-import java.util.ArrayList;
-
-public class ServerLog {
-
-    private String filepath;
-
-    private ArrayList<ServerLogRecord> records;
-
-    public ServerLog(String filepath) {
-        this.filepath = filepath;
-        this.records = new ArrayList<>();
-        this.loadLogFile(filepath);
-    }
-
-    private void loadLogFile(String filename) {
-        ArrayList<String[]> data = Utils.readCSV(filename);
-        System.out.println("CSV Loaded, size: " + data.size());
-        for (int i = 1; i < data.size(); i++) {
-            String[] elements = data.get(i);
-            System.out.println("Parsing row: " + String.join("|", elements));
-            try {
-                this.records.add(new ServerLogRecord(
-                        elements[0], elements[1], elements[2],
-                        Integer.parseInt(elements[3]),
-                        elements[4].equalsIgnoreCase("yes")
-                ));
-            } catch (Exception e) {
-                System.err.println("Error parsing row: " + String.join("|", elements));
-                e.printStackTrace();
-            }
-        }
-    }
-
-
-    public int size() {
-        return this.records.size();
-    }
-
-    public ServerLogRecord getRecordAt(int index) {
-        return this.records.get(index);
-    }
-
-    public int getNumberOfBounces() {
-        int total = 0;
-        for (ServerLogRecord record: this.records) {
-            total += record.browseTime() < 120 || record.getPagesViewed() == 1 ? 1 : 0;
-        }
-        return total;
-    }
-
-    public int getNumberOfConversions() {
-        int total = 0;
-        for (ServerLogRecord record: this.records) {
-            total += record.isConversion() ? 1 : 0;
-        }
-        return total;
-    }
-
-    public static void main(String[] args) {
-        ServerLog serverLog = new ServerLog("server_log.csv");
-        System.out.println("Bounces: " + serverLog.getNumberOfBounces());
-        System.out.println("Conversions: " + serverLog.getNumberOfConversions());
-        System.out.println("Total Records: " + serverLog.size());
-    }
-
-
-}
diff --git a/src/main/java/com/example/ServerLogRecord.java b/src/main/java/com/example/ServerLogRecord.java
deleted file mode 100644
index b49af3eb6d46a045f0f4f92e10303f9745a238bf..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/ServerLogRecord.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.example;
-
-import java.time.Duration;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-
-public class ServerLogRecord {
-
-    final private static String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
-
-    private LocalDateTime entryDate;
-    private String Id;
-    private LocalDateTime exitDate;
-    private int pagesViewed;
-    private boolean conversion;
-
-    public ServerLogRecord(String entryDate,
-                           String Id,
-                           String exitDate,
-                           int pagesViewed,
-                           boolean conversion) {
-        if (!entryDate.equalsIgnoreCase("n/a")) {
-            this.entryDate = LocalDateTime.parse(entryDate, DateTimeFormatter.ofPattern(DATE_PATTERN));
-        }
-        this.Id = Id;
-        if (!exitDate.equalsIgnoreCase("n/a")) {
-            this.exitDate = LocalDateTime.parse(exitDate, DateTimeFormatter.ofPattern(DATE_PATTERN));
-        }
-        this.pagesViewed = pagesViewed;
-        this.conversion = conversion;
-    }
-
-    public LocalDateTime getEntryDate() {
-        return entryDate;
-    }
-
-    public String getId() {
-        return Id;
-    }
-
-    public LocalDateTime getExitDate() {
-        return exitDate;
-    }
-
-    public int getPagesViewed() {
-        return pagesViewed;
-    }
-
-    public boolean isConversion() {
-        return conversion;
-    }
-
-    public long browseTime() {
-        if (this.entryDate == null || this.exitDate == null) {
-            return 0;
-        } else {
-            Duration interval = Duration.between(this.entryDate, this.exitDate);
-            return interval.toSeconds();
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ServerLogRecord{" +
-                "entryDate=" + entryDate +
-                ", Id='" + Id + '\'' +
-                ", exitDate=" + exitDate +
-                ", pagesViewed=" + pagesViewed +
-                ", conversion=" + conversion +
-                '}';
-    }
-}
diff --git a/src/main/java/com/example/TestClickLog.java b/src/main/java/com/example/TestClickLog.java
deleted file mode 100644
index db0474e24164087c420103c4f38948922a27cfbe..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/TestClickLog.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.example;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.List;
-
-public class TestClickLog {
-    public static void main(String[] args) {
-        ClickLogReader reader = new ClickLogReader();
-        List<Click> clicks = reader.readCSV("clicks_log.csv");
-
-        if (!clicks.isEmpty()) {
-            System.out.println("CSV Loaded! Total Rows: " + clicks.size());
-
-            // Save all impressions to a file
-            try (FileWriter writer = new FileWriter("clicks_output.txt")) {
-                for (Click click : clicks) {
-                    writer.write(click.toString() + "\n");
-                }
-                System.out.println("All clicks saved to `clicks_output.txt`.");
-            } catch (IOException e) {
-                e.printStackTrace();
-                System.out.println("Failed to save data to file.");
-            }
-
-        } else {
-            System.out.println("No data found!");
-        }
-    }
-}
diff --git a/src/main/java/com/example/TestImpressionLog.java b/src/main/java/com/example/TestImpressionLog.java
deleted file mode 100644
index 4e2b71caee19309e82fa28cc47c9a5146d2c2ec3..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/TestImpressionLog.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.example;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.List;
-
-public class TestImpressionLog {
-  public static void main(String[] args) {
-    ImpressionLogReader reader = new ImpressionLogReader();
-    List<Impression> impressions = reader.readCSV("impression_log.csv");
-
-    if (!impressions.isEmpty()) {
-      System.out.println("CSV Loaded! Total Rows: " + impressions.size());
-
-      // Save all impressions to a file
-      try (FileWriter writer = new FileWriter("impressions_output.txt")) {
-        for (Impression impression : impressions) {
-          writer.write(impression.toString() + "\n");
-        }
-        System.out.println("All impressions saved to `impressions_output.txt`.");
-      } catch (IOException e) {
-        e.printStackTrace();
-        System.out.println("Failed to save data to file.");
-      }
-
-    } else {
-      System.out.println("No data found!");
-    }
-  }
-}
diff --git a/src/main/java/com/example/Utils.java b/src/main/java/com/example/Utils.java
deleted file mode 100644
index 084c7a957b3963bb2f2126c290ffcb5311990347..0000000000000000000000000000000000000000
--- a/src/main/java/com/example/Utils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.example;
-
-import java.util.ArrayList;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-public class Utils {
-
-
-    public static ArrayList<String[]> readCSV(String filename) {
-        ArrayList<String[]> result = new ArrayList<>();
-        try {
-            InputStream inputStream = Utils.class.getClassLoader().getResourceAsStream(filename);
-            if (inputStream == null) {
-                throw new IllegalArgumentException("File not found: " + filename);
-            }
-
-            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
-            String line;
-            while ((line = reader.readLine()) != null) {
-                line = line.strip();
-                if (!line.isEmpty()) {
-                    result.add(line.split(","));
-                }
-            }
-            reader.close();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return result;
-    }
-}
\ No newline at end of file