diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts
index 454654e8e774617de4ef68b5e99f9e15a8b1918c..207900198b7094596015f5efc85a30b0b6881e29 100644
--- a/api/src/engine/connectors/datashield/main.connector.ts
+++ b/api/src/engine/connectors/datashield/main.connector.ts
@@ -27,7 +27,7 @@ import { ListExperiments } from 'src/engine/models/experiment/list-experiments.m
 import { RawResult } from 'src/engine/models/result/raw-result.model';
 import {
   TableResult,
-  ThemeType,
+  TableStyle,
 } from 'src/engine/models/result/table-result.model';
 import { User } from 'src/users/models/user.model';
 import {
@@ -141,7 +141,7 @@ export default class DataShieldService implements IEngineService {
     const table = transformToTable.evaluate(data);
     return {
       ...table,
-      theme: ThemeType.NORMAL,
+      tableStyle: TableStyle.NORMAL,
     };
   }
 
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts b/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts
index 9aa0115d8daa56a9ab36233472c86aa1c48025b9..f390eea800eb08fb341b1ee4b6e7158791855702 100644
--- a/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/PCA.handler.spec.ts
@@ -1,7 +1,7 @@
 import { Experiment } from '../../../../models/experiment/experiment.model';
 import { HeatMapResult } from '../../../../models/result/heat-map-result.model';
 import handlers from '..';
-import { BarChartResult } from 'src/engine/models/result/bar-chart-result.model';
+import { BarChartResult } from '../../../../models/result/bar-chart-result.model';
 
 const createExperiment = (): Experiment => ({
   id: 'dummy-id',
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4cd6dcf6a9f3cd8c1d837b8a46b4d310842b874
--- /dev/null
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.spec.ts
@@ -0,0 +1,159 @@
+import handlers from '..';
+import { Experiment } from '../../../../models/experiment/experiment.model';
+import AnovaOneWayHandler from './anova-one-way.handler';
+
+const createExperiment = (): Experiment => ({
+  id: 'dummy-id',
+  name: 'Testing purpose',
+  algorithm: {
+    id: 'Anova_OnEway',
+  },
+  datasets: ['desd-synthdata'],
+  domain: 'dementia',
+  variables: ['rightcerebralwhitematter'],
+  coVariables: ['ppmicategory'],
+  results: [],
+});
+
+describe('Anova oneway result handler', () => {
+  const anovaHandler = new AnovaOneWayHandler();
+  const data = {
+    x_label: 'Variable X',
+    y_label: 'Variable Y',
+    df_residual: 1424.0,
+    df_explained: 3.0,
+    ss_residual: 1941.1517872154072,
+    ss_explained: 23.52938815624377,
+    ms_residual: 1.3631683898984601,
+    ms_explained: 7.843129385414589,
+    p_value: 0.0006542139533101455,
+    f_stat: 5.753602741623733,
+    tuckey_test: [
+      {
+        groupA: 'GENPD',
+        groupB: 'HC',
+        meanA: 10.200898765432095,
+        meanB: 10.50253333333334,
+        diff: -0.3016345679012442,
+        se: 0.11017769051976001,
+        t_stat: -2.737710025308137,
+        p_tuckey: 0.03178790563153744,
+      },
+      {
+        groupA: 'GENPD',
+        groupB: 'PD',
+        meanA: 10.200898765432095,
+        meanB: 10.530083456790125,
+        diff: -0.3291846913580301,
+        se: 0.10048653456497285,
+        t_stat: -3.2759084864767125,
+        p_tuckey: 0.005936908999390811,
+      },
+      {
+        groupA: 'GENPD',
+        groupB: 'PRODROMA',
+        meanA: 10.200898765432095,
+        meanB: 10.161453333333334,
+        diff: 0.039445432098760946,
+        se: 0.1534957169892615,
+        t_stat: 0.2569806693793321,
+        p_tuckey: 0.9,
+      },
+      {
+        groupA: 'HC',
+        groupB: 'PD',
+        meanA: 10.50253333333334,
+        meanB: 10.530083456790125,
+        diff: -0.02755012345678587,
+        se: 0.07353521425604895,
+        t_stat: -0.37465211375949203,
+        p_tuckey: 0.9,
+      },
+      {
+        groupA: 'HC',
+        groupB: 'PRODROMA',
+        meanA: 10.50253333333334,
+        meanB: 10.161453333333334,
+        diff: 0.34108000000000516,
+        se: 0.13737110045731235,
+        t_stat: 2.4829094246500176,
+        p_tuckey: 0.0630887851749381,
+      },
+      {
+        groupA: 'PD',
+        groupB: 'PRODROMA',
+        meanA: 10.530083456790125,
+        meanB: 10.161453333333334,
+        diff: 0.368630123456791,
+        se: 0.1297275582960786,
+        t_stat: 2.8415714309172655,
+        p_tuckey: 0.02355122851783331,
+      },
+    ],
+    min_per_group: [
+      {
+        GENPD: 7.2276,
+        HC: 7.2107,
+        PD: 7.0258,
+        PRODROMA: 6.3771,
+      },
+    ],
+    max_per_group: [
+      {
+        GENPD: 13.7312,
+        HC: 14.52,
+        PD: 14.4812,
+        PRODROMA: 12.3572,
+      },
+    ],
+    ci_info: {
+      sample_stds: {
+        GENPD: 1.2338388511229372,
+        HC: 1.1276421260632183,
+        PD: 1.16245855322075,
+        PRODROMA: 1.197046185656396,
+      },
+      means: {
+        GENPD: 10.200898765432095,
+        HC: 10.50253333333334,
+        PD: 10.530083456790125,
+        PRODROMA: 10.161453333333334,
+      },
+      'm-s': {
+        GENPD: 8.967059914309157,
+        HC: 9.374891207270121,
+        PD: 9.367624903569375,
+        PRODROMA: 8.964407147676939,
+      },
+      'm+s': {
+        GENPD: 11.434737616555033,
+        HC: 11.630175459396558,
+        PD: 11.692542010010875,
+        PRODROMA: 11.35849951898973,
+      },
+    },
+  };
+
+  it('Test anova 1 way handler', () => {
+    const exp = createExperiment();
+    const table1 = anovaHandler.getSummaryTable(data, exp.coVariables[0]);
+    const table2 = anovaHandler.getTuckeyTable(data);
+    const meanPlot = anovaHandler.getMeanPlot(data);
+
+    handlers(exp, data);
+
+    expect(exp.results.length).toBeGreaterThanOrEqual(3);
+    expect(exp.results).toContainEqual(table1);
+    expect(exp.results).toContainEqual(table2);
+    expect(exp.results).toContainEqual(meanPlot);
+
+    expect(table1.data[0].length).toEqual(6);
+    expect(table2.headers.length).toEqual(8);
+    expect(table2.data).toBeTruthy();
+
+    expect(meanPlot.pointCIs.length).toBeGreaterThan(1);
+    expect(meanPlot.name).toEqual(
+      `Mean Plot: ${data.y_label} ~ ${data.x_label}`,
+    );
+  });
+});
diff --git a/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c8d9a6750785d57df2f2637572d306cd313935ee
--- /dev/null
+++ b/api/src/engine/connectors/exareme/handlers/algorithms/anova-one-way.handler.ts
@@ -0,0 +1,114 @@
+import * as jsonata from 'jsonata'; // old import style needed due to 'export = jsonata'
+import { MeanChartResult } from 'src/engine/models/result/means-chart-result.model';
+import { Experiment } from '../../../../models/experiment/experiment.model';
+import {
+  TableResult,
+  TableStyle,
+} from '../../../../models/result/table-result.model';
+import BaseHandler from '../base.handler';
+
+export default class AnovaOneWayHandler extends BaseHandler {
+  private static readonly tuckeyTransform = jsonata(`
+    {
+        "name": 'Tuckey Honest Significant Differences',
+        "headers": [
+            {"name": 'A', "type": 'string'},
+            {"name": 'B', "type": 'string'},
+            {"name": 'Mean A', "type": 'string'},
+            {"name": 'Mean B', "type": 'string'},
+            {"name": 'Diff', "type": 'string'},
+            {"name": 'Standard error', "type": 'string'},
+            {"name": 'T value', "type": 'string'},
+            {"name": 'P value', "type": 'string'}     
+        ],
+        "data": tuckey_test.[$.groupA, $.groupB, $.meanA, $.meanB, $.diff, $.se, $.t_stat, $.p_tuckey]
+    }
+  `);
+
+  private static readonly meanPlotTransform = jsonata(`
+  (
+    $cats:= $keys(ci_info.means);
+    {
+    "name": "Mean Plot: " & y_label & ' ~ ' & x_label,
+    "xAxis": {
+        "label": x_label,
+        "categories": $cats
+    },
+    "yAxis": {
+        "label": '95% CI: ' & y_label
+    },
+    "pointCIs": $cats.[{
+        "min": $lookup($$.ci_info.'m-s', $),
+        "mean": $lookup($$.ci_info.means, $),
+        "max": $lookup($$.ci_info.'m+s', $)
+    }]
+  })
+  `);
+
+  canHandle(algorithm: string): boolean {
+    return algorithm.toLocaleLowerCase() === 'anova_oneway';
+  }
+
+  getTuckeyTable(data: unknown): TableResult | undefined {
+    const tableData = AnovaOneWayHandler.tuckeyTransform.evaluate(data);
+
+    if (!tableData) return undefined;
+
+    const tableResult: TableResult = {
+      ...tableData,
+      tableStyle: TableStyle.NORMAL,
+    } as unknown as TableResult;
+
+    return tableResult;
+  }
+
+  getSummaryTable(data: unknown, varname: string): TableResult | undefined {
+    const tableSummary: TableResult = {
+      name: 'Annova summary',
+      tableStyle: TableStyle.NORMAL,
+      headers: ['', 'DF', 'SS', 'MS', 'F ratio', 'P value'].map((name) => ({
+        name,
+        type: 'string',
+      })),
+      data: [
+        [
+          varname,
+          data['df_explained'],
+          data['ss_explained'],
+          data['ms_explained'],
+          data['p_value'],
+          data['f_stat'],
+        ],
+        [
+          'Residual',
+          data['df_residual'],
+          data['ss_residual'],
+          data['ms_residual'],
+          '',
+          '',
+        ],
+      ],
+    };
+
+    return tableSummary;
+  }
+
+  getMeanPlot(data: unknown): MeanChartResult {
+    return AnovaOneWayHandler.meanPlotTransform.evaluate(data);
+  }
+
+  handle(exp: Experiment, data: unknown): void {
+    if (!this.canHandle(exp.algorithm.id)) return super.handle(exp, data);
+
+    const summaryTable = this.getSummaryTable(data, exp.coVariables[0]);
+    if (summaryTable) exp.results.push(summaryTable);
+
+    const tuckeyTable = this.getTuckeyTable(data);
+    if (tuckeyTable) exp.results.push(tuckeyTable);
+
+    const meanPlot = this.getMeanPlot(data);
+    if (meanPlot && meanPlot.pointCIs) exp.results.push(meanPlot);
+
+    super.handle(exp, data); // continue request
+  }
+}
diff --git a/api/src/engine/connectors/exareme/handlers/index.ts b/api/src/engine/connectors/exareme/handlers/index.ts
index f9c6c47a8a5dd4dd9b12a817fe77054baf9e85d5..2d7d607d5dac7ebc553536c30f1a3b4c2acd6514 100644
--- a/api/src/engine/connectors/exareme/handlers/index.ts
+++ b/api/src/engine/connectors/exareme/handlers/index.ts
@@ -1,4 +1,5 @@
 import { Experiment } from '../../../../engine/models/experiment/experiment.model';
+import AnovaOneWayHandler from './algorithms/anova-one-way.handler';
 import AreaHandler from './algorithms/area.handler';
 import DescriptiveHandler from './algorithms/descriptive.handler';
 import HeatMapHandler from './algorithms/heat-map.handler';
@@ -12,6 +13,7 @@ start
   .setNext(new AreaHandler())
   .setNext(new DescriptiveHandler())
   .setNext(new HeatMapHandler())
+  .setNext(new AnovaOneWayHandler())
   .setNext(new PCAHandler())
   .setNext(new RawHandler()); // should be last handler as it works as a fallback (if other handlers could not process the results)
 
diff --git a/api/src/engine/models/result/common/result-union.model.ts b/api/src/engine/models/result/common/result-union.model.ts
index 5c2ffc69597c6b1afc39ea624972586285d6d3e4..0e385962665d0ad0708c84b4597273b4678f55d8 100644
--- a/api/src/engine/models/result/common/result-union.model.ts
+++ b/api/src/engine/models/result/common/result-union.model.ts
@@ -1,10 +1,11 @@
 import { createUnionType } from '@nestjs/graphql';
-import { BarChartResult } from '../bar-chart-result.model';
 import { GroupsResult } from '../groups-result.model';
 import { HeatMapResult } from '../heat-map-result.model';
 import { LineChartResult } from '../line-chart-result.model';
 import { RawResult } from '../raw-result.model';
 import { TableResult } from '../table-result.model';
+import { BarChartResult } from '../bar-chart-result.model';
+import { MeanChartResult } from '../means-chart-result.model';
 
 export const ResultUnion = createUnionType({
   name: 'ResultUnion',
@@ -15,6 +16,7 @@ export const ResultUnion = createUnionType({
     HeatMapResult,
     LineChartResult,
     BarChartResult,
+    MeanChartResult,
   ],
   resolveType(value) {
     if (value.headers) {
@@ -37,6 +39,10 @@ export const ResultUnion = createUnionType({
       return BarChartResult;
     }
 
+    if (value.pointCIs) {
+      return MeanChartResult;
+    }
+
     return RawResult;
   },
 });
diff --git a/api/src/engine/models/result/means-chart-result.model.ts b/api/src/engine/models/result/means-chart-result.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..12dd97416c4ab90afd28d3c26556ba66a8c9ebe5
--- /dev/null
+++ b/api/src/engine/models/result/means-chart-result.model.ts
@@ -0,0 +1,33 @@
+import { Field, ObjectType } from '@nestjs/graphql';
+import { ChartAxis } from './common/chart-axis.model';
+import { Result } from './common/result.model';
+
+@ObjectType()
+export class PointCI {
+  @Field({ nullable: true })
+  min?: number;
+
+  @Field()
+  mean: number;
+
+  @Field({ nullable: true })
+  max?: number;
+}
+
+@ObjectType()
+export class MeanChartResult extends Result {
+  @Field()
+  name: string;
+
+  @Field(() => ChartAxis, { nullable: true })
+  xAxis?: ChartAxis;
+
+  @Field(() => ChartAxis, { nullable: true })
+  yAxis?: ChartAxis;
+
+  @Field(() => [PointCI], {
+    description: 'List of points with confidence information: min, mean, max',
+    defaultValue: [],
+  })
+  pointCIs: PointCI[];
+}
diff --git a/api/src/engine/models/result/table-result.model.ts b/api/src/engine/models/result/table-result.model.ts
index a733683d607f6f8bfbaa9d6cec5884620a76cceb..85fa6eeba8c7f2eba961fb9773159190f313923a 100644
--- a/api/src/engine/models/result/table-result.model.ts
+++ b/api/src/engine/models/result/table-result.model.ts
@@ -2,13 +2,13 @@ import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
 import { Header } from './common/header.model';
 import { Result } from './common/result.model';
 
-export enum ThemeType {
+export enum TableStyle {
   DEFAULT,
   NORMAL,
 }
 
-registerEnumType(ThemeType, {
-  name: 'ThemeType',
+registerEnumType(TableStyle, {
+  name: 'TableStyle',
 });
 
 @ObjectType()
@@ -22,6 +22,6 @@ export class TableResult extends Result {
   @Field(() => [Header])
   headers: Header[];
 
-  @Field(() => ThemeType, { defaultValue: ThemeType.DEFAULT, nullable: true })
-  theme?: ThemeType;
+  @Field(() => TableStyle, { defaultValue: TableStyle.DEFAULT, nullable: true })
+  tableStyle?: TableStyle;
 }
diff --git a/api/src/main/app.module.ts b/api/src/main/app.module.ts
index 56ef2df6fe32a0198a818a8b035418c44e54ad76..4f784efb09a185d903b603ad1ec5c677afd9c703 100644
--- a/api/src/main/app.module.ts
+++ b/api/src/main/app.module.ts
@@ -53,7 +53,6 @@ import { AppService } from './app.service';
         migrations: ['dist/migrations/*{.ts,.js}'],
         migrationsRun: process.env.NODE_ENV !== 'dev',
         synchronize: process.env.NODE_ENV === 'dev',
-        loggerLevel: 'debug',
         autoLoadEntities: true,
       }),
     }),
diff --git a/api/src/schema.gql b/api/src/schema.gql
index 8a0e2400bf297c9d066ef68dc77ec2cee3b7672f..95da1492e47ee6d0470960adf26763505a6c1d4d 100644
--- a/api/src/schema.gql
+++ b/api/src/schema.gql
@@ -85,30 +85,22 @@ type Algorithm {
   description: String
 }
 
-type ChartAxis {
-  """label of the Axis"""
-  label: String
-
-  """label of each element on this Axis"""
-  categories: [String!]
-}
-
 type GroupResult {
   name: String!
   description: String
   results: [ResultUnion!]!
 }
 
-union ResultUnion = TableResult | RawResult | GroupsResult | HeatMapResult | LineChartResult | BarChartResult
+union ResultUnion = TableResult | RawResult | GroupsResult | HeatMapResult | LineChartResult | BarChartResult | MeanChartResult
 
 type TableResult {
   name: String!
   data: [[String!]!]!
   headers: [Header!]!
-  theme: ThemeType
+  tableStyle: TableStyle
 }
 
-enum ThemeType {
+enum TableStyle {
   DEFAULT
   NORMAL
 }
@@ -157,6 +149,23 @@ type BarChartResult {
   hasConnectedBars: Boolean
 }
 
+type MeanChartResult {
+  name: String!
+  xAxis: ChartAxis
+  yAxis: ChartAxis
+
+  """List of points with confidence information: min, mean, max"""
+  pointCIs: [PointCI!]!
+}
+
+type ChartAxis {
+  """label of the Axis"""
+  label: String
+
+  """label of each element on this Axis"""
+  categories: [String!]
+}
+
 type ExtraLineInfo {
   label: String!
   values: [String!]!
@@ -180,6 +189,12 @@ type Header {
   type: String!
 }
 
+type PointCI {
+  min: Float
+  mean: Float!
+  max: Float
+}
+
 type Author {
   username: String
   fullname: String