package org.molgenis.charts.highcharts.convert; import org.molgenis.charts.MolgenisSerieType; import org.molgenis.charts.data.BoxPlotSerie; import org.molgenis.charts.data.XYData; import org.molgenis.charts.data.XYDataSerie; import org.molgenis.charts.highcharts.basic.Marker; import org.molgenis.charts.highcharts.basic.Series; import org.molgenis.charts.highcharts.basic.SeriesType; import org.molgenis.data.meta.AttributeType; import org.springframework.stereotype.Component; import java.util.*; /** * This data util is made for converting the Molgenis charts structure to the Highchart structure */ @Component public class HighchartSeriesUtil { /** * Parse the xyDataSeries objects list to a Series objects list. The new series object can be used for xy data * charts (like scatter plot) * * @param xYDataSeries * @return Series */ public List<Series> parseToXYDataSeriesList(List<XYDataSerie> xYDataSeries) { List<Series> series = new ArrayList<Series>(); for (XYDataSerie xYDataSerie : xYDataSeries) { series.add(parsexYDataSerieToSeries(xYDataSerie)); } return series; } /** * Parse the boxPlotSeries objects list to a Series objects list. The new series object can be used only for * BoxPlotSeries * * @param boxPlotSeries * @return series */ public List<Series> parseToBoxPlotSeriesList(List<BoxPlotSerie> boxPlotSeries) { List<Series> series = new ArrayList<Series>(); for (BoxPlotSerie boxPlotSerie : boxPlotSeries) { series.add(parseBoxPlotSerieToSeries(boxPlotSerie)); } return series; } /** * Parse the xYDataSerie to a Series object computable with the Highcharts xy series standard. * * @param xYDataSerie * @return Series */ public Series parsexYDataSerieToSeries(XYDataSerie xYDataSerie) { Series series = new Series(); series.setName(xYDataSerie.getName()); series.setType(SeriesType.getSeriesType(xYDataSerie.getType())); series.setData(parseXYDataToList(xYDataSerie.getData(), xYDataSerie.getAttributeXFieldTypeEnum(), xYDataSerie.getAttributeYFieldTypeEnum())); if (MolgenisSerieType.SCATTER.equals(xYDataSerie.getType()) && ( AttributeType.DATE.equals(xYDataSerie.getAttributeXFieldTypeEnum()) || AttributeType.DATE_TIME .equals(xYDataSerie.getAttributeXFieldTypeEnum()))) { series.setLineWidth(0); series.setMarker(new Marker(true, 4)); series.setType(SeriesType.getSeriesType(MolgenisSerieType.LINE)); } return series; } /** * Parse the boxPlotSerie to a Series object computable with the Highcharts box plot series standard * * @param boxPlotSerie * @return series */ public Series parseBoxPlotSerieToSeries(BoxPlotSerie boxPlotSerie) { Series series = new Series(); series.setName(boxPlotSerie.getName()); series.setData(new ArrayList<Object>(boxPlotSerie.getData())); return series; } /** * Parse the x and y data-objects to object computable with the Highcharts scatter plot standard. * * @param xydata * @param xValueFieldTypeEnum * @param yValueFieldTypeEnum * @return List<Object> */ public List<Object> parseXYDataToList(List<XYData> xydata, AttributeType xValueFieldTypeEnum, AttributeType yValueFieldTypeEnum) { List<Object> data = new ArrayList<Object>(); for (XYData xYData : xydata) { List<Object> list = new ArrayList<Object>(); list.add(convertValue(xValueFieldTypeEnum, xYData.getXvalue())); list.add(convertValue(yValueFieldTypeEnum, xYData.getYvalue())); data.add(list); } return data; } /** * Convert values to match the Highcharts demand when using json * * @param fieldTypeEnum * @param value * @return Object */ public Object convertValue(AttributeType fieldTypeEnum, Object value) { if (AttributeType.DATE_TIME.equals(fieldTypeEnum)) { return (convertDateTimeToMilliseconds((Date) value)); } else if (AttributeType.DATE.equals(fieldTypeEnum)) { return (convertDateToMilliseconds((Date) value)); } else { // Highcharts uses the string value of the x axis as the name of the point return value; } } /** * Convert date to long keeping the timezone valued date. When asking the time of a Date object java return the * milliseconds from the begin of counting. "Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT * represented by this Date object." * <p> * This can be a problem when accepting JavaSript to create a JavaScript Date object not knowing the time zone and * .. */ public Long convertDateToMilliseconds(Date date) { if (date == null) return null; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); Calendar calendarConverted = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH); calendarConverted.clear(); calendarConverted.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)); return calendarConverted.getTimeInMillis(); } /** * Convert date to long keeping the timezone valued date. When asking the time of a Date object java return the * milliseconds from the begin of counting. "Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT * represented by this Timestamp object." * <p> * This can be a problem when accepting JavaSript to create a JavaScript Date object not knowing the time zone and * .. */ public Long convertDateTimeToMilliseconds(Date date) { if (date == null) return null; Calendar calendar = Calendar.getInstance(); calendar.setTime(date); Calendar calendarConverted = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH); calendarConverted.clear(); calendarConverted.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND)); return calendarConverted.getTimeInMillis(); } }