Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.metsci.glimpse.plot.MultiAxisPlot2D Maven / Gradle / Ivy
/*
* Copyright (c) 2016, Metron, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Metron, Inc. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL METRON, INC. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.metsci.glimpse.plot;
import static com.metsci.glimpse.plot.MultiAxisPlot2D.AxisOrientation.Bottom;
import static com.metsci.glimpse.plot.MultiAxisPlot2D.AxisOrientation.Left;
import static com.metsci.glimpse.plot.MultiAxisPlot2D.AxisOrientation.Right;
import static com.metsci.glimpse.plot.MultiAxisPlot2D.AxisOrientation.Top;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.metsci.glimpse.axis.Axis1D;
import com.metsci.glimpse.axis.Axis2D;
import com.metsci.glimpse.axis.listener.mouse.AxisMouseListener;
import com.metsci.glimpse.axis.listener.mouse.AxisMouseListener1D;
import com.metsci.glimpse.axis.listener.mouse.AxisMouseListener2D;
import com.metsci.glimpse.axis.painter.NumericAxisPainter;
import com.metsci.glimpse.axis.painter.NumericRightYAxisPainter;
import com.metsci.glimpse.axis.painter.NumericTopXAxisPainter;
import com.metsci.glimpse.axis.painter.NumericXAxisPainter;
import com.metsci.glimpse.axis.painter.NumericYAxisPainter;
import com.metsci.glimpse.axis.painter.label.AxisLabelHandler;
import com.metsci.glimpse.axis.painter.label.GridAxisLabelHandler;
import com.metsci.glimpse.event.mouse.Mouseable;
import com.metsci.glimpse.layout.GlimpseAxisLayout2D;
import com.metsci.glimpse.layout.GlimpseAxisLayoutX;
import com.metsci.glimpse.layout.GlimpseAxisLayoutY;
import com.metsci.glimpse.layout.GlimpseLayout;
import com.metsci.glimpse.layout.GlimpseLayoutManagerMig;
import com.metsci.glimpse.painter.base.GlimpsePainter;
import com.metsci.glimpse.painter.base.GlimpsePainterCallback;
import com.metsci.glimpse.painter.decoration.BackgroundPainter;
import com.metsci.glimpse.painter.group.DelegatePainter;
import com.metsci.glimpse.painter.info.SimpleTextPainter;
import com.metsci.glimpse.painter.info.SimpleTextPainter.HorizontalPosition;
import com.metsci.glimpse.painter.info.SimpleTextPainter.VerticalPosition;
import com.metsci.glimpse.support.settings.DefaultLookAndFeel;
import com.metsci.glimpse.support.settings.LookAndFeel;
/**
* A flexible plotting area with the ability to create an arbitrary number of additional
* axes above, below, left, or right of the main central plotting area.
*
* @author ulman
*/
public class MultiAxisPlot2D extends GlimpseLayout
{
protected int outerBorder = 10;
protected int titleSpacing = 50;
protected int innerSpacing = 0;
protected Map axesTopX;
protected Map axesBottomX;
protected Map axesRightY;
protected Map axesLeftY;
protected Map axesAll;
protected Axis1D centerAxisX;
protected Axis1D centerAxisY;
protected GlimpseLayoutManagerMig layout;
protected GlimpseLayout titleLayout;
protected SimpleTextPainter titlePainter;
protected String title = null;
protected boolean showTitle = false;
protected BackgroundPainter plotBackgroundPainter;
protected BackgroundPainter backgroundPainter;
protected LookAndFeel laf;
protected GlimpseAxisLayout2D axisLayoutXY;
protected AxisMouseListener mouseListenerXY;
protected enum AxisOrientation
{
Top, Bottom, Left, Right;
}
public class AxisInfo
{
protected String id;
protected int order;
protected Axis1D axis;
protected AxisMouseListener mouseListener;
protected GridAxisLabelHandler tickHandler;
protected GlimpseLayout layout;
protected int size;
protected AxisOrientation orient;
protected DelegatePainter backgroundDelegate;
protected DelegatePainter axisDelegate;
protected NumericAxisPainter axisPainter;
protected DelegatePainter foregroundDelegate;
public AxisInfo( String id, AxisOrientation orient, Axis1D axis, AxisMouseListener mouseListener, GridAxisLabelHandler tickHandler, NumericAxisPainter painter, GlimpseLayout layout, int order, int size )
{
this.id = id;
this.axis = axis;
this.mouseListener = mouseListener;
this.tickHandler = tickHandler;
this.axisPainter = painter;
this.layout = layout;
this.order = order;
this.size = size;
this.orient = orient;
this.backgroundDelegate = new DelegatePainter( );
this.backgroundDelegate.setVisible( false );
this.axisDelegate = new DelegatePainter( );
this.foregroundDelegate = new DelegatePainter( );
this.foregroundDelegate.setVisible( false );
this.layout.addPainter( backgroundDelegate );
this.layout.addPainter( axisDelegate );
this.layout.addPainter( foregroundDelegate );
this.axisDelegate.addPainter( axisPainter );
}
public String getId( )
{
return id;
}
public Axis1D getAxis( )
{
return axis;
}
public AxisMouseListener getMouseListener( )
{
return mouseListener;
}
public GridAxisLabelHandler getTickHandler( )
{
return tickHandler;
}
public NumericAxisPainter getAxisPainter( )
{
return axisPainter;
}
public GlimpseLayout getLayout( )
{
return layout;
}
public AxisOrientation getOrientation( )
{
return orient;
}
public int getSize( )
{
return size;
}
public void setSize( int size )
{
this.size = size;
updatePainterLayout( );
validate( );
}
public int getOrder( )
{
return order;
}
public void setOrder( int order )
{
this.order = order;
updatePainterLayout( );
validate( );
}
public void addBackgroundPainter( GlimpsePainter painter )
{
this.backgroundDelegate.addPainter( painter );
this.backgroundDelegate.setVisible( true );
}
public void removeBackgroundPainter( GlimpsePainter painter )
{
this.backgroundDelegate.removePainter( painter );
}
public void addForegroundPainter( GlimpsePainter painter )
{
this.foregroundDelegate.addPainter( painter );
this.foregroundDelegate.setVisible( true );
}
public void removeForegroundPainter( GlimpsePainter painter )
{
this.foregroundDelegate.removePainter( painter );
}
public void setAxisPainter( NumericAxisPainter newPainter )
{
this.axisDelegate.removePainter( this.axisPainter );
this.axisPainter = newPainter;
this.axisDelegate.addPainter( this.axisPainter );
}
@Override
public int hashCode( )
{
final int prime = 31;
int result = 1;
result = prime + result * ( ( id == null ) ? 0 : id.hashCode( ) );
result = prime + result * ( ( orient == null ) ? 0 : orient.hashCode( ) );
return result;
}
@Override
public boolean equals( Object obj )
{
if ( this == obj ) return true;
if ( obj == null ) return false;
if ( getClass( ) != obj.getClass( ) ) return false;
AxisInfo other = ( AxisInfo ) obj;
if ( id == null ) return other.id == null;
if ( !id.equals( other.id ) ) return false;
if ( orient != other.orient ) return false;
return true;
}
}
public MultiAxisPlot2D( )
{
initialize( );
}
//////////////////////////////////////
// Initialization Methods //
//////////////////////////////////////
protected void initialize( )
{
initializeArrays( );
initializeLayout( );
initializePainters( );
initializeLookAndFeel( );
updatePainterLayout( );
}
protected void initializeArrays( )
{
this.axesTopX = new LinkedHashMap( );
this.axesBottomX = new LinkedHashMap( );
this.axesRightY = new LinkedHashMap( );
this.axesLeftY = new LinkedHashMap( );
this.axesAll = new LinkedHashMap( );
this.centerAxisX = new Axis1D( );
this.centerAxisY = new Axis1D( );
}
protected void initializeLayout( )
{
this.layout = new GlimpseLayoutManagerMig( );
this.setLayoutManager( layout );
}
protected void updatePainterLayout( )
{
int t = axesTopX.size( );
int b = axesBottomX.size( );
int r = axesRightY.size( );
int l = axesLeftY.size( );
this.layout.setLayoutConstraints( String.format( "bottomtotop, gapx 0, gapy 0, insets %d %d %d %d", getTopInset( ), outerBorder, outerBorder, outerBorder ) );
this.titleLayout.setLayoutData( String.format( "cell %d %d 1 1, pushx, growx, height %d!", l, 0, isTitleVisible( ) ? titleSpacing : 0 ) );
this.axisLayoutXY.setLayoutData( String.format( "cell %d %d 1 1, push, grow", l, t + 1 ) );
List axisList = getSortedAxes( axesTopX.values( ) );
for ( int i = 0; i < t; i++ )
{
AxisInfo axis = axisList.get( i );
axis.getLayout( ).setLayoutData( String.format( "cell %d %d 1 1, pushx, growx, height %d!", l, i + 1, axis.getSize( ) ) );
}
axisList = getSortedAxes( axesBottomX.values( ) );
for ( int i = 0; i < b; i++ )
{
AxisInfo axis = axisList.get( i );
axis.getLayout( ).setLayoutData( String.format( "cell %d %d 1 1, pushx, growx, height %d!", l, t + 2 + i, axis.getSize( ) ) );
}
axisList = getSortedAxes( axesLeftY.values( ) );
for ( int i = 0; i < l; i++ )
{
AxisInfo axis = axisList.get( i );
axis.getLayout( ).setLayoutData( String.format( "cell %d %d 1 1, pushy, growy, width %d!", i, t + 1, axis.getSize( ) ) );
}
axisList = getSortedAxes( axesRightY.values( ) );
for ( int i = 0; i < r; i++ )
{
AxisInfo axis = axisList.get( i );
axis.getLayout( ).setLayoutData( String.format( "cell %d %d 1 1, pushy, growy, width %d!", l + 1 + i, t + 1, axis.getSize( ) ) );
}
this.invalidateLayout( );
}
protected void initializePainters( )
{
this.backgroundPainter = new BackgroundPainter( true );
super.addPainter0( backgroundPainter, null, Integer.MIN_VALUE );
this.titleLayout = new GlimpseLayout( this, "Title" );
this.axisLayoutXY = new GlimpseAxisLayout2D( this, "Center", new Axis2D( centerAxisX, centerAxisY ) );
this.titlePainter = createTitlePainter( );
if ( titlePainter != null ) titleLayout.addPainter( titlePainter );
this.plotBackgroundPainter = new BackgroundPainter( false );
this.axisLayoutXY.addPainter( this.plotBackgroundPainter );
this.mouseListenerXY = createAxisMouseListenerXY( );
this.attachAxisMouseListener( axisLayoutXY, mouseListenerXY );
}
protected void initializeLookAndFeel( )
{
setLookAndFeel( new DefaultLookAndFeel( ) );
}
protected List getSortedAxes( Collection unsorted )
{
List sortedList = new ArrayList( );
sortedList.addAll( unsorted );
Collections.sort( sortedList, new Comparator( )
{
@Override
public int compare( AxisInfo axis0, AxisInfo axis1 )
{
return axis0.getOrder( ) - axis1.getOrder( );
}
} );
return sortedList;
}
//////////////////////////////////////
// Painter Methods //
//////////////////////////////////////
@Override
public void setLookAndFeel( LookAndFeel laf )
{
super.setLookAndFeel( laf );
this.laf = laf;
}
public void setPlotBackgroundColor( float[] color )
{
plotBackgroundPainter.setColor( color );
}
public void setBackgroundColor( float[] color )
{
backgroundPainter.setColor( color );
}
@Override
public void addPainter( GlimpsePainter painter )
{
axisLayoutXY.addPainter( painter );
}
@Override
public void addPainter( GlimpsePainter painter, GlimpsePainterCallback callback )
{
axisLayoutXY.addPainter( painter, callback );
}
@Override
public void addPainter( GlimpsePainter painter, int zOrder )
{
axisLayoutXY.addPainter( painter, zOrder );
}
@Override
public void addPainter( GlimpsePainter painter, GlimpsePainterCallback callback, int zOrder )
{
axisLayoutXY.addPainter( painter, callback, zOrder );
}
@Override
public void removePainter( GlimpsePainter painter )
{
axisLayoutXY.removePainter( painter );
}
public GlimpseAxisLayout2D getLayoutCenter( )
{
return axisLayoutXY;
}
//////////////////////////////////////
// Axis Getter Methods //
//////////////////////////////////////
public Axis1D getAxis( String label )
{
AxisInfo info = axesAll.get( label );
return info == null ? null : info.getAxis( );
}
public AxisInfo getAxisInfo( String label )
{
return axesAll.get( label );
}
public Axis2D getAxis2D( String axisX, String axisY )
{
return new Axis2D( getAxis( axisX ), getAxis( axisY ) );
}
public Axis1D getCenterAxisX( )
{
return centerAxisX;
}
public Axis1D getCenterAxisY( )
{
return centerAxisY;
}
public Axis2D getCenterAxis( )
{
return new Axis2D( centerAxisX, centerAxisY );
}
//////////////////////////////////////////////
// Title / Font / Color Methods //
//////////////////////////////////////////////
public void setTitleFont( Font font )
{
this.titlePainter.setFont( font, true );
}
public void setTitleFont( Font font, boolean antialias )
{
this.titlePainter.setFont( font, antialias );
}
public String getTitle( )
{
return this.title;
}
public void setTitle( String title )
{
this.title = title;
this.titlePainter.setText( title );
this.setShowTitle( true );
}
public void setShowTitle( boolean show )
{
this.showTitle = show;
this.updatePainterLayout( );
this.validate( );
}
public void setTitleHeight( int height )
{
this.titleSpacing = height;
this.updatePainterLayout( );
this.validate( );
}
//////////////////////////////////////
// Layout Size Methods //
//////////////////////////////////////
public void setBorderSize( int size )
{
this.outerBorder = size;
this.updatePainterLayout( );
this.validate( );
}
public void validate( )
{
centerAxisX.validate( );
centerAxisY.validate( );
for ( AxisInfo axis : axesTopX.values( ) )
axis.getAxis( ).validate( );
for ( AxisInfo axis : axesBottomX.values( ) )
axis.getAxis( ).validate( );
for ( AxisInfo axis : axesLeftY.values( ) )
axis.getAxis( ).validate( );
for ( AxisInfo axis : axesRightY.values( ) )
axis.getAxis( ).validate( );
}
//////////////////////////////////////
// Axis Deletion Methods //
//////////////////////////////////////
public void deleteAxisRight( String name )
{
AxisInfo info = axesRightY.get( name );
if ( info == null ) return;
this.removeLayout( info.getLayout( ) );
axesRightY.remove( name );
axesAll.remove( name );
updatePainterLayout( );
validate( );
}
public void deleteAxisLeft( String name )
{
AxisInfo info = axesLeftY.get( name );
if ( info == null ) return;
this.removeLayout( info.getLayout( ) );
axesLeftY.remove( name );
axesAll.remove( name );
updatePainterLayout( );
validate( );
}
public void deleteAxisTop( String name )
{
AxisInfo info = axesTopX.get( name );
if ( info == null ) return;
this.removeLayout( info.getLayout( ) );
axesTopX.remove( name );
axesAll.remove( name );
updatePainterLayout( );
validate( );
}
public void deleteAxisBottom( String name )
{
AxisInfo info = axesBottomX.get( name );
if ( info == null ) return;
this.removeLayout( info.getLayout( ) );
axesBottomX.remove( name );
axesAll.remove( name );
updatePainterLayout( );
validate( );
}
//////////////////////////////////////
// Axis Creation Methods //
//////////////////////////////////////
public AxisInfo createAxisRight( String name, Axis1D axis, AxisMouseListener mouseListener )
{
int order = 0;
int size = defaultAxisSizeRight( );
GridAxisLabelHandler tickHandler = createTickHandlerRight( );
NumericAxisPainter painter = createAxisPainterRight( tickHandler );
painter.setLookAndFeel( laf );
GlimpseLayout layout = new GlimpseAxisLayoutY( this, name, axis );
attachAxisMouseListener( layout, mouseListener );
AxisInfo info = new AxisInfo( name, Right, axis, mouseListener, tickHandler, painter, layout, order, size );
axesRightY.put( name, info );
axesAll.put( name, info );
layout.setLookAndFeel( laf );
updatePainterLayout( );
validate( );
return info;
}
public AxisInfo createAxisRight( String name )
{
Axis1D axis = createAxisRight( );
return createAxisRight( name, axis, createAxisMouseListenerRight( ) );
}
public AxisInfo createAxisLeft( String name, Axis1D axis, AxisMouseListener mouseListener )
{
int order = 0;
int size = defaultAxisSizeLeft( );
GridAxisLabelHandler tickHandler = createTickHandlerLeft( );
NumericAxisPainter painter = createAxisPainterLeft( tickHandler );
painter.setLookAndFeel( laf );
GlimpseLayout layout = new GlimpseAxisLayoutY( this, name, axis );
attachAxisMouseListener( layout, mouseListener );
AxisInfo info = new AxisInfo( name, Left, axis, mouseListener, tickHandler, painter, layout, order, size );
axesLeftY.put( name, info );
axesAll.put( name, info );
layout.setLookAndFeel( laf );
updatePainterLayout( );
validate( );
return info;
}
public AxisInfo createAxisLeft( String name )
{
Axis1D axis = createAxisLeft( );
return createAxisLeft( name, axis, createAxisMouseListenerLeft( ) );
}
public AxisInfo createAxisTop( String name, Axis1D axis, AxisMouseListener mouseListener )
{
int order = 0;
int size = defaultAxisSizeTop( );
GridAxisLabelHandler tickHandler = createTickHandlerTop( );
NumericAxisPainter painter = createAxisPainterTop( tickHandler );
painter.setLookAndFeel( laf );
GlimpseLayout layout = new GlimpseAxisLayoutX( this, name, axis );
attachAxisMouseListener( layout, mouseListener );
AxisInfo info = new AxisInfo( name, Top, axis, mouseListener, tickHandler, painter, layout, order, size );
axesTopX.put( name, info );
axesAll.put( name, info );
layout.setLookAndFeel( laf );
updatePainterLayout( );
validate( );
return info;
}
public AxisInfo createAxisTop( String name )
{
Axis1D axis = createAxisTop( );
return createAxisTop( name, axis, createAxisMouseListenerTop( ) );
}
public AxisInfo createAxisBottom( String name, Axis1D axis, AxisMouseListener mouseListener )
{
int order = 0;
int size = defaultAxisSizeBottom( );
GridAxisLabelHandler tickHandler = createTickHandlerBottom( );
NumericAxisPainter painter = createAxisPainterBottom( tickHandler );
painter.setLookAndFeel( laf );
GlimpseLayout layout = new GlimpseAxisLayoutX( this, name, axis );
attachAxisMouseListener( layout, mouseListener );
AxisInfo info = new AxisInfo( name, Bottom, axis, mouseListener, tickHandler, painter, layout, order, size );
axesBottomX.put( name, info );
axesAll.put( name, info );
layout.setLookAndFeel( laf );
updatePainterLayout( );
validate( );
return info;
}
protected void attachAxisMouseListener( Mouseable mouseable, AxisMouseListener listener )
{
mouseable.addGlimpseMouseListener( listener );
mouseable.addGlimpseMouseMotionListener( listener );
mouseable.addGlimpseMouseWheelListener( listener );
}
public AxisInfo createAxisBottom( String name )
{
Axis1D axis = createAxisBottom( );
return createAxisBottom( name, axis, createAxisMouseListenerBottom( ) );
}
protected Axis1D createAxisRight( )
{
return new Axis1D( );
}
protected Axis1D createAxisLeft( )
{
return new Axis1D( );
}
protected Axis1D createAxisTop( )
{
return new Axis1D( );
}
protected Axis1D createAxisBottom( )
{
return new Axis1D( );
}
protected NumericAxisPainter createAxisPainterRight( AxisLabelHandler tickHandler )
{
return new NumericRightYAxisPainter( tickHandler );
}
protected NumericAxisPainter createAxisPainterTop( AxisLabelHandler tickHandler )
{
return new NumericTopXAxisPainter( tickHandler );
}
protected NumericAxisPainter createAxisPainterBottom( AxisLabelHandler tickHandler )
{
return new NumericXAxisPainter( tickHandler );
}
protected NumericAxisPainter createAxisPainterLeft( AxisLabelHandler tickHandler )
{
return new NumericYAxisPainter( tickHandler );
}
protected GridAxisLabelHandler createTickHandlerRight( )
{
return new GridAxisLabelHandler( );
}
protected GridAxisLabelHandler createTickHandlerTop( )
{
return new GridAxisLabelHandler( );
}
protected GridAxisLabelHandler createTickHandlerBottom( )
{
return new GridAxisLabelHandler( );
}
protected GridAxisLabelHandler createTickHandlerLeft( )
{
return new GridAxisLabelHandler( );
}
protected AxisMouseListener createAxisMouseListenerRight( )
{
return new AxisMouseListener1D( );
}
protected AxisMouseListener createAxisMouseListenerTop( )
{
return new AxisMouseListener1D( );
}
protected AxisMouseListener createAxisMouseListenerBottom( )
{
return new AxisMouseListener1D( );
}
protected AxisMouseListener createAxisMouseListenerLeft( )
{
return new AxisMouseListener1D( );
}
protected int defaultAxisSizeRight( )
{
return 50;
}
protected int defaultAxisSizeTop( )
{
return 35;
}
protected int defaultAxisSizeBottom( )
{
return 40;
}
protected int defaultAxisSizeLeft( )
{
return 50;
}
protected AxisMouseListener createAxisMouseListenerXY( )
{
return new AxisMouseListener2D( );
}
protected SimpleTextPainter createTitlePainter( )
{
SimpleTextPainter painter = new SimpleTextPainter( );
painter.setHorizontalPosition( HorizontalPosition.Center );
painter.setVerticalPosition( VerticalPosition.Center );
return painter;
}
protected boolean isTitleVisible( )
{
return showTitle && title != null && !title.isEmpty( );
}
protected int getTopInset( )
{
if ( isTitleVisible( ) )
return 0;
else
return outerBorder;
}
@Override
public String toString( )
{
return MultiAxisPlot2D.class.getSimpleName( );
}
}