001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030/** 031 * 032 */ 033package org.openimaj.vis.general; 034 035import java.awt.Dimension; 036 037import org.openimaj.image.MBFImage; 038import org.openimaj.vis.Visualisation; 039 040/** 041 * A chronological bar chart, where each time you add a data point, the visualisation is 042 * moved along and another set of data is added to the 3D visualisation. Data must therefore 043 * be one dimensional. 044 * 045 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 046 * @created 8 Jul 2013 047 */ 048public class ChronologicalScrollingBarVisualisation3D implements Visualisation<double[]> 049{ 050 /** The 3D bar visualisation used to display the time series */ 051 private final BarVisualisation3D barVis; 052 053 /** The data */ 054 private final double[][] data; 055 056 /** The expected length of each data line */ 057 private final int expectedDataLength; 058 059 /** 060 * Default constructor 061 * @param width Width in pixels 062 * @param height Height in pixels 063 * @param timeLength The number of time points to show 064 * @param dataWidth Length of each data line 065 */ 066 public ChronologicalScrollingBarVisualisation3D( final int width, final int height, final int timeLength, final int dataWidth ) 067 { 068 this.barVis = new BarVisualisation3D( width, height ); 069 this.data = new double[timeLength][dataWidth]; 070 this.expectedDataLength = dataWidth; 071 } 072 073 /** 074 * {@inheritDoc} 075 * @see org.openimaj.vis.VisualisationImageProvider#updateVis() 076 */ 077 @Override 078 public void updateVis() 079 { 080 this.barVis.updateVis(); 081 } 082 083 /** 084 * {@inheritDoc} 085 * @see org.openimaj.vis.VisualisationImageProvider#getVisualisationImage() 086 */ 087 @Override 088 public MBFImage getVisualisationImage() 089 { 090 return this.barVis.getVisualisationImage(); 091 } 092 093 /** 094 * {@inheritDoc} 095 * @see org.openimaj.vis.VisualisationImageProvider#setRequiredSize(java.awt.Dimension) 096 */ 097 @Override 098 public void setRequiredSize( final Dimension d ) 099 { 100 this.barVis.setRequiredSize( d ); 101 } 102 103 /** 104 * Set the maximum data value 105 * @param max The maximum 106 */ 107 public void setMaximum( final double max ) 108 { 109 this.barVis.setMaximum( max ); 110 } 111 112 /** 113 * Set the x axis name 114 * @param xAxis The x axis 115 */ 116 public void setXAxisName( final String xAxis ) 117 { 118 this.barVis.setxAxisName( xAxis ); 119 } 120 121 /** 122 * Set the y axis name 123 * @param yAxis The y axis 124 */ 125 public void setYAxisName( final String yAxis ) 126 { 127 this.barVis.setyAxisName( yAxis ); 128 } 129 130 /** 131 * Set the z axis name 132 * @param zAxis The z axis 133 */ 134 public void setZAxisName( final String zAxis ) 135 { 136 this.barVis.setzAxisName( zAxis ); 137 } 138 139 /** 140 * Data is copied into the visualisation, so the arrays passed in are untouched. 141 * 142 * {@inheritDoc} 143 * @see org.openimaj.vis.Visualisation#setData(java.lang.Object) 144 */ 145 @Override 146 public void setData( final double[] newData ) 147 { 148 if( newData.length != this.expectedDataLength ) 149 throw new IllegalArgumentException( "WARNING: Data was not the correct length. Expected " 150 +this.expectedDataLength+" got "+newData.length ); 151 152 // Move all the old data up 153 for( int i = 1; i < this.data.length; i++ ) 154 System.arraycopy( this.data[i], 0, this.data[i-1], 0, this.expectedDataLength ); 155 System.arraycopy( newData, 0, this.data[this.data.length-1], 0, this.expectedDataLength ); 156 157 this.barVis.setData( this.data ); 158 } 159 160 /** 161 * Test 162 * @param args 163 * @throws InterruptedException 164 */ 165 public static void main( final String[] args ) throws InterruptedException 166 { 167 // Number of data points 168 final int N = 10; 169 170 // Number of data frames to draw 171 final int F = 2500; 172 173 // Number of time points to draw 174 final int T = 50; 175 176 // Sleep time 177 final int S = 25; 178 179 final ChronologicalScrollingBarVisualisation3D c = 180 new ChronologicalScrollingBarVisualisation3D( 800, 800, T, N ); 181 c.setMaximum( 2 ); 182 c.setXAxisName( "Scrolling Bar Demo" ); 183 c.setZAxisName( "Time" ); 184 c.setYAxisName( "Value" ); 185 186 for( int i = 0; i < F; i++ ) 187 { 188 final double[] d = new double[N]; 189 for( int j = 0; j < N; j++ ) 190 d[j] = Math.sin( (N+i+4*j)/20d ) + 1d; 191 c.setData( d ); 192 Thread.sleep( S ); 193 } 194 } 195}