diff --git a/config/pmd-suppressions.properties b/config/pmd-suppressions.properties
index fd6a1ac8251caa2931ef48696753b0f785d067d9..a842bcf870af3d7390f1a423e46bb4230e25bbf3 100644
--- a/config/pmd-suppressions.properties
+++ b/config/pmd-suppressions.properties
@@ -1,11 +1,17 @@
 # See https://maven.apache.org/plugins/maven-pmd-plugin/examples/violation-exclusions.html
 # annotations generate not clean code
+fr.agrometinfo.www.shared.dto.ChoiceDTOBeanJsonDeserializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.ChoiceDTOBeanJsonSerializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.ChoiceDTO_MapperImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.IndicatorDTOBeanJsonDeserializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.IndicatorDTOBeanJsonSerializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.IndicatorDTO_MapperImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonDeserializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonSerializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.PeriodDTO_MapperImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonDeserializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonSerializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.SummaryDTO_MapperImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.service.IndicatorServiceFactory=UnnecessaryImport
 org.geojson.FeatureBeanJsonDeserializerImpl=UnnecessaryImport
 org.geojson.FeatureBeanJsonSerializerImpl=UnnecessaryImport
diff --git a/pom.xml b/pom.xml
index b15dd4ba23dff8c72fbc3bd501d0115718d7ae86..679864fb2f4ac2b6a06565e2fd34397743078509 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,12 @@
       <version>${junit.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-params</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+	</dependency>
   </dependencies>
 
   <dependencyManagement>
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java
index e5c58a8a8595bc335c42e466de92ae81772fc335..b4ea46c72c17fc16c6098c2e759c713dd639026e 100644
--- a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java
@@ -39,6 +39,12 @@ public interface AppConstants extends com.google.gwt.i18n.client.ConstantsWithLo
     @DefaultStringValue("Application loading...")
     String applicationLoading();
 
+    /**
+     * @return translation
+     */
+    @DefaultStringValue("Average monthly values")
+    String averageMonthlyValues();
+
     /**
      * @return translation
      */
@@ -184,6 +190,12 @@ public interface AppConstants extends com.google.gwt.i18n.client.ConstantsWithLo
     @DefaultStringValue("Metropolitan France")
     String metropolitanFrance();
 
+    /**
+     * @return translation
+     */
+    @DefaultStringValue("Monthly values")
+    String monthlyValues();
+
     /**
      * @return translation
      */
@@ -222,6 +234,12 @@ public interface AppConstants extends com.google.gwt.i18n.client.ConstantsWithLo
     @DefaultStringValue("-- please select --")
     String selectPrompt();
 
+    /**
+     * @return translation
+     */
+    @DefaultStringValue("Toggle right panel")
+    String toggleRightPanel();
+
     /**
      * @return translation
      */
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java
index 40f1da0573e92c909e95a873d7814b3514add917..64fcdcc8383276cd1d05a709b65aec7cc53fddd0 100644
--- a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java
@@ -17,6 +17,16 @@ public interface AppMessages extends Messages {
     @DefaultMessage("{0}''s account ({1})")
     String account(String username, String email);
 
+    /**
+     * @param indicator chosen indicator
+     * @param period chosen period
+     * @param region chosen region
+     * @param year chosen year
+     * @return translation
+     */
+    @DefaultMessage("Average value for the indicator {0} ({1}) at {2} in {3}")
+    String averageValue(String indicator, String period, String region, int year);
+
     /**
      * @param details failure details
      * @return translation
@@ -37,7 +47,7 @@ public interface AppMessages extends Messages {
      */
     @DefaultMessage("{0} periods.")
     @AlternateMessage({"=0", "No period.", //
-            "=1", "1 period."})
+        "=1", "1 period."})
     String nbOfIndicatorPeriods(@PluralCount int nb);
 
     /**
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/LayoutPresenter.java b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/LayoutPresenter.java
index 30f2017a2020ca45f5c01c082c4c30936d9d81ba..71d1f62cb9868752147be4cb768d05b0cfbd0511 100644
--- a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/LayoutPresenter.java
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/LayoutPresenter.java
@@ -12,6 +12,7 @@ import com.google.gwt.user.client.Cookies;
 import fr.agrometinfo.www.client.view.BaseView;
 import fr.agrometinfo.www.client.view.LayoutView;
 import fr.agrometinfo.www.client.view.MapView;
+import fr.agrometinfo.www.client.view.RightPanelView;
 import fr.agrometinfo.www.shared.dto.ChoiceDTO;
 import fr.agrometinfo.www.shared.dto.PeriodDTO;
 import fr.agrometinfo.www.shared.service.IndicatorServiceFactory;
@@ -57,14 +58,14 @@ public final class LayoutPresenter implements Presenter {
     }
 
     /**
-     * Related view.
+     * Presenter for {@link MapView}.
      */
-    private LayoutView view;
+    private final MapPresenter mapPresenter = new MapPresenter();
 
     /**
-     * Presenter for {@link MapView}.
+     * Presenter for {@link RightPanelView}.
      */
-    private final MapPresenter mapPresenter = new MapPresenter();
+    private final RightPanelPresenter rightPanelPresenter = new RightPanelPresenter();
 
     /**
      * @see https://github.com/gwtproject/gwt/issues/7631#issuecomment-110876116
@@ -87,6 +88,7 @@ public final class LayoutPresenter implements Presenter {
      */
     public void onChoiceChange(final ChoiceDTO choice) {
         mapPresenter.loadValues(choice);
+        rightPanelPresenter.loadValues(choice);
     }
 
     /**
@@ -99,12 +101,16 @@ public final class LayoutPresenter implements Presenter {
     @Override
     public void start() {
         GWT.log("LayoutPresenter.start()");
-        view = new LayoutView();
+        final LayoutView view = new LayoutView();
         view.setPresenter(this);
         view.setMapPresenter(mapPresenter);
+        view.setRightPanelPresenter(rightPanelPresenter);
         view.init();
         view.setDevMode(isDevMode());
 
+        rightPanelPresenter.setLayoutView(view);
+        rightPanelPresenter.start();
+
         IndicatorServiceFactory.INSTANCE.getPeriods() //
         .onSuccess(view::setPeriods) //
         .onFailed(view::failureNotification) //
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java
index e1fbf9a2b91a6f08c83b17f3462c762a13d9a054..c8a554253e362e512cc11b04797c1dc0ffe077cf 100644
--- a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java
@@ -1,26 +1,13 @@
 package fr.agrometinfo.www.client.presenter;
 
-import java.util.List;
-
-import org.dominokit.domino.ui.button.Button;
-import org.dominokit.domino.ui.modals.IsModalDialog;
-import org.dominokit.domino.ui.modals.Window;
-import org.dominokit.domino.ui.typography.Paragraph;
 import org.dominokit.domino.ui.utils.DominoElement;
 import org.dominokit.rest.JsRestfulRequestFactory;
 import org.dominokit.rest.shared.RestfulRequest;
 import org.geojson.FeatureCollection;
-import org.pepstock.charba.client.BarChart;
-import org.pepstock.charba.client.colors.HtmlColor;
-import org.pepstock.charba.client.data.BarDataset;
-import org.pepstock.charba.client.dom.elements.Div;
 
 import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.Random;
 
 import elemental2.dom.HTMLDivElement;
-import elemental2.dom.Node;
-import fr.agrometinfo.www.client.i18n.AppConstants;
 import fr.agrometinfo.www.client.util.ApplicationUtils;
 import fr.agrometinfo.www.client.view.BaseView;
 import fr.agrometinfo.www.client.view.MapView;
@@ -48,11 +35,6 @@ public final class MapPresenter implements Presenter {
         void setGeoJson(String geoJSON);
     }
 
-    /**
-     * I18N constants.
-     */
-    private static final AppConstants CSTS = GWT.create(AppConstants.class);
-
     /**
      * URL to get indicator values.
      */
@@ -92,47 +74,6 @@ public final class MapPresenter implements Presenter {
         }).send();
     }
 
-    /**
-     * @param ids IDS of selected cells.
-     */
-    public void onSelectionChange(final List<Long> ids) {
-        GWT.log("selection : " + ids);
-
-        // Juste là pour tester Charba.
-        // TODO : déplacer dans une vue
-        // TODO : déclencher un événement ou appeler un autre Presenter ou appeler un
-        // callback
-        final BarChart chart = new BarChart();
-
-        chart.getOptions().setResponsive(true);
-        chart.getOptions().setAnimationEnabled(false);
-        chart.getOptions().getTitle().setText("Chart for " + ids);
-        chart.getOptions().getTitle().setDisplay(true);
-
-        final BarDataset dataset = chart.newDataset();
-        dataset.setLabel("dataset 1");
-
-        final double alpha = 0.2;
-        dataset.setBackgroundColor(HtmlColor.CORNFLOWER_BLUE.alpha(alpha));
-        dataset.setBorderColor(HtmlColor.CORNFLOWER_BLUE);
-        dataset.setBorderWidth(1);
-        final int upperBound = 100;
-        dataset.setData(Random.nextInt(upperBound), Random.nextInt(upperBound), Random.nextInt(upperBound),
-                Random.nextInt(upperBound), Random.nextInt(upperBound), Random.nextInt(upperBound),
-                Random.nextInt(upperBound));
-
-        chart.getData().setLabels("January", "February", "March", "April", "May", "June", "July");
-        chart.getData().setDatasets(dataset);
-        final Div chartElement = chart.getChartElement();
-        final Window window = new Window("Cell " + ids);
-        window.setFixed()
-        // .setRight("0")
-        .setSize(IsModalDialog.ModalSize.LARGE)
-        // .setHeaderBackground(Color.PINK)
-        .add(Paragraph.create("Paragraphe !" + ids)).appendChild((Node) chartElement.as())
-        .appendFooterChild(Button.create(CSTS.close()).addClickListener(evt -> window.close())).open();
-    }
-
     /**
      * @param mapContainer container for the map
      */
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java
new file mode 100644
index 0000000000000000000000000000000000000000..de4eeb9b4d3f1469601a34047c0417fcbffe5ab3
--- /dev/null
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java
@@ -0,0 +1,101 @@
+package fr.agrometinfo.www.client.presenter;
+
+import org.dominokit.domino.ui.utils.DominoElement;
+
+import com.google.gwt.core.client.GWT;
+
+import elemental2.dom.HTMLElement;
+import fr.agrometinfo.www.client.view.BaseView;
+import fr.agrometinfo.www.client.view.LayoutView;
+import fr.agrometinfo.www.client.view.RightPanelView;
+import fr.agrometinfo.www.shared.dto.ChoiceDTO;
+import fr.agrometinfo.www.shared.dto.SummaryDTO;
+import fr.agrometinfo.www.shared.service.IndicatorServiceFactory;
+
+/**
+ * Presenter for the right panel in the LayoutView to display data related to
+ * user choice.
+ *
+ * @author Olivier Maury
+ */
+public final class RightPanelPresenter implements Presenter {
+    /**
+     * Related view interface.
+     */
+    public interface View extends BaseView<RightPanelPresenter> {
+        /**
+         * Hide the panel.
+         */
+        void hide();
+
+        /**
+         * Display summary data.
+         *
+         * @param data summary related to user choice.
+         */
+        void setSummary(SummaryDTO data);
+
+        /**
+         * Show the panel.
+         */
+        void show();
+    }
+
+    /**
+     * Related view.
+     */
+    private View view;
+
+    /**
+     * The layout handling the panel.
+     */
+    private LayoutView layoutView;
+
+    /**
+     * Container for the panel.
+     */
+    private DominoElement<HTMLElement> container;
+
+    /**
+     * Load indicator values on the panel.
+     *
+     * @param choice user choice for the indicator values
+     */
+    public void loadValues(final ChoiceDTO choice) {
+        GWT.log("RightPanelPresenter.loadValues() " + choice);
+        Integer regionId;
+        try {
+            regionId = Integer.valueOf(choice.getRegion());
+        } catch (final NumberFormatException e) {
+            regionId = null;
+        }
+        IndicatorServiceFactory.INSTANCE
+        .getSummary(choice.getIndicator(), choice.getPeriod(), regionId, choice.getYear()) //
+        .onSuccess(view::setSummary)//
+        .onFailed(layoutView::failureNotification)//
+        .send();
+        view.show();
+    }
+
+    /**
+     * @param mapContainer container for the map
+     */
+    public void setContainer(final DominoElement<HTMLElement> mapContainer) {
+        container = mapContainer;
+    }
+
+    /**
+     * @param lView the layout handling the panel.
+     */
+    public void setLayoutView(final LayoutView lView) {
+        layoutView = lView;
+    }
+
+    @Override
+    public void start() {
+        GWT.log("RightPanelPresenter.start()");
+        view = new RightPanelView(layoutView, container);
+        view.setPresenter(this);
+        view.init();
+    }
+}
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java b/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java
index b555737f3b8df866211cbf42a27d47d2a80db4ea..c1b8f3b228144820b5037d6ca61bc48480edaee1 100644
--- a/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java
@@ -50,6 +50,7 @@ import fr.agrometinfo.www.client.i18n.AppConstants;
 import fr.agrometinfo.www.client.i18n.AppMessages;
 import fr.agrometinfo.www.client.presenter.LayoutPresenter;
 import fr.agrometinfo.www.client.presenter.MapPresenter;
+import fr.agrometinfo.www.client.presenter.RightPanelPresenter;
 import fr.agrometinfo.www.client.ui.AgroclimAppsMenu;
 import fr.agrometinfo.www.client.ui.HTMLSelectElementBuilder;
 import fr.agrometinfo.www.shared.dto.ChoiceDTO;
@@ -113,11 +114,6 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
      */
     private final ChoiceDTO choice = new ChoiceDTO();
 
-    /**
-     * The element in the content panel.
-     */
-    private HTMLDivElement contentElement;
-
     /**
      * Menu displayed on small screen with vertical "...".
      */
@@ -171,6 +167,11 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
      */
     private List<PeriodDTO> periods;
 
+    /**
+     * Presenter for {@link RightPanelView}.
+     */
+    private RightPanelPresenter rightPanelPresenter;
+
     /**
      * @param text     link text
      * @param callback {@link EventCallbackFn<MouseEvent>} to be added to the click
@@ -189,6 +190,13 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
         this.notification(MSGS.failureRetrieveIndicatorCategories(getDetails(failedResponse)));
     }
 
+    /**
+     * Close the left panel if it is open.
+     */
+    public void hideRightPanel() {
+        layout.hideRightPanel();
+    }
+
     /**
      * @see https://demo.dominokit.org/layout/app-layout
      */
@@ -199,11 +207,13 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
         layout = Layout.create("AgroMetInfo").show();
         final EmptyContentBuilder<HTMLImageElement> logoElem = Elements.img("app/img/logo_etat-agrometinfo.svg");
         layout.setLogo(logoElem);
-        contentElement = Elements.div().element();
+        final HTMLDivElement contentElement = Elements.div().element();
         contentElement.textContent = CSTS.applicationLoading();
         layout.getContentPanel().id(MapView.MAP_CONTAINER_ID);
         layout.getContentPanel().appendChild(contentElement);
-        layout.getLeftPanel().css("agrometinfo-sidebar");
+        layout.getLeftPanel().css("agrometinfo-leftsidebar");
+        layout.autoFixLeftPanel();
+        layout.getRightPanel().css("agrometinfo-rightsidebar");
         layout.getNavigationBar().css("agrometinfo-navbar");
 
         initTopBar();
@@ -227,6 +237,15 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
         // https://demo.dominokit.org/forms/basic-form-elements?theme=blue
         GWT.log("initLeftPanel() sumary");
         final DominoElement<HTMLElement> panel = layout.getLeftPanel();
+
+        panel.add(a() //
+                .css(Styles.pull_right) //
+                .on(EventType.click, e -> {
+                    layout.unfixLeftPanelPosition();
+                    layout.hideLeftPanel();
+                }) //
+                .add(Icons.CONTENT_ICONS.clear().clickable()));
+
         panel.appendChild(summary);
 
         //
@@ -301,6 +320,8 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
         Window.addResizeHandler(e -> setContentPanelHeight());
         mapPresenter.setContainer(layout.getContentPanel());
         mapPresenter.start();
+
+        rightPanelPresenter.setContainer(layout.getRightPanel());
     }
 
     private void initTopBar() {
@@ -310,6 +331,12 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
 
         layout.getTopBar() //
         .css("agrometinfo-topbar") //
+        .appendChild(DominoElement.of(li() //
+                .css(Styles.pull_right) //
+                .add(a() //
+                        .on(EventType.click, e -> toggleRightPanel()) //
+                        .title(CSTS.toggleRightPanel()) //
+                        .add(Icons.ALL.menu_open_mdi().clickable())))) //
         .appendChild(DominoElement.of(li() //
                 .css(Styles.pull_right) //
                 .add(a() //
@@ -398,7 +425,11 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
     }
 
     private void onRegionChange(final String newValue) {
-        choice.setRegion(newValue);
+        if (newValue.length() > 2) {
+            choice.setRegion(null);
+        } else {
+            choice.setRegion(newValue);
+        }
         onChoiceChange();
     }
 
@@ -480,6 +511,13 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
         .build();
     }
 
+    /**
+     * @param presenter presenter for {@link RightPanelView}.
+     */
+    public void setRightPanelPresenter(final RightPanelPresenter presenter) {
+        this.rightPanelPresenter = presenter;
+    }
+
     @Override
     public void setYears(final List<Integer> list) {
         final Map<String, String> yearOptions = new HashMap<>();
@@ -496,4 +534,24 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen
             onChoiceChange();
         });
     }
+
+    /**
+     * Open the right panel.
+     */
+    public void showRightPanel() {
+        if (!layout.isRightPanelVisible()) {
+            layout.showRightPanel();
+        }
+    }
+
+    /**
+     * Open or close the right panel.
+     */
+    public void toggleRightPanel() {
+        if (layout.isRightPanelVisible()) {
+            layout.hideRightPanel();
+        } else {
+            layout.showRightPanel();
+        }
+    }
 }
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java b/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java
index ea5fc75bfcf5099bcfbedcef098b437d507d2532..3cf7561dab6b7be5474d6261dae3d1b6111e06be 100644
--- a/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java
@@ -1,6 +1,5 @@
 package fr.agrometinfo.www.client.view;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.dominokit.domino.ui.utils.DominoElement;
@@ -29,12 +28,8 @@ import ol.OLFactory;
 import ol.View;
 import ol.ViewOptions;
 import ol.color.Color;
-import ol.event.EventListener;
-import ol.events.condition.Condition;
 import ol.format.GeoJson;
 import ol.format.GeoJsonFeatureOptions;
-import ol.interaction.Select;
-import ol.interaction.SelectOptions;
 import ol.layer.Base;
 import ol.layer.Group;
 import ol.layer.LayerGroupOptions;
@@ -214,34 +209,11 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma
         v.renderMode = 'image';
     }-*/;
 
-    /**
-     * Force vector layer to renderMode image.
-     *
-     * @param sel
-     */
-    private static native void setRenderSelModeImage(Select sel) /*-{
-        for ( var propSel in sel) {
-            if (sel[propSel] != null && sel[propSel]['type'] == 'VECTOR') {
-                for ( var prop in sel[propSel]) {
-                    if (sel[propSel][prop] == 'vector') {
-                        sel[propSel][prop] = 'image';
-                        return;
-                    }
-                }
-            }
-        }
-    }-*/;
-
     /**
      * Layer with cells.
      */
     private Vector vectorLayer;
 
-    /**
-     * Zoom at map creation.
-     */
-    private Double initialZoom = null;
-
     /**
      * map.
      */
@@ -271,32 +243,11 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma
         super(element.element());
     }
 
-    /**
-     * Mouse click interaction to select a cell.
-     */
-    private void addClickInteractions() {
-        final SelectOptions selectOptions = new SelectOptions();
-        selectOptions.setCondition(Condition.getClick());
-        final Style style = createCellStyle(Color.getColorFromString("blue"), new Color(255, 0, 0, 0.5f));
-        selectOptions.setStyle((f, r) -> new Style[] {style});
-
-        // create a select interaction
-        final Select featureSelect = new Select(selectOptions);
-        setRenderSelModeImage(featureSelect);
-        map.addInteraction(featureSelect);
-
-        final EventListener<Select.Event> selectListener = this::onSelection;
-
-        featureSelect.on("select", selectListener);
-
-        removeContextMenuRightClick();
-    }
-
     private Feature[] colorizeFeatures(final Feature[] features) {
         for (final Feature f : features) {
             final Double value = getValue(f);
             final String color = "#" + ColorSequenceManager.getColorForValue(colorIntervals, value);
-            GWT.log("Feature #" + f.getId() + ", value=" + value + ", color=" + color);
+            // GWT.log("Feature #" + f.getId() + ", value=" + value + ", color=" + color);
             final Color foreground = Color.getColorFromString(color);
             final Style style = createCellStyle(foreground, foreground);
             f.setStyle(style);
@@ -326,7 +277,6 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma
         viewOptions.setZoom(startZoom);
         viewOptions.setMaxZoom(maxZoom);
         view = new View(viewOptions);
-        initialZoom = view.getZoom();
     }
 
     /**
@@ -348,17 +298,7 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma
         map = new Map(options);
 
         // add some interactions
-        addClickInteractions();
-    }
-
-    private void onSelection(final Select.Event event) {
-        if (event.getSelected() != null && event.getSelected().length > 0) {
-            final List<Long> ids = new ArrayList<>();
-            for (final Feature f : event.getSelected()) {
-                ids.add(Long.valueOf(f.getId()));
-            }
-            presenter.onSelectionChange(ids);
-        }
+        removeContextMenuRightClick();
     }
 
     /**
@@ -385,10 +325,7 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma
         vectorLayer = createVectorLayer(vectorSource);
         map.addLayer(vectorLayer);
         map.addControl(ControlSuppliers.createZoomToExtent(vectorSource.getExtent()));
-        // Only zoom on the results the first time
-        if (view.getZoom() == initialZoom) {
-            view.fit(vectorSource.getExtent());
-        }
+        view.fit(vectorSource.getExtent());
     }
 
     @Override
diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java b/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c8bef46f86937f7c1d88376b637eae5a8edd644
--- /dev/null
+++ b/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java
@@ -0,0 +1,143 @@
+package fr.agrometinfo.www.client.view;
+
+import static org.jboss.elemento.Elements.a;
+
+import java.util.Map;
+
+import org.dominokit.domino.ui.cards.Card;
+import org.dominokit.domino.ui.icons.Icons;
+import org.dominokit.domino.ui.utils.DominoElement;
+import org.dominokit.domino.ui.utils.TextNode;
+import org.jboss.elemento.EventType;
+import org.pepstock.charba.client.BarChart;
+import org.pepstock.charba.client.colors.HtmlColor;
+import org.pepstock.charba.client.data.BarDataset;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
+
+import elemental2.dom.HTMLDivElement;
+import elemental2.dom.HTMLElement;
+import elemental2.dom.Node;
+import fr.agrometinfo.www.client.i18n.AppConstants;
+import fr.agrometinfo.www.client.i18n.AppMessages;
+import fr.agrometinfo.www.client.presenter.RightPanelPresenter;
+import fr.agrometinfo.www.shared.dto.SummaryDTO;
+
+/**
+ * Right panel in the LayoutView to display data related to user choice.
+ *
+ * @author Olivier Maury
+ */
+public final class RightPanelView implements RightPanelPresenter.View {
+
+    /**
+     * I18N messages.
+     */
+    private static final AppMessages MSGS = GWT.create(AppMessages.class);
+
+    /**
+     * I18N constants.
+     */
+    private static final AppConstants CSTS = GWT.create(AppConstants.class);
+
+    /**
+     * Container for the panel.
+     */
+    private final DominoElement<HTMLElement> container;
+
+    /**
+     * Layout handling the panel.
+     */
+    private final LayoutView layoutView;
+
+    /**
+     * Container for bar chart displaying monthly values.
+     */
+    private final DominoElement<HTMLDivElement> barChartContainer = DominoElement.div();
+
+    /**
+     * Card for the daily average value for the user choice.
+     */
+    private final Card averageCard = Card.create();
+
+    /**
+     * Constructor.
+     *
+     * @param view layout handling the panel.
+     * @param div  container for the panel.
+     */
+    public RightPanelView(final LayoutView view, final DominoElement<HTMLElement> div) {
+        layoutView = view;
+        container = div;
+    }
+
+    private void createBarChart(final Map<String, Float> monthlyValues) {
+        GWT.log("RightPanelView.createBarChart() " + monthlyValues.size());
+        final BarChart barChart = new BarChart();
+        barChart.getOptions().setResponsive(true);
+        barChart.getOptions().setAnimationEnabled(false);
+        barChart.getOptions().getTitle().setText(CSTS.monthlyValues());
+        barChart.getOptions().getTitle().setDisplay(true);
+
+        final BarDataset dataset = barChart.newDataset();
+        dataset.setLabel(CSTS.averageMonthlyValues());
+
+        final double alpha = 0.2;
+        dataset.setBackgroundColor(HtmlColor.CORNFLOWER_BLUE.alpha(alpha));
+        dataset.setBorderColor(HtmlColor.CORNFLOWER_BLUE);
+        dataset.setBorderWidth(1);
+        final double[] values = monthlyValues.values().stream().mapToDouble(Float::doubleValue).toArray();
+        dataset.setData(values);
+
+        final String[] labels = monthlyValues.keySet().stream().toArray(String[]::new);
+        barChart.getData().setLabels(labels);
+
+        barChart.getData().setDatasets(dataset);
+
+        barChartContainer.clearElement();
+        barChartContainer.appendChild((Node) barChart.getChartElement().as());
+    }
+
+    @Override
+    public void hide() {
+        layoutView.hideRightPanel();
+    }
+
+    @Override
+    public void init() {
+        container.add(a() //
+                .on(EventType.click, e -> hide()) //
+                .add(Icons.CONTENT_ICONS.clear().clickable()));
+        container.add(averageCard);
+        container.add(barChartContainer);
+    }
+
+    @Override
+    public void setPresenter(final RightPanelPresenter p) {
+        // Do nothing
+    }
+
+    @Override
+    public void setSummary(final SummaryDTO data) {
+        GWT.log("RightPanelView.setSummary()");
+        String region = data.getRegion();
+        if (region == null) {
+            region = CSTS.metropolitanFrance();
+        }
+        final DateTimeFormat df = DateTimeFormat.getFormat(PredefinedFormat.DATE_MEDIUM);
+        averageCard.setTitle(MSGS.averageValue(data.getIndicator().getDescription(), data.getPeriod(), region,
+                data.getChoice().getYear()));
+        averageCard.setDescription(df.format(data.getDate()));
+        averageCard.getBody().clearElement();
+        averageCard.getBody().appendChild(TextNode.of(String.valueOf(data.getAverageValue())));
+        createBarChart(data.getMonthlyValues());
+    }
+
+    @Override
+    public void show() {
+        layoutView.showRightPanel();
+    }
+
+}
diff --git a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties
index 9fca179e7505343c7b07cb62f9ca4b1a1ca25ca4..ae70b8245cc49f91bb5121d5c6df1d8386bbb6ad 100644
--- a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties
+++ b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties
@@ -4,6 +4,7 @@ acceptEULA = En vous connectant, vous acceptez les conditions d’utilisation et
 agrometinfoIntro = AgroMetInfo met à disposition des indicateurs agroclimatiques et des indicateurs de suivi de culture d'hiver (culture type  blé tendre) et de printemps (culture type maïs) actualisés quotidiennement sous forme de cartes et de graphiques.
 agroclimApps = Les applications d’AgroClim
 applicationLoading = Chargement de l’application…
+averageMonthlyValues = Valeurs moyennes mensuelles
 cancel= Annuler
 chooseIndicator= Choisir un indicateur
 choosePeriod= Choisir une période
@@ -28,12 +29,14 @@ login = Se connecter
 loginOrSignIn = ou s’inscrire avec
 logout = Se déconnecter
 metropolitanFrance = France métropolitaine
+monthlyValues = Valeurs mensuelles
 no= Non
 normalComparison= Comparaison à la normale
 normalComparisonTooltip= <b>La comparaison à la normale</b> <em>se calcule en soustrayant <b>la moyenne de l’indicateur choisi</b> pour les trente dernières années (1990-2020) de <b>l’année sélectionnée</b>
 otherAgroclimApps = Autres applications d’AgroClim
 seePrivacyPolicy = Consultez le paragraphe « Données personnelles » dans les mentions légales.
 selectPrompt = -- sélectionner --
+toggleRightPanel = Afficher / masquer le panneau de droite
 userProfile = Compte et paramètres
 whyConnectionIsRequired = Vous devez vous identifier pour accéder à AgroMetInfo en raison des accords avec Météo-France relatifs aux échanges de données SAFRAN avec AgroClim.
 yes= Oui
diff --git a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties
index 758ba39f88317ad49855cc394370d7058a66e3ca..5ee6f48c8586db5c54b56321e0f30c99fea12659 100644
--- a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties
+++ b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties
@@ -1,5 +1,6 @@
 # Ce fichier est encodé en UTF-8.
 account = Compte de {0} ({1})
+averageValue = Valeur moyenne de l’indicateur {0} ({1}) en {2} sur {3}
 failureStatusCode = Code d’état HTTP : {0}
 nbOfIndicatorPeriods[\=0] = Aucune catégorie d’indicateurs.
 nbOfIndicatorPeriods[\=1] = Une catégorie d’indicateurs.
diff --git a/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css b/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css
index 179ef3fa9651cfa1373f306d5ca04d7388a893c2..2859185b03efd98820287c9afc00b26305857b90 100644
--- a/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css
+++ b/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css
@@ -89,10 +89,17 @@ select {
 .agrometinfo-navbar .navbar-header .menu-toggle .bars {
     line-height: 15px;
 }
-.agrometinfo-sidebar.sidebar {
-    height: calc(100vh - var(--logo-height));
+.agrometinfo-leftsidebar.sidebar,
+.agrometinfo-rightsidebar.right-sidebar {
+	height: calc(100vh - var(--logo-height));
     top: var(--logo-height);
 }
+.agrometinfo-rightsidebar.right-sidebar {
+	width: var(--rightsidebar-width);
+}
+.agrometinfo-rightsidebar.right-sidebar.slide-out-right {
+	right: calc(-1 * var(--rightsidebar-width));
+}
 .agrometinfo-topbar.navbar {
     border: 0px;
 }
@@ -166,3 +173,13 @@ div.idp {
 :root {
     --logo-height: 50px;
 }
+@media screen and (max-width: 700px) {
+	:root {
+		--rightsidebar-width: 90%;
+	}
+}
+@media screen and (min-width: 700px) {
+	:root {
+		--rightsidebar-width: 400px;
+	}
+}
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/I18n.java b/www-server/src/main/java/fr/agrometinfo/www/server/I18n.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac7e99031af6d4132e7dcef159495a41c25e007c
--- /dev/null
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/I18n.java
@@ -0,0 +1,251 @@
+package fr.agrometinfo.www.server;
+
+import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+
+import lombok.Getter;
+import lombok.NonNull;
+
+/**
+ * Localized messages with plural handling à la GWT.
+ *
+ * @author Olivier Maury
+ */
+public class I18n {
+    /**
+     * Accepted operators, ordered.
+     */
+    public enum Operator implements BiFunction<Integer, Integer, Boolean> {
+        /**
+         * Equals.
+         */
+        AEQ("=", Objects::equals),
+        /**
+         * Inferior or equals.
+         */
+        BINFEQ("<=", (a, b) -> a <= b),
+        /**
+         * Strictly inferior.
+         */
+        CINF("<", (a, b) -> a < b),
+        /**
+         * Superior or equals.
+         */
+        DSUPEQ(">=", (a, b) -> a >= b),
+        /**
+         * Strictly superior.
+         */
+        ESUP(">", (a, b) -> a > b);
+
+        /**
+         * Guess the right operator in the string comparison.
+         *
+         * @param string string comparison (eg.: ">=10")
+         * @return operator matching the string comparison
+         */
+        static Optional<Operator> extract(final String string) {
+            for (final Operator op : values()) {
+                if (string.startsWith(op.symbol)) {
+                    return Optional.of(op);
+                }
+            }
+            return Optional.empty();
+        }
+        /**
+         * Comparison function of the operator.
+         */
+        private final BiPredicate<Integer, Integer> function;
+        /**
+         * String representation of the operator.
+         */
+        private final String symbol;
+        /**
+         * Constructor.
+         *
+         * @param string String representation of the operator.
+         * @param func Comparison function of the operator.
+         */
+        Operator(final String string,
+                final BiPredicate<Integer, Integer> func) {
+            symbol = string;
+            function = func;
+        }
+
+        @Override
+        public Boolean apply(final Integer arg0, final Integer arg1) {
+            return function.test(arg0, arg1);
+        }
+
+        /**
+         * @return length of string representation
+         */
+        public int getLength() {
+            return symbol.length();
+        }
+    }
+
+    /**
+     * Bundle name.
+     */
+    public static final String BUNDLE_NAME = "fr.agrometinfo.www.server.i18n";
+
+    /**
+     * Check if the comparison string matches the value.
+     *
+     * @param comparison comparison string (eg.: ">10")
+     * @param plural value
+     * @return if the comparison string matches the value.
+     */
+    static boolean matches(final String comparison, final int plural) {
+        final Optional<Operator> operator = Operator.extract(comparison);
+        if (operator.isPresent()) {
+            final Operator op = operator.get();
+            String val = comparison.substring(op.getLength());
+            if (val != null) {
+                val = val.trim();
+                if (!val.isEmpty()) {
+                    final Integer value = Integer.valueOf(val);
+                    return op.apply(plural, value);
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Fallback resources from .properties file, in case of missing translation.
+     */
+    private final ResourceBundle fallbackResources;
+
+    /**
+     * Translation keys.
+     */
+    private final Set<String> keys = new HashSet<>();
+
+    /**
+     * Requested locale.
+     */
+    @Getter
+    private final Locale locale;
+
+    /**
+     * Resources from .properties file.
+     */
+    private final ResourceBundle resources;
+
+    /**
+     * Constructor.
+     *
+     * @param rb the bundle.
+     */
+    public I18n(final ResourceBundle rb) {
+        resources = rb;
+        locale = rb.getLocale();
+        final var bundleName = rb.getBaseBundleName();
+        if (bundleName != null) {
+            fallbackResources = ResourceBundle.getBundle(bundleName, Locale.ROOT);
+        } else {
+            fallbackResources = null;
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param bundleName      Path of .property resource.
+     * @param requestedLocale The requested locale for the bundle.
+     */
+    public I18n(@NonNull final String bundleName, @NonNull final Locale requestedLocale) {
+        locale = requestedLocale;
+        fallbackResources = ResourceBundle.getBundle(bundleName, Locale.ROOT);
+        final var res = ResourceBundle.getBundle(bundleName, locale);
+        if (res.getLocale().equals(locale)) {
+            resources = res;
+        } else {
+            resources = fallbackResources;
+        }
+        keys.addAll(Collections.list(resources.getKeys()));
+        keys.addAll(Collections.list(fallbackResources.getKeys()));
+    }
+
+    /**
+     * Return message with inlined arguments.
+     *
+     * @param plural value for plural form
+     * @param key message key
+     * @param messageArguments arguments for the message.
+     * @return message with arguments or exclamation message
+     */
+    public String format(final int plural, final String key,
+            final Object... messageArguments) {
+        String keyWithSuffix;
+
+        // the suffix for the value
+        keyWithSuffix = key + "[=" + plural + "]";
+        if (getKeys().contains(keyWithSuffix)) {
+            return format(keyWithSuffix, messageArguments);
+        }
+
+        // with comparators <, <=, >, >=
+        final List<String> suffixes = getKeys().stream()
+                .filter(k -> k.startsWith(key + "[") && k.endsWith("]"))
+                .map(k -> k.substring(key.length() + 1, k.length() - 1))
+                .collect(Collectors.toList());
+        for (final String suf : suffixes) {
+            if (matches(suf, plural)) {
+                keyWithSuffix = key + "[" + suf + "]";
+                return format(keyWithSuffix, messageArguments);
+            }
+        }
+        // if not defined, used default
+        return format(key, messageArguments);
+    }
+
+    /**
+     * Return message with inlined arguments.
+     *
+     * @param key message key
+     * @param messageArguments arguments for the message.
+     * @return message with arguments or exclamation message
+     */
+    public String format(final String key, final Object... messageArguments) {
+        final var format = this.get(key);
+        final var messageFormat = new MessageFormat(format, locale);
+        return messageFormat.format(messageArguments);
+    }
+
+    /**
+     * Retrieve message from key.
+     *
+     * @param key message key
+     * @return message value or exclamation message
+     */
+    public String get(final String key) {
+        if (resources.containsKey(key)) {
+            return resources.getString(key);
+        }
+        if (fallbackResources != null && fallbackResources.containsKey(key)) {
+            return fallbackResources.getString(key);
+        }
+        return "!" + key + "!";
+    }
+
+
+    /**
+     * @return all keys in the .properties file
+     */
+    public Set<String> getKeys() {
+        return Collections.unmodifiableSet(keys);
+    }
+
+}
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDao.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDao.java
index 6d297d07657c295fa94efe2008b9d82dba17c265..3cebb35c470e4a2c4fdbda1394171269150e9812 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDao.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDao.java
@@ -33,6 +33,25 @@ public interface DailyValueDao {
      */
     List<DailyValue> find(Indicator indicator, Region region, LocalDate date);
 
+    /**
+     * The average value {@link DailyValue#getComputedValue()} for the indicator on a date for all cells.
+     *
+     * @param indicator indicator to search
+     * @param date simulation date
+     * @return average value
+     */
+    Double findAverageComputedValue(Indicator indicator, LocalDate date);
+
+    /**
+     * The average value {@link DailyValue#getComputedValue()} for the indicator on a date for a region.
+     *
+     * @param indicator indicator to search
+     * @param date simulation date
+     * @param regionId ID of region to search
+     * @return average value
+     */
+    Double findAverageComputedValue(Indicator indicator, LocalDate date, Integer regionId);
+
     /**
      * @return the indicators (with period) related to computed values
      */
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernate.java
index bbd3b2bd1c017cba54d9b9cab0cb77057588de18..52104f3c6116e2273f3367b51a7e8489f2a03133 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernate.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernate.java
@@ -38,6 +38,26 @@ public class DailyValueDaoHibernate extends DaoHibernate<DailyValue> implements
                 DailyValue.class);
     }
 
+    @Override
+    public final Double findAverageComputedValue(final Indicator indicator, final LocalDate date) {
+        final var jpql = """
+                SELECT AVG(t.computedValue)
+                FROM DailyValue AS t
+                WHERE t.indicator=:indicator AND t.date=:date""";
+        return super.findOneByJPQL(jpql, Map.of("indicator", indicator, "date", date), Double.class);
+    }
+
+    @Override
+    public final Double findAverageComputedValue(final Indicator indicator, final LocalDate date,
+            final Integer regionId) {
+        final var jpql = """
+                SELECT AVG(t.computedValue)
+                FROM DailyValue AS t
+                WHERE t.indicator=:indicator AND t.date=:date AND t.cell.department.region.id=:region""";
+        return super.findOneByJPQL(jpql, Map.of("indicator", indicator, "date", date, "region", regionId),
+                Double.class);
+    }
+
     @Override
     public final List<Indicator> findIndicators() {
         final var jpql = "SELECT DISTINCT i FROM DailyValue AS t JOIN t.indicator AS i JOIN t.indicator.period";
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ca7b5f944e808eb903c51a5ddb46af762e0b64a
--- /dev/null
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java
@@ -0,0 +1,34 @@
+package fr.agrometinfo.www.server.dao;
+
+import java.time.LocalDate;
+import java.util.List;
+
+import fr.agrometinfo.www.server.model.Indicator;
+import fr.agrometinfo.www.server.model.MonthlyValue;
+import fr.agrometinfo.www.server.model.Region;
+
+/**
+ * DAO for {@link MonthlyValue}.
+ *
+ * @author Olivier Maury
+ */
+public interface MonthlyValueDao {
+    /**
+     * Last 12 monthly values for the indicator and all cells.
+     *
+     * @param indicator indicator
+     * @param date      date for the value last date
+     * @return values
+     */
+    List<MonthlyValue> find(Indicator indicator, LocalDate date);
+
+    /**
+     * Last 12 monthly values for the indicator and all cells of a region.
+     *
+     * @param indicator indicator
+     * @param region    region
+     * @param date      date for the value last date
+     * @return values
+     */
+    List<MonthlyValue> find(Indicator indicator, Region region, LocalDate date);
+}
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd873041357b1dc04efe57bb8bc22bbfdd47ca49
--- /dev/null
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java
@@ -0,0 +1,61 @@
+package fr.agrometinfo.www.server.dao;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+import fr.agrometinfo.www.server.model.Indicator;
+import fr.agrometinfo.www.server.model.MonthlyValue;
+import fr.agrometinfo.www.server.model.Region;
+import jakarta.enterprise.context.ApplicationScoped;
+
+/**
+ * Hibernate implementation of {@link MonthlyValueDao}.
+ *
+ * @author Olivier Maury
+ */
+@ApplicationScoped
+public class MonthlyValueDaoHibernate extends DaoHibernate<MonthlyValue> implements MonthlyValueDao {
+
+    /**
+     * Constructor.
+     */
+    public MonthlyValueDaoHibernate() {
+        super(MonthlyValue.class);
+    }
+
+    @Override
+    public final List<MonthlyValue> find(final Indicator indicator, final LocalDate date) {
+        final var jpql = """
+                SELECT new fr.agrometinfo.www.server.model.MonthlyValue(
+                    EXTRACT(YEAR FROM t.date) AS year,
+                    EXTRACT(MONTH FROM t.date) AS month,
+                    AVG(t.computedValue) AS value)
+                FROM DailyValue AS t
+                WHERE t.indicator=:indicator AND
+                    t.date BETWEEN :startdate AND :enddate AND
+                    t.computedValue IS NOT NULL
+                GROUP BY year, month""";
+        return super.findAllByJPQL(jpql,
+                Map.of("indicator", indicator, "startdate", date.minusYears(1), "enddate", date), MonthlyValue.class);
+    }
+
+    @Override
+    public final List<MonthlyValue> find(final Indicator indicator, final Region region, final LocalDate date) {
+        final var jpql = """
+                SELECT new fr.agrometinfo.www.server.model.MonthlyValue(
+                    EXTRACT(YEAR FROM t.date) AS year,
+                    EXTRACT(MONTH FROM t.date) AS month,
+                    AVG(t.computedValue) AS value)
+                FROM DailyValue AS t
+                WHERE t.indicator=:indicator AND
+                    t.date BETWEEN :startdate AND :enddate AND
+                    t.cell.department.region=:region AND
+                    t.computedValue IS NOT NULL
+                GROUP BY year, month""";
+        return super.findAllByJPQL(jpql,
+                Map.of("indicator", indicator, "startdate", date.minusYears(1), "enddate", date, "region", region),
+                MonthlyValue.class);
+    }
+
+}
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/model/Indicator.java b/www-server/src/main/java/fr/agrometinfo/www/server/model/Indicator.java
index c84430bf50c4bb4d55fc49f04aafeb3e5963e222..09b06eb107521a0f5323f5bc85ef64a7f5d8fe8a 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/model/Indicator.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/model/Indicator.java
@@ -48,12 +48,6 @@ public class Indicator {
     @JoinColumn(name = "period")
     @ManyToOne
     private Period period;
-    /**
-     * Color sequence used to display indicator values on the map.
-     */
-    @JoinColumn(name = "colorsequence")
-    @ManyToOne
-    private ColorSequence colorSequence;
     /**
      * Defined to use in @JoinTable.
      */
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/model/MonthlyValue.java b/www-server/src/main/java/fr/agrometinfo/www/server/model/MonthlyValue.java
new file mode 100644
index 0000000000000000000000000000000000000000..02be7f0ff1c7b5f1d5c66d15160468eea40969d3
--- /dev/null
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/model/MonthlyValue.java
@@ -0,0 +1,42 @@
+package fr.agrometinfo.www.server.model;
+
+import jakarta.persistence.Column;
+import lombok.Data;
+
+/**
+ * Value of the indicator for the month on an area (cell, department, region,
+ * all cells).
+ *
+ * @author Olivier Maury
+ */
+@Data
+public class MonthlyValue {
+    /**
+     * Year.
+     */
+    @Column(name = "year")
+    private Integer year;
+    /**
+     * Month number [1-12].
+     */
+    @Column(name = "month")
+    private Integer month;
+    /**
+     * Value of the indicator.
+     */
+    @Column(name = "value")
+    private Float value;
+
+    /**
+     * Constructor.
+     *
+     * @param y Year
+     * @param m Month number [1-12]
+     * @param v Value of the indicator
+     */
+    public MonthlyValue(final Number y, final Number m, final Number v) {
+        year = y.intValue();
+        month = m.intValue();
+        value = v.floatValue();
+    }
+}
diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java b/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java
index 3340ff453fbb5af190a10fd4a588aadfef5102be..5abf7d3609d063d6df35226b616d13223c56c9dc 100644
--- a/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java
+++ b/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java
@@ -1,7 +1,9 @@
 package fr.agrometinfo.www.server.rs;
 
 import java.time.LocalDate;
+import java.time.ZoneId;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -13,18 +15,23 @@ import org.geojson.FeatureCollection;
 import org.geojson.LngLatAlt;
 import org.geojson.Polygon;
 
+import fr.agrometinfo.www.server.I18n;
 import fr.agrometinfo.www.server.dao.CellDao;
 import fr.agrometinfo.www.server.dao.DailyValueDao;
 import fr.agrometinfo.www.server.dao.IndicatorDao;
+import fr.agrometinfo.www.server.dao.MonthlyValueDao;
 import fr.agrometinfo.www.server.dao.RegionDao;
 import fr.agrometinfo.www.server.model.Cell;
 import fr.agrometinfo.www.server.model.DailyValue;
 import fr.agrometinfo.www.server.model.Indicator;
+import fr.agrometinfo.www.server.model.MonthlyValue;
 import fr.agrometinfo.www.server.model.Region;
 import fr.agrometinfo.www.server.util.LocaleUtils;
+import fr.agrometinfo.www.shared.dto.ChoiceDTO;
 import fr.agrometinfo.www.shared.dto.ErrorResponseDTO;
 import fr.agrometinfo.www.shared.dto.IndicatorDTO;
 import fr.agrometinfo.www.shared.dto.PeriodDTO;
+import fr.agrometinfo.www.shared.dto.SummaryDTO;
 import fr.agrometinfo.www.shared.service.IndicatorService;
 import jakarta.annotation.PostConstruct;
 import jakarta.enterprise.context.RequestScoped;
@@ -61,6 +68,13 @@ public class IndicatorResource implements IndicatorService {
         return "no translation !";
     }
 
+    private static IndicatorDTO toDTO(final Indicator indicator, final Locale locale) {
+        final var dto = new IndicatorDTO();
+        dto.setDescription(getTranslation(indicator.getDescriptions(), locale));
+        dto.setCode(indicator.getCode());
+        return dto;
+    }
+
     /**
      * Convert a {@link Cell} entity to GeoJSON feature.
      *
@@ -109,6 +123,18 @@ public class IndicatorResource implements IndicatorService {
         return feature;
     }
 
+    /**
+     * DAO for cells.
+     */
+    @Inject
+    private CellDao cellDao;
+
+    /**
+     * DAO for {@link DailyValue}.
+     */
+    @Inject
+    private DailyValueDao dailyValueDao;
+
     /**
      * Information for HTTP servlet.
      */
@@ -122,10 +148,10 @@ public class IndicatorResource implements IndicatorService {
     private IndicatorDao indicatorDao;
 
     /**
-     * DAO for cells.
+     * DAO for {@link MonthlyValue}.
      */
     @Inject
-    private CellDao cellDao;
+    private MonthlyValueDao monthlyValueDao;
 
     /**
      * DAO for {@link Region}.
@@ -133,12 +159,6 @@ public class IndicatorResource implements IndicatorService {
     @Inject
     private RegionDao regionDao;
 
-    /**
-     * DAO for {@link DailyValue}.
-     */
-    @Inject
-    private DailyValueDao dailyValueDao;
-
     /**
      * Ensure the value of query parameter is not null and not blank.
      *
@@ -181,10 +201,7 @@ public class IndicatorResource implements IndicatorService {
                 period.setIndicators(new ArrayList<>());
                 return period;
             });
-            final var dto = new IndicatorDTO();
-            dto.setDescription(getTranslation(indicator.getDescriptions(), locale));
-            dto.setCode(indicator.getCode());
-            dtos.get(key).getIndicators().add(dto);
+            dtos.get(key).getIndicators().add(toDTO(indicator, locale));
         }
         return new ArrayList<>(dtos.values());
     }
@@ -198,6 +215,62 @@ public class IndicatorResource implements IndicatorService {
                 .collect(Collectors.toMap(r -> String.valueOf(r.getId()), Region::getName));
     }
 
+    @GET
+    @Path(IndicatorService.PATH_SUMMARY)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Override
+    public SummaryDTO getSummary(@QueryParam(value = "indicator") final String indicatorUid,
+            @QueryParam(value = "period") final String periodCode, @QueryParam(value = "region") final Integer regionId,
+            @QueryParam(value = "year") final Integer year) {
+        checkRequired(indicatorUid, "indicator");
+        checkRequired(periodCode, "period");
+        checkRequired(year, "year");
+
+        final var locale = LocaleUtils.getLocale(httpServletRequest);
+        final var i18n = new I18n(I18n.BUNDLE_NAME, locale);
+        final var indicator = indicatorDao.findByCodeAndPeriod(indicatorUid, periodCode);
+        if (indicator == null) {
+            final var status = Response.Status.BAD_REQUEST;
+            throw new WebApplicationException(Response.status(status) //
+                    .entity(ErrorResponseDTO.of(status.getStatusCode(), //
+                            status.getReasonPhrase(), //
+                            indicatorUid + " is unknown for " + periodCode)) //
+                    .build());
+        }
+
+        final var date = dailyValueDao.findLastDate(indicator, year);
+        final Double averageValue;
+        final Map<String, Float> monthlyValues;
+        final Region region;
+        if (regionId == null) {
+            region = null;
+            averageValue = dailyValueDao.findAverageComputedValue(indicator, date);
+            monthlyValues = toMonthlyValues(monthlyValueDao.find(indicator, date), i18n);
+        } else {
+            region = dailyValueDao.findRegions().stream().filter(r -> r.getId() == regionId).findFirst()
+                    .orElseGet(() -> null);
+            averageValue = dailyValueDao.findAverageComputedValue(indicator, date, regionId);
+            monthlyValues = toMonthlyValues(monthlyValueDao.find(indicator, region, date), i18n);
+        }
+
+        final var choice = new ChoiceDTO();
+        choice.setIndicator(indicatorUid);
+        choice.setPeriod(periodCode);
+        choice.setRegion(String.valueOf(regionId));
+        choice.setYear(year);
+        final var dto = new SummaryDTO();
+        dto.setAverageValue(averageValue.floatValue());
+        dto.setChoice(choice);
+        dto.setDate(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()));
+        dto.setIndicator(toDTO(indicator, locale));
+        dto.setMonthlyValues(monthlyValues);
+        dto.setPeriod(getTranslation(indicator.getPeriod().getNames(), locale));
+        if (region != null) {
+            dto.setRegion(region.getName());
+        }
+        return dto;
+    }
+
     @GET
     @Path(IndicatorService.PATH_VALUES)
     @Produces("application/geo+json")
@@ -250,4 +323,11 @@ public class IndicatorResource implements IndicatorService {
         LOGGER.traceEntry();
     }
 
+    private Map<String, Float> toMonthlyValues(final List<MonthlyValue> values, final I18n i18n) {
+        return values.stream().collect(Collectors.toMap(//
+                v -> i18n.format(v.getMonth(), "month", v.getYear()), //
+                MonthlyValue::getValue
+                ));
+    }
+
 }
diff --git a/www-server/src/main/resources/fr/agrometinfo/www/server/i18n.properties b/www-server/src/main/resources/fr/agrometinfo/www/server/i18n.properties
new file mode 100644
index 0000000000000000000000000000000000000000..dc58fe90011f1c4e70377de812a5351a0abceeef
--- /dev/null
+++ b/www-server/src/main/resources/fr/agrometinfo/www/server/i18n.properties
@@ -0,0 +1,13 @@
+# Ce fichier est encodé en UTF-8
+month[\=1]=January {0,number,#}
+month[\=2]=February {0,number,#}
+month[\=3]=March {0,number,#}
+month[\=4]=April {0,number,#}
+month[\=5]=May {0,number,#}
+month[\=6]=June {0,number,#}
+month[\=7]=July {0,number,#}
+month[\=8]=August {0,number,#}
+month[\=9]=September {0,number,#}
+month[\=10]=October {0,number,#}
+month[\=11]=November {0,number,#}
+month[\=12]=December {0,number,#}
diff --git a/www-server/src/main/resources/fr/agrometinfo/www/server/i18n_fr.properties b/www-server/src/main/resources/fr/agrometinfo/www/server/i18n_fr.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ed0220468d9c953c91a1b7dce68713bd433cfd7b
--- /dev/null
+++ b/www-server/src/main/resources/fr/agrometinfo/www/server/i18n_fr.properties
@@ -0,0 +1,13 @@
+# Ce fichier est encodé en UTF-8
+month[\=1]=Janvier {0,number,#}
+month[\=2]=Février {0,number,#}
+month[\=3]=Mars {0,number,#}
+month[\=4]=Avril {0,number,#}
+month[\=5]=Mai {0,number,#}
+month[\=6]=Juin {0,number,#}
+month[\=7]=Juillet {0,number,#}
+month[\=8]=Août {0,number,#}
+month[\=9]=Septembre {0,number,#}
+month[\=10]=Octobre {0,number,#}
+month[\=11]=Novembre {0,number,#}
+month[\=12]=Décembre {0,number,#}
diff --git a/www-server/src/test/java/fr/agrometinfo/www/server/I18nTest.java b/www-server/src/test/java/fr/agrometinfo/www/server/I18nTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b1a6f01e9626aa05d7d8c269d7068442a4ba2d3
--- /dev/null
+++ b/www-server/src/test/java/fr/agrometinfo/www/server/I18nTest.java
@@ -0,0 +1,162 @@
+package fr.agrometinfo.www.server;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.ResourceBundle;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import fr.agrometinfo.www.server.I18n.Operator;
+
+/**
+ * Test plural form handling with I18n.
+ */
+class I18nTest {
+
+    /**
+     * Name of test bundle.
+     */
+    private static final String NAME = "fr.agrometinfo.www.server.test";
+
+    /**
+     * Key for plural messages to test.
+     */
+    private static final String KEY = "cartItems";
+
+    /**
+     * {@link MethodSource} annotation marks this method as parameters provider.
+     *
+     * @return combinaisons of nb, key, expected translation
+     */
+    static Stream<Arguments> formatPluralData() {
+        return Stream.of(//
+                Arguments.of(1, KEY, "Il y a un produit dans votre panier."), //
+                Arguments.of(2, KEY, "Il y a deux produits dans votre panier."), //
+                Arguments.of(3, KEY, "Il y a 3 produits dans votre panier, ce qui est peu."), //
+                Arguments.of(42, KEY, "Il y a 42 produits dans votre panier, ce qui est un nombre spécial."), //
+                Arguments.of(101, KEY, "Il y a 101 produits dans votre panier, ce qui est beaucoup."), //
+                Arguments.of(1314, KEY, "Il y a 1 314 produits dans votre panier, ce qui est beaucoup."), //
+                Arguments.of(1, "cats", "Un chat"), //
+                // Variation is not present, default value.
+                Arguments.of(2, "cats", "2 chats"), //
+                Arguments.of(1, "comparison", "Valeur == 1"), //
+                Arguments.of(10, "comparison", "Valeur >= 10"), //
+                Arguments.of(11, "comparison", "Valeur > 10"), //
+                Arguments.of(-10, "comparison", "Valeur <= -10"), //
+                Arguments.of(-101, "comparison", "Valeur < -100") //
+                );
+    }
+
+    /**
+     * French translations.
+     */
+    private final I18n res = new I18n(NAME, Locale.FRENCH);
+
+    @Test
+    void contructorWithResourceBundle() {
+        final ResourceBundle bundle = ResourceBundle.getBundle(NAME, Locale.FRENCH);
+        final I18n res = new I18n(bundle);
+        String actual;
+        String expected;
+        actual = res.get("error.title");
+        expected = "Erreur";
+        assertEquals(expected, actual);
+
+        actual = res.get("not.translated");
+        expected = "This message is not translated.";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    void format() {
+        final String actual = res.format("warning.missing", "climat", 1, "WIND");
+        final String expected = "climat : ligne 1 : WIND manque.";
+        assertEquals(expected, actual);
+    }
+
+    @ParameterizedTest(name = "formatPluralDefault {index}: {0} {1}")
+    @MethodSource("formatPluralData")
+    void formatPluralDefault(final int nb, final String key, final String expected) {
+        final String actual = res.format(nb, key, nb);
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    void formatPluralSpecialDefaultProperties() {
+        final int nb = 42;
+        final I18n korea = new I18n(NAME, Locale.KOREA);
+        final String actual = korea.format(nb, KEY, nb);
+        final String expected = "There are 42 items in your cart, a special number!";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    void getStringDefault() {
+        final String actual = res.get("not.translated");
+        final String expected = "This message is not translated.";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    void getStringExisting() {
+        final String actual = res.get("error.title");
+        final String expected = "Erreur";
+        assertEquals(expected, actual);
+    }
+
+    @Test
+    void matches() {
+        final Map<String, Integer> doesMatch = new HashMap<>();
+        doesMatch.put("=1", 1);
+        doesMatch.put(">0", 1);
+        doesMatch.put(">=0", 1);
+        doesMatch.put(">=1", 1);
+        doesMatch.put("<0", -1);
+        doesMatch.put("<=0", -1);
+        doesMatch.put("<=1", -1);
+        doesMatch.put("<-100", -101);
+        doesMatch.forEach((comparison, plural) -> {
+            final boolean actual = I18n.matches(comparison, plural);
+            assertTrue(actual, comparison + " must be true for " + plural);
+        });
+        final Map<String, Integer> dontMatch = new HashMap<>();
+        dontMatch.put("=0", 1);
+        dontMatch.put(">1", 1);
+        dontMatch.put(">2", 1);
+        dontMatch.put(">=2", 1);
+        dontMatch.put("<-1", -1);
+        dontMatch.put("<-2", -1);
+        dontMatch.put("<=-2", -1);
+        dontMatch.forEach((comparison, plural) -> {
+            final boolean actual = I18n.matches(comparison, plural);
+            assertFalse(actual, comparison + " must be false for " + plural);
+        });
+    }
+
+    @Test
+    void operatorExtract() {
+        final Map<String, I18n.Operator> operators = new HashMap<>();
+        operators.put("1", null);
+        operators.put("=1", I18n.Operator.AEQ);
+        operators.put(">0", I18n.Operator.ESUP);
+        operators.put(">=0", I18n.Operator.DSUPEQ);
+        operators.put(">=1", I18n.Operator.DSUPEQ);
+        operators.put("<0", I18n.Operator.CINF);
+        operators.put("<=0", I18n.Operator.BINFEQ);
+        operators.forEach((comparison, expected) -> {
+            final Optional<Operator> res = I18n.Operator.extract(comparison);
+            final I18n.Operator actual = res.orElse(null);
+            assertEquals(expected, actual, expected + " must be extracted from " + comparison);
+        });
+    }
+}
diff --git a/www-server/src/test/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernateTest.java b/www-server/src/test/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernateTest.java
index 69f4eb3bf3d476705edd41a80d04ab3a48f894f0..8b7ffa6663ddb7eb889551dc08df60c88c1d61d1 100644
--- a/www-server/src/test/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernateTest.java
+++ b/www-server/src/test/java/fr/agrometinfo/www/server/dao/DailyValueDaoHibernateTest.java
@@ -21,6 +21,16 @@ class DailyValueDaoHibernateTest {
      */
     private final IndicatorDao indicatorDao = new IndicatorDaoHibernate();
 
+    @Test
+    void findAverageComputedValue() {
+        final var indicator = indicatorDao.findByCodeAndPeriod("rainsum", "year");
+        final var date = dao.findLastDate(indicator, 2023);
+        final var region = dao.findRegions().get(0);
+        final var actual = dao.findAverageComputedValue(indicator, date, (int) region.getId());
+        final Double expected = 22.d;
+        assertEquals(expected, actual);
+    }
+
     @Test
     void findIndicators() {
         final var actual = dao.findIndicators();
diff --git a/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java b/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc9a3654e84d3a30d6cee208964d182ed20fd951
--- /dev/null
+++ b/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java
@@ -0,0 +1,40 @@
+package fr.agrometinfo.www.server.dao;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.jupiter.api.Test;
+
+import fr.agrometinfo.www.server.model.Indicator;
+
+/**
+ * Test {@link MonthlyValueDao} Hibernate implementation.
+ */
+class MonthlyValueDaoHibernateTest {
+    /**
+     * DAO for computed values.
+     */
+    private final DailyValueDao dailyValueDao = new DailyValueDaoHibernate();
+
+    /**
+     * DAO to test.
+     */
+    private final MonthlyValueDao dao = new MonthlyValueDaoHibernate();
+
+    /**
+     * DAO for {@link Indicator}.
+     */
+    private final IndicatorDao indicatorDao = new IndicatorDaoHibernate();
+
+    @Test
+    void find() {
+        final var indicator = indicatorDao.findByCodeAndPeriod("rainsum", "year");
+        final var date = dailyValueDao.findLastDate(indicator, 2023);
+        final var region = dailyValueDao.findRegions().get(0);
+        final var actual = dao.find(indicator, region, date);
+        assertNotNull(actual);
+        assertEquals(1, actual.size());
+        final Float expected = (0 + 0 + 10 + 22) / 4.f;
+        assertEquals(expected, actual.get(0).getValue());
+    }
+}
diff --git a/www-server/src/test/resources/fr/agrometinfo/www/server/test.properties b/www-server/src/test/resources/fr/agrometinfo/www/server/test.properties
new file mode 100644
index 0000000000000000000000000000000000000000..15a4e5393a7c16528a914ad4ba2fc18f4e9abc09
--- /dev/null
+++ b/www-server/src/test/resources/fr/agrometinfo/www/server/test.properties
@@ -0,0 +1,16 @@
+cartItems=There are {0,number} items in your cart.
+cartItems=There are {0,number} items in your cart, which are many.
+cartItems[\=0]=There are no items in your cart.
+cartItems[\=1]=There is one item in your cart.
+cartItems[\=2]=There are two items in your cart.
+cartItems[\=3]=There are {0,number} items in your cart, which are few.
+cartItems[\=42]=There are {0,number} items in your cart, a special number!
+cats={0,number} cats
+cats[\=1]=One cat
+date.iso_local_date_time=2018-08-27T11:46:30
+date.yyyyMMddHHmmss=20180827114630
+not.translated=This message is not translated.
+error.title=Error
+warning.missing={0}: line {1}: {2} is missing
+build.date=2018-08-28 14:59:30
+version=1.2.3
\ No newline at end of file
diff --git a/www-server/src/test/resources/fr/agrometinfo/www/server/test_fr.properties b/www-server/src/test/resources/fr/agrometinfo/www/server/test_fr.properties
new file mode 100644
index 0000000000000000000000000000000000000000..4a1e24b43fbd13b7ab1d5876f54096f8f36dd19b
--- /dev/null
+++ b/www-server/src/test/resources/fr/agrometinfo/www/server/test_fr.properties
@@ -0,0 +1,17 @@
+cartItems=Il y a {0,number} produits dans votre panier.
+cartItems=Il y a {0,number} produits dans votre panier, ce qui est beaucoup.
+cartItems[\=0]=Il n'y a aucun produit dans votre panier.
+cartItems[\=1]=Il y a un produit dans votre panier.
+cartItems[\=2]=Il y a deux produits dans votre panier.
+cartItems[\=3]=Il y a {0,number} produits dans votre panier, ce qui est peu.
+cartItems[\=42]=Il y a 42 produits dans votre panier, ce qui est un nombre spécial.
+cats={0,number} chats
+cats[\=1]=Un chat
+comparison=Valeur par défaut pour {0,number}
+comparison[<-100]=Valeur < -100
+comparison[<\=-10]=Valeur <= -10
+comparison[\=1]=Valeur == 1
+comparison[>\=10]=Valeur >= 10
+comparison[>10]=Valeur > 10
+error.title=Erreur
+warning.missing={0}\u00a0: ligne {1}\u00a0: {2} manque.
diff --git a/www-shared/config/pmd-suppressions.properties b/www-shared/config/pmd-suppressions.properties
index 46a40bd59b544b7a41a2074494d7ecb35f6db349..86faec274b17c99d94ed5ed9b248e28b029259af 100644
--- a/www-shared/config/pmd-suppressions.properties
+++ b/www-shared/config/pmd-suppressions.properties
@@ -1,11 +1,17 @@
 # See https://maven.apache.org/plugins/maven-pmd-plugin/examples/violation-exclusions.html
 # annotations generate not clean code
+fr.agrometinfo.www.shared.dto.ChoiceDTOBeanJsonDeserializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.ChoiceDTOBeanJsonSerializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.ChoiceDTO_MapperImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.IndicatorDTOBeanJsonDeserializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.IndicatorDTOBeanJsonSerializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.IndicatorDTO_MapperImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonDeserializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonSerializerImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.dto.PeriodDTO_MapperImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonDeserializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonSerializerImpl=UnnecessaryImport
+fr.agrometinfo.www.shared.dto.SummaryDTO_MapperImpl=UnnecessaryImport
 fr.agrometinfo.www.shared.service.IndicatorServiceFactory=UnnecessaryImport
 org.geojson.FeatureBeanJsonDeserializerImpl=UnnecessaryImport
 org.geojson.FeatureBeanJsonSerializerImpl=UnnecessaryImport
diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java
index 97ba997fcd50d332d4719fb32809ba1953d88adf..0794bbcb3deb6d530d51868afd77e9c64905eddb 100644
--- a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java
+++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java
@@ -1,16 +1,21 @@
 package fr.agrometinfo.www.shared.dto;
 
+import org.dominokit.jackson.annotation.JSONMapper;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
 /**
  * Choice from user to get indicators.
  *
  * @author Olivier Maury
  */
+@JSONMapper
 public final class ChoiceDTO {
 
     /**
      * The user wants to compare with normal.
      */
-    private boolean comparison = false;
+    private Boolean comparison = Boolean.FALSE;
 
     /**
      * ID of chosen indicator.
@@ -36,7 +41,7 @@ public final class ChoiceDTO {
      * @return true if the user wants to compare with normal.
      */
     public boolean getComparison() {
-        return comparison;
+        return Boolean.TRUE.equals(comparison);
     }
 
     /**
@@ -70,6 +75,7 @@ public final class ChoiceDTO {
     /**
      * @return the user chose all options
      */
+    @JsonIgnore
     public boolean isValid() {
         return period != null && !period.trim().isEmpty() //
                 && indicator != null && !indicator.trim().isEmpty() //
diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..94ff1482e54fe6c784c49d946ebc350e0a8d3b9d
--- /dev/null
+++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java
@@ -0,0 +1,141 @@
+package fr.agrometinfo.www.shared.dto;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.dominokit.jackson.annotation.JSONMapper;
+
+/**
+ * Values to display according to user choice ({@link ChoiceDTO}).
+ *
+ * @author Olivier Maury
+ */
+@JSONMapper
+public class SummaryDTO {
+    /**
+     * Average daily value of the indicator for the user choice.
+     */
+    private Float averageValue;
+    /**
+     * User choice.
+     */
+    private ChoiceDTO choice;
+    /**
+     * Date of the last simulation.
+     */
+    private Date date;
+    /**
+     * Chosen indicator.
+     */
+    private IndicatorDTO indicator;
+    /**
+     * Monthly values of the indicator for the user choice.
+     */
+    private Map<String, Float> monthlyValues;
+    /**
+     * Period name.
+     */
+    private String period;
+    /**
+     * Region name.
+     */
+    private String region;
+
+    /**
+     * @return Average daily value of the indicator for the user choice.
+     */
+    public final Float getAverageValue() {
+        return averageValue;
+    }
+
+    /**
+     * @return User choice.
+     */
+    public final ChoiceDTO getChoice() {
+        return choice;
+    }
+
+    /**
+     * @return Date of the last simulation.
+     */
+    public final Date getDate() {
+        return date;
+    }
+
+    /**
+     * @return Chosen indicator.
+     */
+    public final IndicatorDTO getIndicator() {
+        return indicator;
+    }
+
+    /**
+     * @return Monthly values of the indicator for the user choice.
+     */
+    public final Map<String, Float> getMonthlyValues() {
+        return monthlyValues;
+    }
+
+    /**
+     * @return period name
+     */
+    public String getPeriod() {
+        return period;
+    }
+
+    /**
+     * @return Region name.
+     */
+    public final String getRegion() {
+        return region;
+    }
+
+    /**
+     * @param value Average daily value of the indicator for the user choice.
+     */
+    public final void setAverageValue(final Float value) {
+        this.averageValue = value;
+    }
+
+    /**
+     * @param value User choice.
+     */
+    public final void setChoice(final ChoiceDTO value) {
+        this.choice = value;
+    }
+
+    /**
+     * @param value Date of the last simulation.
+     */
+    public final void setDate(final Date value) {
+        this.date = value;
+    }
+
+    /**
+     * @param value Chosen indicator.
+     */
+    public final void setIndicator(final IndicatorDTO value) {
+        this.indicator = value;
+    }
+
+    /**
+     * @param values Monthly values of the indicator for the user choice.
+     */
+    public final void setMonthlyValues(final Map<String, Float> values) {
+        this.monthlyValues = values;
+    }
+
+    /**
+     * @param name period name
+     */
+    public final void setPeriod(final String name) {
+        this.period = name;
+    }
+
+    /**
+     * @param name Region name.
+     */
+    public final void setRegion(final String name) {
+        this.region = name;
+    }
+}
diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java
index b3a60eae1007fe7618c7bc8b9907694bf3628d76..58cefcad7637affdd3ce5eaae0b8adb78bda166e 100644
--- a/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java
+++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java
@@ -11,6 +11,7 @@ import org.dominokit.rest.shared.request.service.annotations.RequestFactory;
 import org.geojson.FeatureCollection;
 
 import fr.agrometinfo.www.shared.dto.PeriodDTO;
+import fr.agrometinfo.www.shared.dto.SummaryDTO;
 
 /**
  * Interface for client and server resource.
@@ -29,13 +30,19 @@ public interface IndicatorService {
      */
     String PATH_LIST = "list";
     /**
-     * Path for {@link IndicatorService#getValues()}.
+     * Path for
+     * {@link IndicatorService#getValues(String, String, Integer, Integer, Boolean)}.
      */
     String PATH_VALUES = "values";
     /**
      * Path for {@link IndicatorService#getRegions()}.
      */
     String PATH_REGIONS = "regions";
+    /**
+     * Path for
+     * {@link IndicatorService#getSummary(String, String, Integer, Integer)}.
+     */
+    String PATH_SUMMARY = "summary";
     /**
      * Path for {@link IndicatorService#getYears()}.
      */
@@ -55,6 +62,19 @@ public interface IndicatorService {
     @Path(PATH_REGIONS)
     Map<String, String> getRegions();
 
+    /**
+     * @param indicator indicator coe
+     * @param period    period code
+     * @param region    region ID
+     * @param year      year
+     * @return indicator summary for the user choice.
+     */
+    @GET
+    @Path(PATH_SUMMARY)
+    SummaryDTO getSummary(@QueryParam(value = "indicator") String indicator,
+            @QueryParam(value = "period") String period, @QueryParam(value = "region") Integer region,
+            @QueryParam(value = "year") Integer year);
+
     /**
      * @param indicator  indicator coe
      * @param period     period code