blob: 9995db24fc5d447b34171774abc2a1ce03014cd1 [file] [log] [blame]
/**********************************************************************
* Copyright (c) 2017 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.tracecompass.tmf.core.presentation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.tmf.core.dataprovider.X11ColorUtils;
import org.eclipse.tracecompass.tmf.core.model.OutputElementStyle;
import org.eclipse.tracecompass.tmf.core.model.StyleProperties;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterables;
/**
* This is a base implementation of {@link IXYPresentationProvider}
*
* @author Yonni Chen
* @since 4.0
*/
public class XYPresentationProvider implements IXYPresentationProvider {
private static final List<String> SUPPORTED_STYLES = ImmutableList.of(
StyleProperties.SeriesStyle.SOLID,
StyleProperties.SeriesStyle.DASH,
StyleProperties.SeriesStyle.DOT,
StyleProperties.SeriesStyle.DASHDOT,
StyleProperties.SeriesStyle.DASHDOTDOT);
private static final List<String> SUPPORTED_TYPES = ImmutableList.of(
StyleProperties.SeriesType.AREA,
StyleProperties.SeriesType.BAR,
StyleProperties.SeriesType.LINE,
StyleProperties.SeriesType.SCATTER);
private static final List<String> SUPPORTED_TICKS = ImmutableList.of(
StyleProperties.SymbolType.DIAMOND,
StyleProperties.SymbolType.CIRCLE,
StyleProperties.SymbolType.SQUARE,
StyleProperties.SymbolType.TRIANGLE,
StyleProperties.SymbolType.INVERTED_TRIANGLE,
StyleProperties.SymbolType.PLUS,
StyleProperties.SymbolType.CROSS);
/* Gets the default palette for available colors for XY series */
private static final IPaletteProvider COLOR_PALETTE = DefaultColorPaletteProvider.INSTANCE;
/* This map a series name and an IYAppearance */
private final Map<Long, OutputElementStyle> fYAppearances = new HashMap<>();
@Override
public @NonNull OutputElementStyle getSeriesStyle(Long seriesId, @NonNull String type, int width) {
OutputElementStyle appearance = fYAppearances.get(seriesId);
if (appearance != null) {
return appearance;
}
if(!SUPPORTED_TYPES.contains(type)) {
throw new UnsupportedOperationException("Series type: " + type + " is not supported."); //$NON-NLS-1$ //$NON-NLS-2$
}
appearance = StyleProperties.SeriesType.SCATTER.equals(type) ? createScatter(seriesId, type, width) : createAppearance(seriesId, type, width);
fYAppearances.put(seriesId, appearance);
return appearance;
}
@Override
public void clear() {
fYAppearances.clear();
}
private OutputElementStyle createAppearance(Long seriesId, String seriesType, int width) {
RGBAColor color = generateColor();
Builder<String, Object> builder = ImmutableMap.builder();
builder.put(StyleProperties.STYLE_NAME, seriesId);
builder.put(StyleProperties.SERIES_TYPE, seriesType);
builder.put(StyleProperties.SERIES_STYLE, generateStyle(seriesType));
builder.put(StyleProperties.COLOR, X11ColorUtils.toHexColor(color.getRed(), color.getGreen(), color.getBlue()));
builder.put(StyleProperties.WIDTH, width);
return new OutputElementStyle(null, builder.build());
}
private OutputElementStyle createScatter(Long seriesId, String seriesType, int width) {
RGBAColor color = generateColor();
Builder<String, Object> builder = ImmutableMap.builder();
builder.put(StyleProperties.STYLE_NAME, seriesId);
builder.put(StyleProperties.SERIES_TYPE, seriesType);
builder.put(StyleProperties.SERIES_STYLE, StyleProperties.SeriesStyle.NONE);
builder.put(StyleProperties.COLOR, X11ColorUtils.toHexColor(color.getRed(), color.getGreen(), color.getBlue()));
builder.put(StyleProperties.WIDTH, width);
builder.put(StyleProperties.SYMBOL_TYPE, generateTickStyle(seriesType));
return new OutputElementStyle(null, builder.build());
}
/**
* By using a Round Robin technique on all available colors supported, it will
* return a color depending of the number of series already present
*
* @return An instance of {@link RGB} that represent the color
*/
private RGBAColor generateColor() {
List<RGBAColor> colors = COLOR_PALETTE.get();
return Iterables.get(colors, fYAppearances.keySet().size() % colors.size());
}
/**
* By using a Round Robin technique on all available styles supported, it will
* return a style depending of the number of series already present and
* depending on the series type.
*
* @param type
* Series type. Indeed, we want to apply style only on type different
* than scatter
* @return A string defining the style. See {@link IYAppearance.Style}'s strings
*/
private String generateStyle(String type) {
if (!StyleProperties.SeriesType.SCATTER.equals(type)) {
int nbColor = COLOR_PALETTE.get().size();
return Iterables.get(SUPPORTED_STYLES, (fYAppearances.keySet().size() / nbColor) % SUPPORTED_STYLES.size());
}
return StyleProperties.SeriesStyle.NONE;
}
private String generateTickStyle(String type) {
if (StyleProperties.SeriesType.SCATTER.equals(type)) {
return Iterables.get(SUPPORTED_TICKS, (fYAppearances.keySet().size() / (COLOR_PALETTE.get().size())) % SUPPORTED_TICKS.size());
}
return StyleProperties.SeriesStyle.NONE;
}
/**
* Associate a style with the ID of an element
*
* @param id
* The ID of the element
* @param style
* The style
* @since 6.0
*/
public void setStyle(long id, OutputElementStyle style) {
fYAppearances.put(id, style);
}
}