r1977 - in trunk: wao-persistence/src/main/java/fr/ifremer/wao/entity wao-services/src/main/java/fr/ifremer/wao/services wao-services/src/main/java/fr/ifremer/wao/services/service wao-services/src/main/java/fr/ifremer/wao/services/utils wao-services/src/main/resources/i18n wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer wao-web/src/main/java/fr/ifremer/wao/web/converter wao-web/src/main/resources/fr/ifremer/wao/services/service wao-web/src/main/webapp wao-web/src/main/webapp/WEB-INF/con
Author: bleny Date: 2014-05-23 12:27:23 +0200 (Fri, 23 May 2014) New Revision: 1977 Url: http://forge.codelutin.com/projects/wao/repository/revisions/1977 Log: refs #4493 start first bar chart Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSynthesis.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/SynthesisService.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/ trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/BarChartData.java trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/ChartDataAxis.java trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/SynthesisAction.java trunk/wao-web/src/main/java/fr/ifremer/wao/web/converter/BarChartDataConverter.java trunk/wao-web/src/main/resources/fr/ifremer/wao/services/service/ObsMerSynthesis-conversion.properties trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/synthesis.jsp Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/ContactTopiaDao.java trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SampleRowTopiaDao.java trunk/wao-services/src/main/resources/i18n/wao-services_en_GB.properties trunk/wao-services/src/main/resources/i18n/wao-services_fr_FR.properties trunk/wao-web/src/main/webapp/WEB-INF/decorators/layout.jsp trunk/wao-web/src/main/webapp/wao.css Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/ContactTopiaDao.java =================================================================== --- trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/ContactTopiaDao.java 2014-05-23 10:06:09 UTC (rev 1976) +++ trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/ContactTopiaDao.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -26,6 +26,8 @@ import fr.ifremer.wao.ContactsFilter; import fr.ifremer.wao.WaoUtils; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.Range; +import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.topia.persistence.HqlAndParametersBuilder; @@ -34,8 +36,12 @@ import org.nuiton.topia.persistence.pager.TopiaPagerBean; import org.nuiton.util.PagerBeanUtil; +import java.util.Calendar; import java.util.Collection; +import java.util.Date; import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; public class ContactTopiaDao extends AbstractContactTopiaDao<Contact> { @@ -226,4 +232,29 @@ return query.findFirstOrNull(); } + public SortedMap<Date, Integer> getActualObservationsByMonths(Date periodFromMonth, Date periodToMonth, ContactsFilter filter) { + + HqlAndParametersBuilder<Contact> query = toSampleRowHqlAndParametersBuilder(filter); + query.addEquals(Contact.PROPERTY_STATE, ContactState.OBSERVATION_DONE.ordinal()); + List<Contact> contacts = findAll(query.getHql(), query.getHqlParameters()); + + SortedMap<Date, Integer> actualObservationsMyMonths = new TreeMap<>(); + Range<Date> range = Range.between(periodFromMonth, periodToMonth); + + for (Contact contact : contacts) { + Date contactMonth = DateUtils.truncate(contact.getObservationBeginDate(), Calendar.MONTH); + if (range.contains(contactMonth)) { + Integer count = actualObservationsMyMonths.get(contactMonth); + if (count == null) { + count = 0; + } + count += 1; + actualObservationsMyMonths.put(contactMonth, count); + + } + } + + return actualObservationsMyMonths; + + } } Modified: trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SampleRowTopiaDao.java =================================================================== --- trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SampleRowTopiaDao.java 2014-05-23 10:06:09 UTC (rev 1976) +++ trunk/wao-persistence/src/main/java/fr/ifremer/wao/entity/SampleRowTopiaDao.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -34,7 +34,11 @@ import java.util.Calendar; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; public class SampleRowTopiaDao extends AbstractSampleRowTopiaDao<SampleRow> { @@ -80,12 +84,12 @@ if (filter.getPeriodFrom() != null) { Date periodFromMonth = DateUtils.truncate(filter.getPeriodFrom(), Calendar.MONTH); - query.addWhereClause("sr." + SampleRow.PROPERTY_PERIOD_END + " >= :periodFromMonth", ImmutableMap.of("periodFromMonth", (Object) periodFromMonth)); + query.addGreaterOrEquals(SampleRow.PROPERTY_PERIOD_END, periodFromMonth); } if (filter.getPeriodTo() != null) { Date periodToMonth = DateUtils.truncate(filter.getPeriodTo(), Calendar.MONTH); - query.addWhereClause("sr." + SampleRow.PROPERTY_PERIOD_BEGIN + " <= :periodToMonth", ImmutableMap.of("periodToMonth", (Object) periodToMonth)); + query.addLowerOrEquals(SampleRow.PROPERTY_PERIOD_BEGIN, periodToMonth); } if (CollectionUtils.isNotEmpty(filter.getSampleRowCodes())) { @@ -152,4 +156,44 @@ topiaHibernateSupport.getHibernateSession().evict(sampleRow); } + public SortedMap<Date, Integer> getExpectedObservationsByMonths(Date periodFromMonth, Date periodToMonth, SampleRowsFilter sampleRowFilter) { + + HqlAndParametersBuilder<SampleRow> sampleRowsQuery = + toSampleRowHqlAndParametersBuilder(sampleRowFilter); + + String selectSumClause; + if (sampleRowFilter.getObsProgram().isObsMer()) { + selectSumClause = "sum(sm.expectedTidesValue)"; + } else if (sampleRowFilter.getObsProgram().isObsVente()) { + selectSumClause = "sum(sm.expectedTidesValue * sr2.averageObservationsCount)"; + } else { + throw new UnsupportedOperationException(); + } + + String hql = "select sm.periodDate, " + selectSumClause + " " + + newFromClause("sr2") + " left join sr2.sampleMonth sm " + + "where sr2.topiaId in (select sr.topiaId " + sampleRowsQuery.getHql() + ") " + + " and sm.periodDate between :periodFromMonth2 and :periodToMonth2 " + + "group by sm.periodDate " + + "order by sm.periodDate"; + + Map<String, Object> hqlParameters = new HashMap<>(sampleRowsQuery.getHqlParameters()); + hqlParameters.put("periodFromMonth2", periodFromMonth); + hqlParameters.put("periodToMonth2", periodToMonth); + + if (log.isTraceEnabled()) { + log.trace("to compute expected tides value, will run query: " + hql + hqlParameters); + } + + List<Object[]> result = findAll(hql, hqlParameters); + + SortedMap<Date, Integer> expectedObservationsByMonths = new TreeMap<>(); + for (Object[] line : result) { + Date month = (Date)line[0]; + int expectedValue = ((Long) line[1]).intValue(); + expectedObservationsByMonths.put(month, expectedValue); + } + + return expectedObservationsByMonths; + } } Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSynthesis.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSynthesis.java (rev 0) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/ObsMerSynthesis.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,16 @@ +package fr.ifremer.wao.services.service; + +import fr.ifremer.wao.services.utils.BarChartData; + +public class ObsMerSynthesis { + + protected BarChartData expectedVsActualObservationsByMonthsBarChartData; + + public void setExpectedVsActualObservationsByMonthsBarChartData(BarChartData expectedVsActualObservationsByMonthsBarChartData) { + this.expectedVsActualObservationsByMonthsBarChartData = expectedVsActualObservationsByMonthsBarChartData; + } + + public BarChartData getExpectedVsActualObservationsByMonthsBarChartData() { + return expectedVsActualObservationsByMonthsBarChartData; + } +} Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/SynthesisService.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/SynthesisService.java (rev 0) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/service/SynthesisService.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,109 @@ +package fr.ifremer.wao.services.service; + +import fr.ifremer.wao.ContactsFilter; +import fr.ifremer.wao.WaoUtils; +import fr.ifremer.wao.entity.ContactTopiaDao; +import fr.ifremer.wao.entity.SampleRowTopiaDao; +import fr.ifremer.wao.services.AuthenticatedWaoUser; +import fr.ifremer.wao.services.utils.BarChartData; +import fr.ifremer.wao.services.utils.ChartDataAxis; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.i18n.I18n; + +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.SortedMap; + +public class SynthesisService extends WaoServiceSupport { + + private static final Log log = LogFactory.getLog(SynthesisService.class); + + public ContactsFilter newFilter(AuthenticatedWaoUser authenticatedWaoUser) { + + ObsMerContactsService obsMerContactsService = newService(ObsMerContactsService.class); + + ContactsFilter newFilter = obsMerContactsService.newContactFilter(authenticatedWaoUser); + + return newFilter; + + } + + public ObsMerSynthesis getObsMerSynthesis(ContactsFilter filter) { + + ObsMerSynthesis obsMerSynthesis = new ObsMerSynthesis(); + + BarChartData expectedVsActualObservationsByMonthsBarChartData = getExpectedVsActualObservationsByMonthsBarChartData(filter); + obsMerSynthesis.setExpectedVsActualObservationsByMonthsBarChartData(expectedVsActualObservationsByMonthsBarChartData); + + return obsMerSynthesis; + + } + + /** + * Un graphique avec, pour chaque mois, deux barres qui représentent l'effort demandé + * vs l'effort réalisé. + */ + protected BarChartData getExpectedVsActualObservationsByMonthsBarChartData(ContactsFilter filter) { + + Locale locale = serviceContext.getLocale(); + + // définition de la fenêtre + Date periodFromMonth = DateUtils.truncate(filter.getPeriodFrom(), Calendar.MONTH); + Date periodToMonth = DateUtils.truncate(filter.getPeriodTo(), Calendar.MONTH); + + // Calcul du programmé + SampleRowTopiaDao dao = getSampleRowDao(); + SortedMap<Date, Integer> expectedObservationsByMonths = + dao.getExpectedObservationsByMonths(periodFromMonth, periodToMonth, filter.getSampleRowFilter()); + + // Calcul du réalisé + ContactTopiaDao contactDao = getContactDao(); + SortedMap<Date, Integer> actualObservationsMyMonths = + contactDao.getActualObservationsByMonths(periodFromMonth, periodToMonth, filter); + +// if (log.isTraceEnabled()) { +// DateFormat dateFormat = new SimpleDateFormat(monthsPeriod.getPattern()); +// for (Date month : monthsPeriod.getMonths()) { +// log.trace("for month " + dateFormat.format(month) +// + " expected is " + expectedObservationsByMonths.get(month) +// + " actual is " + actualObservationsMyMonths.get(month)); +// } +// } + + BarChartData.BarChartDataSeries expectedObservationsByMonthsBarChartDataSeries = + new BarChartData.BarChartDataSeries(); + expectedObservationsByMonthsBarChartDataSeries.setLabel(I18n.l(locale, "wao.synthesis.planned")); + for (Map.Entry<Date, Integer> expectedObservationMonth : expectedObservationsByMonths.entrySet()) { + Date month = expectedObservationMonth.getKey(); + String tick = WaoUtils.formatMonth(locale, month); + double value = expectedObservationMonth.getValue().doubleValue(); + expectedObservationsByMonthsBarChartDataSeries.addValue(tick, value); + } + + BarChartData.BarChartDataSeries actualObservationsMyMonthsBarChartDataSeries = + new BarChartData.BarChartDataSeries(); + actualObservationsMyMonthsBarChartDataSeries.setLabel(I18n.l(locale, "wao.synthesis.estimated")); + for (Map.Entry<Date, Integer> actualObservationsMyMonth : actualObservationsMyMonths.entrySet()) { + Date month = actualObservationsMyMonth.getKey(); + String tick = WaoUtils.formatMonth(locale, month); + double value = actualObservationsMyMonth.getValue().doubleValue(); + actualObservationsMyMonthsBarChartDataSeries.addValue(tick, value); + } + + BarChartData expectedVsActualObservationsByMonthsBarChartData = new BarChartData(""); + + ChartDataAxis yAxis = expectedVsActualObservationsByMonthsBarChartData.getYAxis(); + yAxis.setLabel(I18n.l(locale, "wao.synthesis.observationsCount")); + yAxis.setStep(10); + + expectedVsActualObservationsByMonthsBarChartData.addDotChartDataSeries(expectedObservationsByMonthsBarChartDataSeries); + expectedVsActualObservationsByMonthsBarChartData.addDotChartDataSeries(actualObservationsMyMonthsBarChartDataSeries); + + return expectedVsActualObservationsByMonthsBarChartData; + + } +} Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/BarChartData.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/BarChartData.java (rev 0) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/BarChartData.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,164 @@ +package fr.ifremer.wao.services.utils; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class BarChartData implements Serializable { + + protected boolean includeOriginInAxises = true; + + protected String title; + + protected List<BarChartDataSeries> barChartDataSeriesForYAxis; + + protected List<BarChartDataSeries> barChartDataSeriesForY2Axis; + + protected ChartDataAxis yAxis; + + protected ChartDataAxis y2Axis; + + public BarChartData(String title) { + this.title = title; + barChartDataSeriesForYAxis = Lists.newLinkedList(); + barChartDataSeriesForY2Axis = Lists.newLinkedList(); + yAxis = new ChartDataAxis(); + y2Axis = new ChartDataAxis(); + } + + public void addDotChartDataSeries(BarChartDataSeries barChartDataSeries) { + barChartDataSeriesForYAxis.add(barChartDataSeries); + } + + public void addDotChartDataSeriesForY2Axis(BarChartDataSeries barChartDataSeries) { + barChartDataSeriesForY2Axis.add(barChartDataSeries); + } + + public void computeAxises() { + + if (includeOriginInAxises) { + yAxis.addValue(0); + y2Axis.addValue(0); + } + + for (BarChartDataSeries series : barChartDataSeriesForYAxis) { + for (double value : series.getValuesByTick().values()) { + yAxis.addValue(value); + } + } + + for (BarChartDataSeries series : barChartDataSeriesForY2Axis) { + for (double value : series.getValuesByTick().values()) { + y2Axis.addValue(value); + } + } + + yAxis.computeAxis(); + y2Axis.computeAxis(); + + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public ChartDataAxis getYAxis() { + return yAxis; + } + + public ChartDataAxis getY2Axis() { + return y2Axis; + } + + public boolean isTwoYAxis() { + return ! barChartDataSeriesForY2Axis.isEmpty(); + } + + public List<BarChartDataSeries> getBarChartDataSeriesForYAxis() { + return barChartDataSeriesForYAxis; + } + + public List<BarChartDataSeries> getBarChartDataSeriesForY2Axis() { + return barChartDataSeriesForY2Axis; + } + + public boolean isIncludeOriginInAxises() { + return includeOriginInAxises; + } + + public void setIncludeOriginInAxises(boolean includeOriginInAxises) { + this.includeOriginInAxises = includeOriginInAxises; + } + + public Set<String> getTicks() { + Set<String> ticks = Sets.newLinkedHashSet(); + + for (BarChartDataSeries series : barChartDataSeriesForYAxis) { + + ticks.addAll(series.getTicks()); + + } + + for (BarChartDataSeries series : barChartDataSeriesForY2Axis) { + + ticks.addAll(series.getTicks()); + + } + + return ticks; + } + + public static class BarChartDataSeries { + + protected String label; + + protected String type; + + protected Map<String, Double> valuesByTick; + + public BarChartDataSeries() { + this.valuesByTick = Maps.newLinkedHashMap(); + } + + public void addValue(String tick, double value) { + valuesByTick.put(tick, value); + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Map<String, Double> getValuesByTick() { + return valuesByTick; + } + + public Set<String> getTicks() { + return valuesByTick.keySet(); + } + + public Double getValue(String tick) { + return valuesByTick.get(tick); + } + } +} \ No newline at end of file Added: trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/ChartDataAxis.java =================================================================== --- trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/ChartDataAxis.java (rev 0) +++ trunk/wao-services/src/main/java/fr/ifremer/wao/services/utils/ChartDataAxis.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,102 @@ +package fr.ifremer.wao.services.utils; + +public class ChartDataAxis { + + protected String label; + + protected double min; + + protected double max; + + protected double step; + + protected int numberTricks; + + public ChartDataAxis () { + this.label = ""; + } + + public void addValue(double value) { + + if (min == 0 && max == 0) { + + min = ((int) (value / step) ) * step; + + max = ((int) (value / step) + 1 ) * step; + + } else { + + if (value < min) { + min = ((int) (value / step) ) * step; + } + + if (value > max) { + max = ((int) (value / step) + 1 ) * step; + } + } + + } + + public void computeAxis() { + numberTricks = 0; + + int countStep = (int)((max - min) / step); + + if (countStep > 12) { + while (numberTricks == 0){ + + for (int countStepGrap = 13; countStepGrap >= 7; countStepGrap--) { + if (numberTricks == 0 && countStep % countStepGrap == 0) { + numberTricks = countStepGrap + 1; + break; + } + } + if (numberTricks == 0) { + countStep++; + max += step; + } + + } + + } else { + switch (countStep) { + case 1 : numberTricks = 11; break; + case 2 : numberTricks = 11; break; + case 3 : numberTricks = 13; break; + case 4 : numberTricks = 9; break; + case 5 : numberTricks = 11; break; + case 6 : numberTricks = 13; break; + default: numberTricks = countStep + 1; + } + } + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public double getMin() { + return min; + } + + public double getMax() { + return max; + } + + public double getStep() { + return step; + } + + public void setStep(double step) { + this.step = step; + } + + public int getNumberTicks() { + return numberTricks; + + } +} Modified: trunk/wao-services/src/main/resources/i18n/wao-services_en_GB.properties =================================================================== --- trunk/wao-services/src/main/resources/i18n/wao-services_en_GB.properties 2014-05-23 10:06:09 UTC (rev 1976) +++ trunk/wao-services/src/main/resources/i18n/wao-services_en_GB.properties 2014-05-23 10:27:23 UTC (rev 1977) @@ -84,5 +84,8 @@ wao.import.sampleRow.failure.unknownTargetSpeciesDcfCode=Unknown target species code\: %s wao.import.sampleRow.failure.wrongFishingZone=There is no fishing zone with the code '%s' wao.import.sampleRow.failure.wrongSampleRowCodeFormat=The sample row code '%s' is not compliant with the format "YYYY_PIIII" +wao.synthesis.estimated=Estimated +wao.synthesis.observationsCount=Observations count +wao.synthesis.planned=Planned wao.validation.sampleRow.conflictOnObserver=Observer %s cannot be associated to the line %s because he has to observer, on the same day, for row %s wao.validation.sampleRow.observerNotInCompany=Observer %s doesn't work for company %s Modified: trunk/wao-services/src/main/resources/i18n/wao-services_fr_FR.properties =================================================================== --- trunk/wao-services/src/main/resources/i18n/wao-services_fr_FR.properties 2014-05-23 10:06:09 UTC (rev 1976) +++ trunk/wao-services/src/main/resources/i18n/wao-services_fr_FR.properties 2014-05-23 10:27:23 UTC (rev 1977) @@ -81,5 +81,8 @@ wao.import.sampleRow.failure.unknownTargetSpeciesDcfCode=Le code espèce cible %s est inconnu du référentiel wao.import.sampleRow.failure.wrongFishingZone=Le code '%s' ne correspond à aucune zone de pêche connue du référentiel wao.import.sampleRow.failure.wrongSampleRowCodeFormat=Le code '%s' n'est pas un code de ligne valide selon le format "AAAA_PIIII" +wao.synthesis.estimated=Estimé +wao.synthesis.observationsCount=Nombre d'observations +wao.synthesis.planned=Planifié wao.validation.sampleRow.conflictOnObserver=L'observateur %s ne peut être associé à la ligne %s car il doit observer, le même jour, pour la ligne %s wao.validation.sampleRow.observerNotInCompany=L'observateur %s ne fait pas parti de la société %s Added: trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/SynthesisAction.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/SynthesisAction.java (rev 0) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/action/obsmer/SynthesisAction.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,47 @@ +package fr.ifremer.wao.web.action.obsmer; + +import com.opensymphony.xwork2.Preparable; +import fr.ifremer.wao.ContactsFilter; +import fr.ifremer.wao.services.service.ObsMerSynthesis; +import fr.ifremer.wao.services.service.SynthesisService; +import fr.ifremer.wao.web.WaoJspActionSupport; + +public class SynthesisAction extends WaoJspActionSupport implements Preparable { + + protected ContactsFilter filter; + + protected SynthesisService service; + + protected ObsMerSynthesis synthesis; + + public void setService(SynthesisService service) { + this.service = service; + } + + public ContactsFilter getFilter() { + if (filter == null) { + prepare(); + } + return filter; + } + + @Override + public void prepare() { + + filter = service.newFilter(getAuthenticatedWaoUser()); + + } + + @Override + public String execute() { + + synthesis = service.getObsMerSynthesis(filter); + + return SUCCESS; + + } + + public ObsMerSynthesis getSynthesis() { + return synthesis; + } +} Added: trunk/wao-web/src/main/java/fr/ifremer/wao/web/converter/BarChartDataConverter.java =================================================================== --- trunk/wao-web/src/main/java/fr/ifremer/wao/web/converter/BarChartDataConverter.java (rev 0) +++ trunk/wao-web/src/main/java/fr/ifremer/wao/web/converter/BarChartDataConverter.java 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,148 @@ +package fr.ifremer.wao.web.converter; + +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import fr.ifremer.wao.WaoTechnicalException; +import fr.ifremer.wao.services.utils.BarChartData; +import fr.ifremer.wao.services.utils.ChartDataAxis; +import org.apache.commons.lang3.StringUtils; +import org.apache.struts2.util.StrutsTypeConverter; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class BarChartDataConverter extends StrutsTypeConverter { + + @Override + public Object convertFromString(Map context, String[] values, Class toClass) { + throw new UnsupportedOperationException(); + } + + @Override + public String convertToString(Map context, Object o) { + + if (o instanceof BarChartData) { + + BarChartData barChartData = (BarChartData) o; + + barChartData.computeAxises(); + + String data = toData(barChartData); + + String options = toOptions(barChartData); + + String result = data + ", " + options; + + return result; + + } else { + throw new WaoTechnicalException("unable to convert " + o); + } + } + + protected String toOptions(BarChartData barChartData) { + String options = ""; + options +="{\n"; + options +=" title: \"" + barChartData.getTitle() + "\",\n"; + options +=" seriesDefaults: {\n"; + options +=" renderer: $.jqplot.BarRenderer, \n"; + options +=" rendererOptions: { \n"; + options +=" highlightMouseOver: true, \n"; + options +=" barWidth: 10 \n"; + options +=" } \n"; + options +=" },\n"; + options +=" axesDefaults: {\n"; + options +=" tickRenderer: $.jqplot.CanvasAxisTickRenderer, \n"; + options +=" tickOptions: { \n"; + options +=" angle: -90, \n"; + options +=" fontSize: '10pt' \n"; + options +=" } \n"; + options +=" },\n"; + options +=" axes: {\n"; + options +=" xaxis: {\n"; + options +=" renderer: $.jqplot.CategoryAxisRenderer, \n"; + options +=" ticks: [\"" + Joiner.on("\", \"").join(barChartData.getTicks()) + "\"]" ; + options +=" },\n"; + + ChartDataAxis yaxis = barChartData.getYAxis(); + options +=" yaxis:{\n "; + options +=" min: " + yaxis.getMin() + ",\n"; + options +=" max: " + yaxis.getMax() + ",\n"; + options +=" numberTicks: " + yaxis.getNumberTicks() + ",\n"; + options +=" label: \"" + yaxis.getLabel() + "\"\n"; + options +=" },\n"; + + if (barChartData.isTwoYAxis()) { + + ChartDataAxis y2axis = barChartData.getY2Axis(); + options +=" y2axis:{\n "; + options +=" min: " + y2axis.getMin() + ",\n"; + options +=" max: " + y2axis.getMax() + ",\n"; + options +=" numberTicks: " + y2axis.getNumberTicks() + ",\n"; + options +=" label: \"" + y2axis.getLabel() + "\"\n"; + options +=" },\n"; + + } + + options +=" },\n"; + options +=" series: [\n"; + + for (BarChartData.BarChartDataSeries series : barChartData.getBarChartDataSeriesForYAxis()) { + + options +=" {\n"; + options +=" yaxis:\"yaxis\",\n"; + options +=" label: \"" + series.getLabel() + "\"\n"; + options +=" },\n"; + } + + for (BarChartData.BarChartDataSeries series : barChartData.getBarChartDataSeriesForY2Axis()) { + + options +=" {\n"; + options +=" yaxis:\"y2axis\",\n"; + options +=" label: \"" + series.getLabel() + "\"\n"; + options +=" },\n"; + } + + options +=" ],\n"; + options +=" legend: {\n"; + options +=" show: true,\n"; + options +=" placement: \"outsideGrid\",\n"; + options +=" location: \"s\",\n"; + options +=" rendererOptions: {\n"; + options +=" numberColumns: 2\n"; + options +=" },\n"; + options +=" renderer: $.jqplot.EnhancedLegendRenderer\n"; + options +=" }\n"; + options +="}\n"; + + return options; + } + + protected String toData(BarChartData barChartData) { + + Set<String> ticks = barChartData.getTicks(); + + List<String> series = new LinkedList<>(); + + List<BarChartData.BarChartDataSeries> barChartDataSeriesList = Lists.newLinkedList(); + barChartDataSeriesList.addAll(barChartData.getBarChartDataSeriesForYAxis()); + barChartDataSeriesList.addAll(barChartData.getBarChartDataSeriesForY2Axis()); + + for (BarChartData.BarChartDataSeries BarChartDataSeries : barChartDataSeriesList) { + List<String> bars = Lists.newLinkedList(); + for (String tick : ticks) { + Double value = BarChartDataSeries.getValue(tick); + if (value == null) { + bars.add("0"); + } else { + bars.add(value.toString()); + } + } + series.add("[" + StringUtils.join(bars, ", ") + "]"); + } + return "[" + StringUtils.join(series, ", ") + "]"; + } + +} \ No newline at end of file Added: trunk/wao-web/src/main/resources/fr/ifremer/wao/services/service/ObsMerSynthesis-conversion.properties =================================================================== --- trunk/wao-web/src/main/resources/fr/ifremer/wao/services/service/ObsMerSynthesis-conversion.properties (rev 0) +++ trunk/wao-web/src/main/resources/fr/ifremer/wao/services/service/ObsMerSynthesis-conversion.properties 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1 @@ +expectedVsActualObservationsByMonthsBarChartData=fr.ifremer.wao.web.converter.BarChartDataConverter Added: trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/synthesis.jsp =================================================================== --- trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/synthesis.jsp (rev 0) +++ trunk/wao-web/src/main/webapp/WEB-INF/content/obsmer/synthesis.jsp 2014-05-23 10:27:23 UTC (rev 1977) @@ -0,0 +1,101 @@ +<%-- + #%L + Wao :: Web + %% + Copyright (C) 2009 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> +<%@taglib uri="/struts-tags" prefix="s" %> + +<content tag="synthesisMenuItemClass">active</content> + +<html> + + <head> + <title> + <s:text name="wao.ui.page.Synthesis.title"/> + </title> + + <script src="<s:url value="/jqplot-1.0.8/jquery.jqplot.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.categoryAxisRenderer.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.pointLabels.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.canvasTextRenderer.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.canvasAxisLabelRenderer.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.canvasAxisTickRenderer.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.enhancedLegendRenderer.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.barRenderer.js" />"></script> + <script src="<s:url value="/jqplot-1.0.8/plugins/jqplot.barRenderer.js" />"></script> + <link rel="stylesheet" href="<s:url value="/jqplot-1.0.8/jquery.jqplot.css" />" /> + + + + <%-- + + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jquery.jqplot.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.core.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.linearTickGenerator.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.linearAxisRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.axisTickRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.axisLabelRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.tableLegendRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.lineRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.markerRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.divTitleRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.canvasGridRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.linePattern.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.shadowRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.shapeRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.sprintf.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jsdate.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.themeEngine.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.toImage.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.effects.core.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/jqplot.effects.blind.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.categoryAxisRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.pointLabels.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.canvasTextRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.canvasAxisTickRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.enhancedLegendRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.barRenderer.js"></script> + <script type="text/javascript" src="http://demo.codelutin.com/extranet-enc-ahi-latest/js/jqplot/plugins/jqplot.pieRenderer.js"></script> + + --%> + + <script type="text/javascript"> + + $(document).ready(function() { + + $.jqplot('expected-vs-actual-observations-by-months-chart', <s:property value="synthesis.expectedVsActualObservationsByMonthsBarChartData" escapeHtml="false"/>); + + }); + + </script> + </head> + + <content tag="mainClass"></content> + + <h2> + <s:text name="SynthesisId.GRAPH_SAMPLING"/> + </h2> + + <div id="" class="chart"> + <div id="expected-vs-actual-observations-by-months-chart" class="chart"></div> + </div> + + +</html> Modified: trunk/wao-web/src/main/webapp/WEB-INF/decorators/layout.jsp =================================================================== --- trunk/wao-web/src/main/webapp/WEB-INF/decorators/layout.jsp 2014-05-23 10:06:09 UTC (rev 1976) +++ trunk/wao-web/src/main/webapp/WEB-INF/decorators/layout.jsp 2014-05-23 10:27:23 UTC (rev 1977) @@ -30,15 +30,15 @@ <title><decorator:title default="Wao"/> - Wao</title> <sj:head locale="fr" jqueryui="true" loadAtOnce="true"/> <sb:head /> - <script type="text/javascript" src="<s:url value="/moment-js-2.5.1/moment-with-langs.js" />"></script> - <script type="text/javascript" src="<s:url value="/select2-3.4.5/select2.min.js" />"></script> - <script type="text/javascript" src="<s:url value="/select2-3.4.5/select2_locale_fr.js" />"></script> - <script type="text/javascript" src="<s:url value="/bootstrap-2.3.1/bootstrap-tooltip.js" />"></script> - <script type="text/javascript" src="<s:url value="/bootstrap-2.3.1/bootstrap-popover.js" />"></script> - <script type="text/javascript" src="<s:url value="/spin.js-2.0.0/spin.js" />"></script> - <script type="text/javascript" src="<s:url value="/spin.js-2.0.0/jquery.spin.js" />"></script> - <script type="text/javascript" src="<s:url value="/wao.js" />"></script> - <script type="text/javascript" src="<s:url value='/endpoints-js.jsp'/>"></script> + <script src="<s:url value="/moment-js-2.5.1/moment-with-langs.js" />"></script> + <script src="<s:url value="/select2-3.4.5/select2.min.js" />"></script> + <script src="<s:url value="/select2-3.4.5/select2_locale_fr.js" />"></script> + <script src="<s:url value="/bootstrap-2.3.1/bootstrap-tooltip.js" />"></script> + <script src="<s:url value="/bootstrap-2.3.1/bootstrap-popover.js" />"></script> + <script src="<s:url value="/spin.js-2.0.0/spin.js" />"></script> + <script src="<s:url value="/spin.js-2.0.0/jquery.spin.js" />"></script> + <script src="<s:url value="/wao.js" />"></script> + <script src="<s:url value='/endpoints-js.jsp'/>"></script> <link rel="stylesheet" type="text/css" href="<s:url value="/select2-3.4.5/select2.css" />" /> <link rel="stylesheet" type="text/css" href="<s:url value="/select2-3.4.5/select2-bootstrap.css" />" /> <link rel="stylesheet" type="text/css" href="<s:url value="/wao.css" />" media="all" /> Modified: trunk/wao-web/src/main/webapp/wao.css =================================================================== --- trunk/wao-web/src/main/webapp/wao.css 2014-05-23 10:06:09 UTC (rev 1976) +++ trunk/wao-web/src/main/webapp/wao.css 2014-05-23 10:27:23 UTC (rev 1977) @@ -501,6 +501,12 @@ color: #2F4F4F; } +.chart { + height: 400px; + margin-left: auto; + margin-right: auto; +} + /****************************************************************************** * Styles spécifiques pour certaines pages de l'appli *****************************************************************************/
participants (1)
-
bleny@users.forge.codelutin.com