All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.deephaven.plot.AxisImpl Maven / Gradle / Ivy

There is a newer version: 0.36.1
Show newest version
//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.plot;

import io.deephaven.plot.axisformatters.AxisFormat;
import io.deephaven.plot.axistransformations.AxisTransform;
import io.deephaven.plot.axistransformations.AxisTransformBusinessCalendar;
import io.deephaven.plot.chartmodifiers.OneClickChartModifier;
import io.deephaven.plot.errors.PlotExceptionCause;
import io.deephaven.plot.errors.PlotInfo;
import io.deephaven.plot.errors.PlotUnsupportedOperationException;
import io.deephaven.plot.filters.SelectableDataSet;
import io.deephaven.plot.util.tables.PartitionedTableHandle;
import io.deephaven.plot.util.tables.SwappableTable;
import io.deephaven.gui.color.Color;
import io.deephaven.gui.color.Paint;
import io.deephaven.time.calendar.BusinessCalendar;
import io.deephaven.time.calendar.Calendars;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;


/**
 * Represents an axis.
 */
public class AxisImpl implements Axis, PlotExceptionCause {

    private static final long serialVersionUID = -3995577961085156934L;

    public enum Type {
        NUMBER, CATEGORY
    }

    private final ChartImpl chart;
    private final int dim;
    private final int id;
    private Type type;
    private boolean log = false;
    private String label;
    private Font labelFont;
    private Font ticksFont;
    private AxisFormat format;
    private String formatPattern;
    private Paint color;
    private double minRange = Double.NaN;
    private double maxRange = Double.NaN;
    private boolean minorTicksVisible = false;
    private boolean majorTicksVisible = true;
    private int minorTickCount = 0;
    private double gapBetweenMajorTicks = -1.0;
    private double[] majorTickLocations;
    private AxisTransform axisTransform;
    private double tickLabelAngle = 0.0;
    private boolean invert = false;

    private boolean isTimeAxis = false;
    private final Set swappableTables = new CopyOnWriteArraySet<>();
    private final Set partitionedTableHandles = new CopyOnWriteArraySet<>();
    public final Set oneClickChartModifiers = new CopyOnWriteArraySet<>();


    AxisImpl(ChartImpl chart, final int dim, final int id) {
        this.chart = chart;
        this.dim = dim;
        this.id = id;
    }

    /**
     * Creates a copy of an Axis using a different chart.
     *
     * @param axis axis to copy.
     * @param chart new chart.
     */
    protected AxisImpl(final AxisImpl axis, final ChartImpl chart) {
        this(chart, axis.dim, axis.id);

        this.type = axis.type;
        this.log = axis.log;
        this.label = axis.label;
        this.labelFont = axis.labelFont;
        this.ticksFont = axis.ticksFont;
        this.format = axis.format;
        this.formatPattern = axis.formatPattern;
        this.color = axis.color;
        this.minRange = axis.minRange;
        this.maxRange = axis.maxRange;
        this.minorTicksVisible = axis.minorTicksVisible;
        this.majorTicksVisible = axis.majorTicksVisible;
        this.minorTickCount = axis.minorTickCount;
        this.gapBetweenMajorTicks = axis.getGapBetweenMajorTicks();
        this.majorTickLocations = axis.majorTickLocations;
        this.axisTransform = axis.axisTransform;
        this.tickLabelAngle = axis.tickLabelAngle;
        this.invert = axis.invert;
        this.isTimeAxis = axis.isTimeAxis;
        this.swappableTables.addAll(axis.swappableTables);
        this.partitionedTableHandles.addAll(axis.partitionedTableHandles);
        this.oneClickChartModifiers.addAll(axis.oneClickChartModifiers);
    }

    /**
     * Creates a copy of this Axis using a different chart.
     *
     * @param chart new chart.
     * @return axis copy.
     */
    public AxisImpl copy(final ChartImpl chart) {
        return new AxisImpl(this, chart);
    }


    ////////////////////////// internal functionality //////////////////////////

    @Override
    public PlotInfo getPlotInfo() {
        return chart.getPlotInfo();
    }

    /**
     * Gets the dimensionality of this AxisImpl.
     *
     * @return this AxisImpl's dimensionality
     */
    public int dim() {
        return dim;
    }

    /**
     * Gets this AxisImpl's id.
     *
     * @return this AxisImpl's id
     */
    public int id() {
        return id;
    }

    /**
     * Gets this AxisImpl's color.
     *
     * @return this AxisImpl's color
     */
    public Paint getColor() {
        return color;
    }

    void setType(final Type type) {
        if (this.type != null && this.type != type) {
            throw new PlotUnsupportedOperationException(
                    "Switching axis types is not supported: " + this.type + " " + type, this);
        }

        this.type = type;
    }

    /**
     * Gets this AxisImpl's id.
     *
     * @return this AxisImpl's id
     */
    public ChartImpl chart() {
        return chart;
    }

    /**
     * Gets the type of axis.
     *
     * @return type of axis.
     */
    public Type getType() {
        return type;
    }

    /**
     * Whether this is a logarithmic axis.
     *
     * @return if this is a logarithmic axis, true; false otherwise
     */
    public boolean isLog() {
        return log;
    }

    /**
     * Gets this AxisImpl's label.
     *
     * @return this AxisImpl's label
     */
    public String getLabel() {
        return label;
    }

    /**
     * Gets the {@link Font} of this AxisImpl's label.
     *
     * @return this AxisImpl's label's {@link Font}
     */
    public Font getLabelFont() {
        return labelFont;
    }

    /**
     * Gets the {@link Font} of this AxisImpl's tick labels.
     *
     * @return this AxisImpl's tick label's {@link Font}
     */
    public Font getTicksFont() {
        return ticksFont;
    }

    /**
     * Gets the {@link AxisFormat} of this AxisImpl.
     *
     * @return this AxisImpl's {@link AxisFormat}
     */
    public AxisFormat getFormat() {
        return format;
    }

    /**
     * Gets the format pattern for this AxisImpl's tick labels.
     *
     * @return this AxisImpl's tick labels' format pattern
     */
    public String getFormatPattern() {
        return formatPattern;
    }


    /**
     * Gets whether to invert this AxisImpl.
     *
     * @return whether to invert this AxisImpl.
     */
    public boolean getInvert() {
        return invert;
    }

    /**
     * Gets the minimum of this AxisImpl's range.
     *
     * @return minimum of this AxisImpl's range
     */
    public double getMinRange() {
        return minRange;
    }

    /**
     * Gets the maximum of this AxisImpl's range.
     *
     * @return maximum of this AxisImpl's range
     */
    public double getMaxRange() {
        return maxRange;
    }

    /**
     * Whether the minor ticks are drawn.
     *
     * @return if the minor ticks will be drawn, true; otherwise false
     */
    public boolean isMinorTicksVisible() {
        return minorTicksVisible;
    }

    /**
     * Whether the major ticks are drawn.
     *
     * @return if the major ticks will be drawn, true; otherwise false
     */
    public boolean isMajorTicksVisible() {
        return majorTicksVisible;
    }

    /**
     * Gets the number of minor ticks between consecutive major ticks.
     *
     * @return number of minor ticks between consecutive major ticks
     */
    public int getMinorTickCount() {
        return minorTickCount;
    }

    /**
     * Gets the gap between consecutive major ticks.
     *
     * @return the gap between consecutive major ticks
     */
    public double getGapBetweenMajorTicks() {
        return gapBetweenMajorTicks;
    }

    /**
     * Gets the locations of the major ticks.
     *
     * @return the locations of the major ticks
     */
    public double[] getMajorTickLocations() {
        return majorTickLocations;
    }

    /**
     * Gets the angle in degrees at which the tick label text will be drawn.
     *
     * @return angle at which the tick label text will be drawn
     */
    public double getTickLabelAngle() {
        return tickLabelAngle;
    }

    /**
     * Gets the {@link AxisTransform} of this AxisImpl.
     *
     * @return this AxisImpl's {@link AxisTransform}
     */
    public AxisTransform getAxisTransform() {
        return axisTransform;
    }

    /**
     * Whether this axis is time axis.
     *
     * @return boolean informing whether this axis is time axis
     */
    public boolean isTimeAxis() {
        return isTimeAxis;
    }

    /**
     * Sets the boolean representing whether this axis is time axis
     *
     * @param timeAxis boolean representing whether this axis is time axis
     */
    public void setTimeAxis(boolean timeAxis) {
        isTimeAxis = timeAxis;
    }

    public void addPartitionedTableHandle(PartitionedTableHandle map) {
        partitionedTableHandles.add(map);
    }

    public Set getSwappableTables() {
        return swappableTables;
    }

    public Set getPartitionedTableHandles() {
        return partitionedTableHandles;
    }

    public void addSwappableTable(SwappableTable st) {
        swappableTables.add(st);
        addPartitionedTableHandle(st.getPartitionedTableHandle());
    }

    public void addOneClickChartModifier(OneClickChartModifier oneClickChartModifier) {
        oneClickChartModifiers.add(oneClickChartModifier);
    }

    public Set getOneClickChartModifiers() {
        return oneClickChartModifiers;
    }

    ////////////////////////// axes configuration //////////////////////////


    @Override
    public AxisImpl axisFormat(final AxisFormat axisFormat) {
        this.format = axisFormat;
        return this;
    }

    @Override
    public AxisImpl axisFormatPattern(final String axisFormatPattern) {
        this.formatPattern = axisFormatPattern;
        return this;
    }

    ////////////////////////// axis colors //////////////////////////


    @Override
    public AxisImpl axisColor(Paint color) {
        this.color = color;
        return this;
    }

    @Override
    public AxisImpl axisColor(String color) {
        return axisColor(Color.color(color));
    }


    ////////////////////////// axis labels //////////////////////////


    @Override
    public AxisImpl axisLabel(final String label) {
        this.label = label;
        return this;
    }

    @Override
    public AxisImpl axisLabelFont(final Font font) {
        this.labelFont = font;
        return this;
    }

    @Override
    public AxisImpl axisLabelFont(final String family, final String style, final int size) {
        return axisLabelFont(Font.font(family, style, size));
    }

    @Override
    public AxisImpl ticksFont(final Font font) {
        this.ticksFont = font;
        return this;
    }

    @Override
    public AxisImpl ticksFont(final String family, final String style, final int size) {
        return ticksFont(Font.font(family, style, size));
    }


    ////////////////////////// axis transforms //////////////////////////


    @Override
    public AxisImpl transform(final AxisTransform transform) {
        this.axisTransform = transform;
        return this;
    }

    // todo:chip switch over to new log transformations???
    // todo:chip should this also set a log formatter? ... if we use the new transformations
    // todo:chip add a log base N case?
    // if the transform covers what we need, we should use that. This seems to use log base 10 only

    @Override
    public AxisImpl log() {
        this.log = true;
        return this;
    }

    @Override
    public Axis log(final boolean useLog) {
        this.log = useLog;
        return this;
    }

    @Override
    public AxisImpl businessTime(final BusinessCalendar calendar) {
        return transform(new AxisTransformBusinessCalendar(calendar));
    }

    @Override
    public AxisImpl businessTime(final SelectableDataSet sds, final String calendar) {
        throw new PlotUnsupportedOperationException(
                "Selectable business time transformation is not currently supported", this);
    }

    @Override
    public AxisImpl businessTime() {
        return businessTime(Calendars.calendar());
    }

    @Override
    public AxisImpl businessTime(boolean useBusinessTime) {
        return useBusinessTime ? businessTime() : transform(null);
    }

    ////////////////////////// axis rescaling //////////////////////////



    @Override
    public AxisImpl invert() {
        invert(!invert);
        return this;
    }


    @Override
    public AxisImpl invert(final boolean invert) {
        this.invert = invert;
        return this;
    }

    @Override
    public AxisImpl range(double min, double max) {
        min(min);
        max(max);
        return this;
    }

    @Override
    public AxisImpl min(double min) {
        this.minRange = min;
        return this;
    }

    @Override
    public AxisImpl max(double max) {
        this.maxRange = max;
        return this;
    }

    @Override
    public AxisImpl min(final SelectableDataSet sds, final String min) {
        throw new PlotUnsupportedOperationException("Selectable min transformation is not currently supported", this);
    }

    @Override
    public AxisImpl max(final SelectableDataSet sds, final String max) {
        throw new PlotUnsupportedOperationException("Selectable max transformation is not currently supported", this);
    }


    ////////////////////////// axis ticks //////////////////////////


    @Override
    public AxisImpl ticksVisible(boolean visible) {
        this.majorTicksVisible = visible;
        return this;
    }

    @Override
    public AxisImpl ticks(double gapBetweenTicks) {
        this.gapBetweenMajorTicks = gapBetweenTicks;
        this.majorTicksVisible = true;
        return this;
    }

    @Override
    public AxisImpl ticks(double[] tickLocations) {
        this.majorTickLocations = tickLocations;
        return this;
    }

    @Override
    public AxisImpl minorTicksVisible(boolean visible) {
        this.minorTicksVisible = visible;
        return this;
    }

    @Override
    public AxisImpl minorTicks(int nminor) {
        this.minorTickCount = nminor;
        this.minorTicksVisible = true;
        return this;
    }

    @Override
    public AxisImpl tickLabelAngle(double angle) {
        this.tickLabelAngle = angle;
        return this;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy