please am a student working on a project to develop a visualization tool to analyse data using an mvc design in matlab. but the problem im having is that im new to programming and matlab is the first real programing im doing. ive pretty much done the codes but i fear they are no way in an mvc design pattern so i need to change this.
would really appreciate as many imputes as possible to link me up with useful materials as i cant find any for mvc in matlab or may be exemplar codes that implement mvc in matlab to help give me an idea of how i can do mine, presently and doing things like this, where data is a structure with fileds for .Name and .Data. the functions/ methods datcorrCoef and datCorrSum are function i have created that accept my data object as arguments
function dataAnalysisGUI(data)
fdataAnalysisGUI = figure('Name','Data Analysis ',...
'tag','dataAnalysisGUI',...
'menu','none',...
'units','normalized',...
'NumberTitle', 'off')
%%% intialise the gui with data set to work with
vtDaUD.opD = data;
Rsq = datcorrCoef(vtDaUD.opD);
opit = datWrappa(Rsq);
vtDaUD.wd = opit;
vtDaUD.feel = datCorrSum(data);
%%%------------------- menus ------------------------------------------%%%
smh = uimenu('Label', 'Sort', 'Tag', 'daSortMenu');
cmh = uimenu(smh, 'Label', 'Sum of CorrCoeff ',...
'Tag', 'correlation');
uimenu(cmh, 'Label', 'Increasing ',...
'Tag', 'cIncreasing',...
'callback','vtDaCallbacks(''cIncreasing_callback'')');
uimenu(cmh, 'Label', 'Decreasing ',...
'Tag', 'cDecreasing',...
'callback','vtDaCallbacks(''cDecreasing_callback'')');
mmh = uimenu(smh, 'Label', 'Max Lag ',...
'Tag', 'maxLag');
uimenu(mmh, 'Label', 'Increasing ',...
'Tag', 'mIncreasing',...
'callback','vtDaCallbacks(''mIncreasing_callback'')');
uimenu(mmh, 'Label', 'Decreasing ',...
'Tag', 'mDecreasing',...
'callback','vtDaCallbacks(''mDecreasing_callback'')');
dmh = uimenu('Label', 'Display', 'Tag', 'daDisplayMenu');
uimenu(dmh, 'Label', 'Scatter Plots ',...
'Tag', 'dScatter',...
'Callback','vtDaCallbacks(''dScatter_callback'')');
uimenu(dmh, 'Label', 'Cross Correlation ',...
'Tag', 'dCrosscorr',...
'callback','vtDaCallbacks(''dCrosscorr_callback'')');
uimenu(dmh, 'Label', 'Time Series ',...
'Tag', 'dTimeseries',...
'callback','vtDaCallbacks(''dTimeseries_callback'')');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%------------------------ panels ------------------------------------%%%
vtDaPanel1 = uipanel(fdataAnalysisGUI,...
'Units','normalized',...
'Position', [.025 .035 .84 .95],...
'FontSize',10,...
'tag','vtDaPanel1',...
'backgroundcolor',[0.8, 0.8,0.8],...
'title', 'Table of Cross Correlations between Data');
vtDaPanel2 = uipanel(fdataAnalysisGUI,...
'Units','normalized',...
'Position', [.87 .566 .12 .396],...
'tag','vtDaPanel2',...
'backgroundcolor',[0.8, 0.8,0.8],...
'title', 'Analysis');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%------------------------- objects -------------------------------%%%
uitable('parent', vtDaPanel1,...
'tag','vtDaTable',...
'RearrangeableColumn', 'on',...
'clipping','off',...
'Units','normalized',...
'Position',[.01 .2 .98 .8],...
'data',opit.Data,...
'rowname',opit.Name,...
'columnname',opit.Name,...
'CellSelectionCallback',{@daTable_callback,vtDaUD.opD});
uitable('parent', vtDaPanel1,...
'tag','vtDaTable2',...
'RearrangeableColumn', 'on',...
'Units','normalized',...
'Position',[.01 .01 .98 .15],...
'data',vtDaUD.feel.Data,...
'rowname','Sum of Corr. Coeff',...
'columnname',vtDaUD.feel.Name,...
'TooltipString','select column header to drill down',...
'CellSelectionCallback',{@daTable2_callback,vtDaUD.opD});
uicontrol(vtDaPanel2, 'Style', 'popupmenu',...
'tag','taskpopMenu',...
'Units','normalized',...
'Position', [.10 .75 .8 .1],...
'String', {'Correlation Coeff';'Max lags'},...
'Callback', 'vtDaCallbacks(''taskpopMenu_callback'')');
uicontrol(vtDaPanel2, 'Style', 'text',...
'tag','staticTxt2',...
'Units','normalized',...
'Position', [.10 .86 .8 .05],...
'String', {'Task'});
uicontrol(vtDaPanel2, 'Style', 'text',...
'tag','staticTxt3',...
'Units','normalized',...
'Position', [.10 .61 .8 .05],...
'String', {'Mini Display'});
uicontrol(vtDaPanel2, 'Style', 'pushbutton',...
'tag','pushTimeseries',...
'Units','normalized',...
'Position', [.10 .5 .8 .1],...%[450 350 100 50]
'String', {'TimeSeries'},...
'Callback', 'vtDaCallbacks(''pushTimeseries_callback'')');
uicontrol(vtDaPanel2, 'Style', 'pushbutton',...
'tag','pushScatter',...
'Units','normalized',...
'Position', [.10 .35 .8 .1],...
'String', {'Scatter'},...
'Callback', 'vtDaCallbacks(''pushScatter_callback'')');
uicontrol(vtDaPanel2, 'Style', 'pushbutton',...
'tag','pushMaxlag',...
'Units','normalized',...
'Position', [.10 .2 .8 .1],...
'String', {'Max Lag'},...
'Callback', 'vtDaCallbacks(''pushMaxlag_callback'')');
name = genvarname(['daGUI' data.Name{2}]);%name = datname('daGUI',lenght(data.Name));
vtDaUD.varName = name;
eval([name '= data.Data']);
assignin('base',name,data.Data);
set(fdataAnalysisGUI,'UserData',vtDaUD)
and i have done the callback/ control as follows;
function vtDaCallbacks(action)
handles = guihandles(gcf);
vtDaUD = get(handles.dataAnalysisGUI,'UserData');
%tabdata=get(handles.vtDaTable,'data');
tab2Data.Data = get(handles.vtDaTable2,'data');
tab2Data.Name = get(handles.vtDaTable2,'columnname');
switch action
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%-----------------------Data AnalysisGUI menu callbacks-----------%%%
case 'cIncreasing_callback'
[newTabData,index] = sortaColumn(tab2Data,'ascend',1);
vtDaUD.wd = dataselect(vtDaUD.opD,index);
set(handles.vtDaTable2, 'data', newTabData.Data)
set(handles.vtDaTable2, 'columnname', newTabData.Name)
set(handles.vtDaTable2,'CellSelectionCallback',{@daTable2_callback,vtDaUD.wd});
case 'cDecreasing_callback'
[newTabData,index] = sortaColumn(tab2Data,'descend',1);
vtDaUD.wd = dataselect(vtDaUD.opD,index);
%[vtDaUD.wd,newTabData,newcolumnname] = sortta2(vtDaUD.opD,'descend',tab2Data,1);
set(handles.vtDaTable2, 'data', newTabData.Data)
set(handles.vtDaTable2, 'columnname', newTabData.Name)
set(handles.vtDaTable2,'CellSelectionCallback',{@daTable2_callback,vtDaUD.wd});
case 'dScatter_callback'
dataDispGUI('dScatta','calnumpage2',vtDaUD.opD, 'Scatter Plots')
case 'dTimeseries_callback'
dataDispGUI('dTimeSeries2','calnumpage2',vtDaUD.opD, 'Time Series Plots')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%-------------------Data AnalysisGUI uiobject callbacks-----------%%%
case 'dataTable_callback'
[indices,data1,data2] = daTable_callback(vtDa.opD);
vtDaUD.data1=data1;
vtDaUD.data2=data2;
dsingTseries(y1,y2)
case 'taskpopMenu_callback'
val = get (handles.taskpopMenu,'value');
switch val
case 1
Rsq = datcorrCoef(vtDaUD.opD);
tab1data = datWrappa(Rsq);%vtDaUD.wd
set(handles.vtDaPanel1,...
'title', 'Table of Cross Correlations between Data');
case 2
[maxT,lags,coeff]= datCrossCorr(vtDaUD.opD,30);
tab1data = datWrappa(maxT);%vtDaUD.wd
set(handles.vtDaPanel1,...
'title', 'Table of Max Lag between Data');
end
set(handles.vtDaTable, 'data', tab1data.Data)%vtDaUD.wd.Data
set(handles.vtDaTable2,'data', vtDaUD.feel.Data)
set(handles.vtDaTable2,'columnname', vtDaUD.feel.Name)
set(handles.vtDaTable2,'CellSelectionCallback',{@daTable2_callback,vtDaUD.opD});
case 'pushTimeseries_callback'
dsingTseries(vtDaUD.opD,vtDaUD.varName,vtDaUD.indices)
case 'pushScatter_callback'
dsingScatta(vtDaUD.opD,vtDaUD.varName,vtDaUD.indices)
case 'pushMaxlag_callback'
dsingMlags(vtDaUD.opD,vtDaUD.varName,vtDaUD.indices)
end
set(handles.dataAnalysisGUI,'UserData',vtDaUD)
where i again have other functions that operate with my data object here in the controller; really frustrated about the whole thing!! please let me know if im not being clear enough about the description of my problem so you can please help out. thank you
What you are attempting is a non-trivial thing. MATLAB's UI system, GUIDE, is not really that flexible. I hate to be negative about this. I appreciate that you are attempting to develop a UI following a pattern, but I would simply use GUIDE and stay with the auto generated code segments.
Using Java or C# for the UI and then using MATLAB Builder NE or MATLAB Builder Java to bring in MATLAB for the heavy lifting of processing is a much better option. I am not sure the student version comes with that, but that is really what you want.
One of the most important lessons any programmer will learn is that each language has strengths and weaknesses. Trying to force a language into a paradigm it was not designed to be used for is an up hill battle, that will usually end with more crying then rejoicing.
For MVC you need proper Object-Orientation. OO in MATLAB is available in the newer versions, you can just do it like you would do MVC in Java. But it does not "feel" right in MATLAB (so I do not think your instructor meant this) because it would be an overkill in most simple cases and for complex/large UI's MATLAB is too slow and has performance issues in some scenarios.
Otherwise you can use nested functions (closures in CS). With closures some OO functionality can be "emulated". The only problem is that everything has to stay in one m-file.
Here is a very basic example, just fill it with your model data and view ui's:
I have just looked at doing MVC in Matlab and have come up with a pattern I think works will given the limitations of Matlab. The main problem is that GUI files are graphics object handles and not classes. However, if you wrap the GUI in a view class, you can subscribe to observable properties in a model class. You have to let go of using the handles structure in the GUI to store all your user data...that doesn't jive with the design pattern. The good news is that Matlab classes support events and listeners quite well, including the observable properties I alluded to.
The demo of my solution can be found on the Matlab Central File Exchange at http://www.mathworks.com/matlabcentral/fileexchange/40294-model-view-control-pattern-using-guide.
A more detailed description of the implementation is in a blog post at http://myunscriptedblog.blogspot.com/2013/02/mvc-in-matlab.html