image thumbnail

MultipleRange Crosshair Demo

by

 

Demonstration of crosshair in multiple range data. Uses JFreeChart and Matlab

crosshairdemo_multiple.m
function crosshairdemo_multiple
% CrosshairDemo with multiple axis al JFreeGraph-Demo
%
% The code behind is just a demo of what is possible with JFreeChart using it in Matlab. I played a little
% with codesnippets I found on the web and the API-Documentation.
% (http://www.jfree.org/jfreechart/api/javadoc/index.html). When  you want to explore the whole functionality,
% I think it is better to buy the JFreeChart Developer Guide (http://www.jfree.org/jfreechart/devguide.html). 
%
% This function shows a single domain multiple range axis plot as an example of JFreeChart
% (http://www.jfree.org/). The Idea to this code is based on the UndocumentedMatlab-Blog of Yair Altman, who
% shows a sample Code of JFreeChart for creating a PieChart
% (http://undocumentedmatlab.com/blog/jfreechart-graphs-and-gauges/#comments) 
%
% Within the plot you can zoom by pressing the left mouse button and moving the pointer. Also you have some
% properties by right-clicking on the chart. With the slider or by mousclick in the chart you can set the
% position of the crosshair. The actual values of the crosshair are displayed in the table.  
%
% Before this demo works, you need to download JFreeChart and make matlab get to know with it. There are 2
% ways you can do this:
% 1. Add the jcommon and jfreechart jar to the dynamic matlab JavaClassPath (uncommented lines in the first
%    cell an change path to your local installation path)
% 2. Add the jcommon and jfreechart jar to the static matlab JavaClassPath (see Matlab Help, modify
%    classpath.txt on matlabroot\toolbox\local) 
%
% Finally you must donwload jcontrol from Malcom Lidierth
% (http://www.mathworks.com/matlabcentral/fileexchange/15580-using-java-swing-components-in-matlab).
% 
%
% Bugs and suggestions:
%    Please send to Sven Koerner: koerner(underline)sven(add)gmx.de
% 
% You need to download and install first:
%    http://sourceforge.net/projects/jfreechart/files/1.%20JFreeChart/1.0.13/ 
%    http://sourceforge.net/projects/jfreechart/files/1.%20JFreeChart/1.0.9/
%    http://www.mathworks.com/matlabcentral/fileexchange/15580-using-java-swing-components-in-matlab 
%
% Programmed by Sven Koerner: koerner(underline)sven(add)gmx.de
% Date: 2011/02/14 



%%  JFreeChart to matlab
%%%  Add the JavaPackages to the static javaclasspath (see Matlab Help, modify classpath.txt on
%%%  matlabroot\toolbox\local) or alternativ turn it to the dynamic path (uncomment the next and change path to jFreeeChart) 

% javaaddpath C:/Users/sk/Documents/MATLAB/jfreechart-1.0.13/lib/jcommon-1.0.16.jar
% javaaddpath C:/Users/sk/Documents/MATLAB/jfreechart-1.0.13/lib/jfreechart-1.0.13.jar


%% Start

% create dataset, Startvalue: 100, 200 values
dataset1 = createDatasetxy('1. Series', 100, 200 );

% generate chart 
chart            = org.jfree.chart.ChartFactory.createXYLineChart('CrosshairDemo 2', 'x-Label', 'Range Axis 1', dataset1, org.jfree.chart.plot.PlotOrientation.VERTICAL, true, false, false);
background_color = chart.getBackgroundPaint;
chart.setBackgroundPaint(background_color.white);   % Background Color set to white
% cretae chart subtitle
chart.addSubtitle(org.jfree.chart.title.TextTitle('Subtitle - Crosshair'));  

% plot object of chart editing
plot_obj = chart.getXYPlot();
plot_obj.setOrientation(org.jfree.chart.plot.PlotOrientation.VERTICAL);       % set orientation
plot_obj.setBackgroundPaint(background_color.lightGray);                      % set background Color
plot_obj.setDomainGridlinePaint(background_color.white);                      % set gridlinecolor x-direction
plot_obj.setRangeGridlinePaint(background_color.white);                       % set gridlinecolor y-direction
plot_obj.getRangeAxis().setAutoRangeIncludesZero(false);                      % set Range include Zero to false
plot_obj.getDomainAxis().setUpperBound(dataset1.getDomainUpperBound(1));      % set range upper bound to data maximum

% edit the datseries-design
Standard_renderer = org.jfree.chart.renderer.xy.XYLineAndShapeRenderer(true, false);  % set the renderer
Standard_renderer.setSeriesPaint(0, background_color.black);                          % 1. dataset seriescolor red
renderer          = plot_obj.getRenderer;                                       
%renderer          = Standard_renderer;
renderer.setPaint(background_color.black);                                            % 1. dataset draw red


%% Create Multiple Axis

%% AXIS 2 
axis2 = org.jfree.chart.axis.NumberAxis('Range Axis 2'); % create new axis
axis2.setAutoRangeIncludesZero(false);                   % don't use 0 in the range
axis2.setLabelPaint(java.awt.Color(255/255,0,0));        % set the Label color
axis2.setTickLabelPaint(background_color.red);           % set TicklabelColor 
plot_obj.setRangeAxis(1, axis2);                         % add axis to range
plot_obj.setRangeAxisLocation(1, org.jfree.chart.axis.AxisLocation.BOTTOM_OR_LEFT);  % set axis Location
% create new Dataset
dataset2 = createDatasetxy('2. Series', -200, 200 );
plot_obj.setDataset(1, dataset2);                        % add dataset to plot object
plot_obj.mapDatasetToRangeAxis(1,1);                     % map the data

% set render options
renderer2 = org.jfree.chart.renderer.xy.XYLineAndShapeRenderer(true, false);
renderer2.setSeriesPaint(0, background_color.red);
plot_obj.setRenderer(1, renderer2);     % set renderoptions in renderlist of plot object


%% AXIS 3 
% (see axis2 comments)
axis3 = org.jfree.chart.axis.NumberAxis('Range Axis 3');
axis3.setLabelPaint(java.awt.Color(0,0,255/255));
axis3.setTickLabelPaint(background_color.blue);
plot_obj.setRangeAxis(2, axis3);

% create new Dataset
dataset3 = createDatasetxy('3. Series', 400,  200 );
plot_obj.setDataset(2, dataset3);
plot_obj.mapDatasetToRangeAxis(2,2);

% set render options
renderer3 = org.jfree.chart.renderer.xy.XYLineAndShapeRenderer(true, false);
renderer3.setSeriesPaint(0, background_color.blue);
plot_obj.setRenderer(2, renderer3);

%% AXIS 4
% (see axis2 comments)
axis4 = org.jfree.chart.axis.NumberAxis('Range Axis 4');
axis4.setLabelPaint(java.awt.Color(0,255/255,0));
axis4.setTickLabelPaint(background_color.green);
plot_obj.setRangeAxis(3, axis4);

% create new Dataset
dataset4 = createDatasetxy('4. Series', 25, 200 );
plot_obj.setDataset(3, dataset4);
plot_obj.mapDatasetToRangeAxis(3,3);

% set render options
renderer4 = org.jfree.chart.renderer.xy.XYLineAndShapeRenderer(true, true);   % Line and Marker
renderer4.setSeriesPaint(0, background_color.green);
plot_obj.setRenderer(3, renderer4);



%% Show graph
jPanel2 = org.jfree.chart.ChartPanel(chart);                         % create new panel
fh = figure('Units','normalized','position',[0.1, 0.1,  0.7,  0.7]); % create new figure
jp = jcontrol(fh, jPanel2,'Position',[0.01 0.14 0.98 0.85]);         % add the jPanel to figure
jp.MouseClickedCallback = @sh_callback_mouse;                        % add a mouseclickedcallback to the jpanel  
 

%% Datahandling for UiTable
nr_dataset = plot_obj.getDatasetCount;          % check the number of datasets in plot_obj
rnames = cell(0);                               % create empty cell for seriesnames
dat = [];                                       % create empty datatable
for datas_nr  = 0:1: nr_dataset-1               % for each dataset (nr_dataset-1) because of indexing starts with 0
    dataset   = plot_obj.getDataset(datas_nr);  % get the dataset
    nr_series = dataset.getSeriesCount;
    for series_nr = 0:1: nr_series-1            % for each series (nr_series-1) because of indexing starts with 0
        series    = dataset.getSeries(series_nr);
        seriesname = char(dataset.getSeriesKey(series_nr).toString);   % get the seriesname (comparable) and convert to char
        nr_items = series.getItemCount-1;           % for each series the same, because of same domain axis
        sh_val   = round(double(nr_items)/2);       % for each series the same, because of same domain axis
        rnames = [rnames, {seriesname}];            % add seriesnames to the rows
        dat = [dat;  double(dataset.getSeries(series_nr).getX(sh_val)) double(dataset.getSeries(series_nr).getY(sh_val)) ];     % get the data of the series
    end;
end;


% Column Names of UiTable
cnames = {'X-Data','Y-Data'};


% UiTable for Crosshair-Value
th = uitable('Parent',fh, ...
             'ColumnName',cnames,...
             'Data',dat, ...    
             'RowName',rnames,...
             'Units','normalized', 'Position',[0.01 0.033 0.18  0.105]);

% Matlab-Slider
sh = uicontrol(fh,'Style','slider',...
                'Max',nr_items,'Min',0,'Value',round(double(nr_items)/2),...%'Max',dataset1.getDomainUpperBound(1),'Min',dataset1.getDomainLowerBound(1),'Value',sh_val,...
                'SliderStep',[1/nr_items   1/nr_items   ],...
                'Units','normalized', ...
                'Position',[0.01 0.01 0.98 0.02], ...
                'UserData', [{plot_obj} {th} ] , ...                       % save the handle of the plot-object and the uitable to Userdata of the slider to change values
                'Callback',@sh_callback2);

            
% modify Gridline:
plot_obj.setDomainGridlinePaint(background_color.white);
plot_obj.setRangeGridlinePaint(background_color.white);

% add the crosshair:
plot_obj.setDomainCrosshairVisible(true);
plot_obj.setDomainCrosshairLockedOnData(true);
plot_obj.setRangeCrosshairVisible(false);  
plot_obj.setRangeCrosshairLockedOnData(true);
plot_obj.setDomainCrosshairValue(double(dataset1.getSeries(0).getX(sh_val)));          % set Crooshair to the domain Value of actual slider item-position




%% Function for XY-SeriesData Generation
function dataset = createDatasetxy(datasetname, value,  nr_values )        
% This function randomly generates datsets with seriesname: datasetname
% The starting value is: value 
% and the number of values are: nr_values
series      =  org.jfree.data.xy.XYSeries(java.lang.String(datasetname));  % create XYSeries
for i =0:1:nr_values
     series.add(i*0.7, value);
     value = value * (1 + (rand(1) - 0.495) / 10.0);
end;
dataset_series = org.jfree.data.xy.XYSeriesCollection(series);        % dataset generation
dataset_series.removeAllSeries
dataset_series.addSeries(series);
dataset = dataset_series;



%% Slider Callback for Changing Crosshair
function sh_callback2(varargin)
hObject = varargin{1,1};  
i       = (get(hObject,'Value')); % Slider Value
% disp(['Slider moved to Item Number ' num2str(i)]);   % diplay stuff in Matlab Command Window

% Get Handle of objects
plot_cell = get(hObject,'Userdata' );
plot_obj  = plot_cell{1,1};      % handle of plot_object
th        = plot_cell{1,2};      % handle of uitable

nr_dataset = plot_obj.getDatasetCount;          % check the number of datasets in plot_obj
dat = [];
for datas_nr  = 0:1: nr_dataset-1               % for each dataset (nr_dataset-1) because of indexing starts with 0
    dataset   = plot_obj.getDataset(datas_nr);  % get the dataset
    nr_series = dataset.getSeriesCount;
    for series_nr = 0:1: nr_series-1            % for each series (nr_series-1) because of indexing starts with 0
      %  series    = dataset.getSeries(series_nr);
        dat = [dat;  double(dataset.getSeries(series_nr).getX(i)) double(dataset.getSeries(series_nr).getY(i)) ];          % get the data of the series
    end;
end
plot_obj.setDomainCrosshairValue(double(dat(1,1)));    % change crosshairvalue
set(th,'Data',dat);                                    % set values to uitable



%% MouseClicked Callback for Changing Crosshair
function sh_callback_mouse(varargin)
sh        = findobj(gcf,'Style','slider');   % There is only one slider in the figure
% get handle of uitable and plot_object
plot_cell = get(sh,'Userdata' );
plot_obj  = plot_cell{1,1};    % handle of plot_object
th        = plot_cell{1,2};    % handle of uitable
% get the Values
pause(0.05);   % if there is no pause the crosshairvalue isn't up to date
d          = plot_obj.getDomainCrosshairValue();    % xValue of Datset

nr_dataset = plot_obj.getDatasetCount;          % check the number of datasets in plot_obj
dat = [];
for datas_nr  = 0:1: nr_dataset-1               % for each dataset (nr_dataset-1) because of indexing starts with 0
    dataset   = plot_obj.getDataset(datas_nr);  % get the dataset
    nr_series = dataset.getSeriesCount;
    for series_nr = 0:1: nr_series-1            % for each series (nr_series-1) because of indexing starts with 0
        series    = dataset.getSeries(series_nr);
        i         = series.indexOf(java.lang.Double(d)); % Search for Index of xValue = d
        dat = [dat;  double(dataset.getSeries(series_nr).getX(i)) double(dataset.getSeries(series_nr).getY(i)) ];       % get the data of the series  
    end;
end

set(th,'Data',dat);        % set values to uitable
set(sh,'Value',double(i)); % set the slider value to series index





 




 

Contact us