diff --git a/plotly/plotlyfig_aux/core/updateData.m b/plotly/plotlyfig_aux/core/updateData.m index f27aff46..e790c4cc 100644 --- a/plotly/plotlyfig_aux/core/updateData.m +++ b/plotly/plotlyfig_aux/core/updateData.m @@ -33,6 +33,8 @@ updateFmesh(obj, dataIndex); elseif strcmpi(obj.PlotOptions.TreatAs, 'mesh') updateMesh(obj, dataIndex); + elseif strcmpi(obj.PlotOptions.TreatAs, 'surfc') + updateSurfc(obj, dataIndex); % this one will be revomed elseif strcmpi(obj.PlotOptions.TreatAs, 'streamtube') diff --git a/plotly/plotlyfig_aux/handlegraphics/updateSurfc.m b/plotly/plotlyfig_aux/handlegraphics/updateSurfc.m new file mode 100644 index 00000000..bb7d3c89 --- /dev/null +++ b/plotly/plotlyfig_aux/handlegraphics/updateSurfc.m @@ -0,0 +1,563 @@ +function obj = updateSurfc(obj, dataIndex) + + if strcmpi(obj.State.Plot(dataIndex).Class, 'surface') + surfaceIndex = dataIndex; + updateSurfOnly(obj, surfaceIndex) + elseif strcmpi(obj.State.Plot(dataIndex).Class, 'contour') + contourIndex = dataIndex; + updateContourOnly(obj, contourIndex) + end + +end + +function updateContourOnly(obj, contourIndex) + + %-AXIS INDEX-% + axIndex = obj.getAxisIndex(obj.State.Plot(contourIndex).AssociatedAxis); + + %-CHECK FOR MULTIPLE AXES-% + [xsource, ysource] = findSourceAxis(obj,axIndex); + + %-AXIS DATA STRUCTURE-% + axisData = get(obj.State.Plot(contourIndex).AssociatedAxis); + + %-CONTOUR DATA STRUCTURE- % + contourData = get(obj.State.Plot(contourIndex).Handle); + surfData = get(obj.State.Plot(contourIndex-1).Handle); + figureData = get(obj.State.Figure.Handle); + + %-------------------------------------------------------------------------% + + %-associate scene-% + obj.data{contourIndex}.scene = sprintf('scene%d', xsource); + + %-------------------------------------------------------------------------% + + %-scatter3d type for contour projection-% + obj.data{contourIndex}.type = 'scatter3d'; + obj.data{contourIndex}.mode = 'lines'; + + %-------------------------------------------------------------------------% + + %-get colormap-% + cMap = figureData.Colormap; + fac = 1/(length(cMap)-1); + colorScale = {}; + + for c = 1: length(cMap) + colorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))}; + end + + %-------------------------------------------------------------------------% + + %-get plot data-% + contourMatrix = contourData.ContourMatrix; + + xData = []; + yData = []; + zData = []; + cData = []; + + zmin = axisData.ZLim(1); + len = size(contourMatrix, 2); + n = 1; + + while (n < len) + + %---------------------------------------------------------------------% + + %-get plot data-% + m = contourMatrix(2, n); + zlevel = contourMatrix(1, n); + + xData = [xData, contourMatrix(1, n+1:n+m), NaN]; + yData = [yData, contourMatrix(2, n+1:n+m), NaN]; + zData = [zData, zmin * ones(1, m), NaN]; + + %---------------------------------------------------------------------% + + %-get edge color-% + if isnumeric(contourData.LineColor) + cData = sprintf('rgb(%f,%f,%f)', 255*contourData.LineColor); + + elseif strcmpi(contourData.LineColor, 'interp') + cData = zData; + obj.data{contourIndex}.line.colorscale = colorScale; + + elseif strcmpi(contourData.LineColor, 'flat') + [err, r] = min(abs(surfData.ZData - zlevel)); + [~, c] = min(err); + r = r(c); + + cData = [cData, surfData.ZData(r, c) * ones(1, m), NaN]; + obj.data{contourIndex}.line.colorscale = colorScale; + + elseif strcmpi(contourData.LineColor, 'none') + cData = 'rgba(0,0,0,0)'; + + end + + n = n + m + 1; + + end + + %-------------------------------------------------------------------------% + + %-set data on scatter3d-% + obj.data{contourIndex}.x = xData; + obj.data{contourIndex}.y = yData; + obj.data{contourIndex}.z = zData; + + %-------------------------------------------------------------------------% + + %-set edge color-% + obj.data{contourIndex}.line.color = cData; + + %-------------------------------------------------------------------------% + + %-line style-% + + obj.data{contourIndex}.line.width = 2*contourData.LineWidth; + + switch contourData.LineStyle + case '-' + obj.data{contourIndex}.line.dash = 'solid'; + case '--' + obj.data{contourIndex}.line.dash = 'dash'; + case '-.' + obj.data{contourIndex}.line.dash = 'dashdot'; + case ':' + obj.data{contourIndex}.line.dash = 'dot'; + end + + %-------------------------------------------------------------------------% + + %-surface name-% + obj.data{contourIndex}.name = contourData.DisplayName; + + %-------------------------------------------------------------------------% + + %-surface showscale-% + obj.data{contourIndex}.showscale = false; + + %-------------------------------------------------------------------------% + + %-surface visible-% + obj.data{contourIndex}.visible = strcmp(contourData.Visible,'on'); + + %-------------------------------------------------------------------------% +end + + +function updateSurfOnly(obj, surfaceIndex) + + %-AXIS INDEX-% + axIndex = obj.getAxisIndex(obj.State.Plot(surfaceIndex).AssociatedAxis); + + %-CHECK FOR MULTIPLE AXES-% + [xsource, ysource] = findSourceAxis(obj,axIndex); + + %-SURFACE DATA STRUCTURE- % + meshData = get(obj.State.Plot(surfaceIndex).Handle); + figureData = get(obj.State.Figure.Handle); + + %-AXIS STRUCTURE-% + axisData = get(ancestor(meshData.Parent,'axes')); + + %-SCENE DATA-% + eval( sprintf('scene = obj.layout.scene%d;', xsource) ); + + %-GET CONTOUR INDEX-% + obj.PlotOptions.nPlots = obj.PlotOptions.nPlots + 1; + contourIndex = obj.PlotOptions.nPlots; + obj.PlotOptions.contourIndex(surfaceIndex) = contourIndex; + + %-------------------------------------------------------------------------% + + %-associate scene-% + obj.data{surfaceIndex}.scene = sprintf('scene%d', xsource); + obj.data{contourIndex}.scene = sprintf('scene%d', xsource); + + %-------------------------------------------------------------------------% + + %-surface type for face color-% + obj.data{surfaceIndex}.type = 'surface'; + + %-scatter3d type for contour mesh lines-% + obj.data{contourIndex}.type = 'scatter3d'; + obj.data{contourIndex}.mode = 'lines'; + + %-------------------------------------------------------------------------% + + %-get plot data-% + xData = meshData.XData; + yData = meshData.YData; + zData = meshData.ZData; + + if isvector(xData) + [xData, yData] = meshgrid(xData, yData); + end + + %-reformat data to mesh-% + xDataSurface = xData; + yDataSurface = yData; + zDataSurface = zData; + + xDataContourDir1 = [xDataSurface; NaN(1, size(xDataSurface, 2))]; + yDataContourDir1 = [yDataSurface; NaN(1, size(yDataSurface, 2))]; + zDataContourDir1 = [zDataSurface; NaN(1, size(zDataSurface, 2))]; + + xDataContourDir2 = xDataContourDir1(1:end-1,:)'; + yDataContourDir2 = yDataContourDir1(1:end-1,:)'; + zDataContourDir2 = zDataContourDir1(1:end-1,:)'; + + xDataContourDir2 = [xDataContourDir2; NaN(1, size(xDataContourDir2, 2))]; + yDataContourDir2 = [yDataContourDir2; NaN(1, size(yDataContourDir2, 2))]; + zDataContourDir2 = [zDataContourDir2; NaN(1, size(zDataContourDir2, 2))]; + + xDataContour = [xDataContourDir1(:); xDataContourDir2(:)]; + yDataContour = [yDataContourDir1(:); yDataContourDir2(:)]; + zDataContour = [zDataContourDir1(:); zDataContourDir2(:)]; + + %-------------------------------------------------------------------------% + + %-set data on surface-% + obj.data{surfaceIndex}.x = xDataSurface; + obj.data{surfaceIndex}.y = yDataSurface; + obj.data{surfaceIndex}.z = zDataSurface; + + %- setting grid mesh by default -% + % x-direction + xData = xData(1, :); + obj.data{surfaceIndex}.contours.x.start = xData(1); + obj.data{surfaceIndex}.contours.x.end = xData(end); + obj.data{surfaceIndex}.contours.x.size = mean(diff(xData)); + + % y-direction + yData = yData(:, 1); + obj.data{surfaceIndex}.contours.y.start = yData(1); + obj.data{surfaceIndex}.contours.y.end = yData(end); + obj.data{surfaceIndex}.contours.y.size = mean(diff(yData));; + + %-------------------------------------------------------------------------% + + %-set data on scatter3d-% + obj.data{contourIndex}.x = xDataContour(:); + obj.data{contourIndex}.y = yDataContour(:); + obj.data{contourIndex}.z = zDataContour(:); + + %-------------------------------------------------------------------------% + + %-COLORING-% + + %-------------------------------------------------------------------------% + + %-get colormap-% + cMap = figureData.Colormap; + fac = 1/(length(cMap)-1); + colorScale = {}; + + for c = 1: length(cMap) + colorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))}; + end + + %-------------------------------------------------------------------------% + + %-get edge color-% + if isnumeric(meshData.EdgeColor) + cDataContour = sprintf('rgb(%f,%f,%f)', 255*meshData.EdgeColor); + + elseif strcmpi(meshData.EdgeColor, 'interp') + cDataContour = zDataContour(:); + obj.data{contourIndex}.line.colorscale = colorScale; + obj.data{surfaceIndex}.contours.x.colorscale = cDataContour; + obj.data{surfaceIndex}.contours.y.colorscale = cDataContour; + + elseif strcmpi(meshData.EdgeColor, 'flat') + cData = meshData.CData; + + if size(cData, 3) ~= 1 + cMap = unique( reshape(cData, ... + [size(cData,1)*size(cData,2), size(cData,3)]), 'rows' ); + cData = rgb2ind(cData, cMap); + + edgeColorScale = {}; + fac = 1/(length(cMap)-1); + + for c = 1: length(cMap) + edgeColorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))}; + end + + obj.data{surfaceIndex}.line.cmin = 0; + obj.data{surfaceIndex}.line.cmax = 255; + obj.data{contourIndex}.line.colorscale = edgeColorScale; + obj.data{surfaceIndex}.contours.x.colorscale = edgeColorScale; + obj.data{surfaceIndex}.contours.y.colorscale = edgeColorScale; + else + obj.data{contourIndex}.line.cmin = axisData.CLim(1); + obj.data{contourIndex}.line.cmax = axisData.CLim(2); + obj.data{contourIndex}.line.colorscale = colorScale; + obj.data{surfaceIndex}.contours.x.colorscale = colorScale; + obj.data{surfaceIndex}.contours.y.colorscale = colorScale; + end + + cDataContourDir1 = [cData; NaN(1, size(cData, 2))]; + cDataContourDir2 = cDataContourDir1(1:end-1,:)'; + cDataContourDir2 = [cDataContourDir2; NaN(1, size(cDataContourDir2, 2))]; + cDataContour = [cDataContourDir1(:); cDataContourDir2(:)]; + + elseif strcmpi(meshData.EdgeColor, 'none') + cDataContour = 'rgba(0,0,0,0)'; + + end + + %-set edge color-% + obj.data{contourIndex}.line.color = cDataContour; + obj.data{surfaceIndex}.contours.x.color = cDataContour; + obj.data{surfaceIndex}.contours.y.color = cDataContour; + + %-------------------------------------------------------------------------% + + %-get face color-% + faceColor = meshData.FaceColor; + + if isnumeric(faceColor) + + if all(faceColor == [1, 1, 1]) + faceColor = [0.96, 0.96, 0.96]; + end + + for n = 1:size(zDataSurface, 2) + for m = 1:size(zDataSurface, 1) + cDataSurface(m, n, :) = faceColor; + end + end + + [cDataSurface, cMapSurface] = rgb2ind(cDataSurface, 256); + cDataSurface = double(cDataSurface) + axisData.CLim(1); + + for c = 1: size(cMapSurface, 1) + colorScale{c} = { (c-1)*fac , sprintf('rgba(%f,%f,%f, 1)', cMapSurface(c, :))}; + end + + obj.data{surfaceIndex}.cmin = axisData.CLim(1); + obj.data{surfaceIndex}.cmax = axisData.CLim(2); + + elseif strcmpi(faceColor, 'interp') + cDataSurface = zDataSurface; + + if surfaceIndex > xsource + cData = []; + + for idx = xsource:surfaceIndex + cData = [cData; obj.data{idx}.z]; + end + + cMin = min(cData(:)); + cMax = max(cData(:)); + + for idx = xsource:surfaceIndex + obj.data{idx}.cmin = cMin; + obj.data{idx}.cmax = cMax; + end + end + + elseif strcmpi(faceColor, 'flat') + cData = meshData.CData; + + if size(cData, 3) ~= 1 + cMap = unique( reshape(cData, ... + [size(cData,1)*size(cData,2), size(cData,3)]), 'rows' ); + cDataSurface = rgb2ind(cData, cMap); + + colorScale = {}; + fac = 1/(length(cMap)-1); + + for c = 1: length(cMap) + colorScale{c} = { (c-1)*fac , sprintf('rgb(%f,%f,%f)', 255*cMap(c, :))}; + end + else + cDataSurface = cData; + end + + end + + %-set face color-% + obj.data{surfaceIndex}.colorscale = colorScale; + obj.data{surfaceIndex}.surfacecolor = cDataSurface; + + %-lighting settings-% + + if isnumeric(meshData.FaceColor) && all(meshData.FaceColor == [1, 1, 1]) + obj.data{surfaceIndex}.lighting.diffuse = 0.5; + obj.data{surfaceIndex}.lighting.ambient = 0.725; + else + % obj.data{surfaceIndex}.lighting.diffuse = 1.0; + % obj.data{surfaceIndex}.lighting.ambient = 0.9; + end + + if meshData.FaceAlpha ~= 1 + obj.data{surfaceIndex}.lighting.diffuse = 0.5; + obj.data{surfaceIndex}.lighting.ambient = 0.725 + (1-meshData.FaceAlpha); + end + + if obj.PlotlyDefaults.IsLight + obj.data{surfaceIndex}.lighting.diffuse = 1.0; + obj.data{surfaceIndex}.lighting.ambient = 0.3; + end + + %-opacity-% + obj.data{surfaceIndex}.opacity = meshData.FaceAlpha; + + %-------------------------------------------------------------------------% + + %-line style-% + obj.data{contourIndex}.line.width = 1.5*meshData.LineWidth; + + if strcmpi(meshData.LineStyle, '-') + obj.data{contourIndex}.line.dash = 'solid'; + obj.data{surfaceIndex}.contours.x.show = true; + obj.data{surfaceIndex}.contours.y.show = true; + else + obj.data{contourIndex}.line.dash = 'dot'; + obj.data{surfaceIndex}.contours.x.show = false; + obj.data{surfaceIndex}.contours.y.show = false; + end + + %-------------------------------------------------------------------------% + + %-SCENE CONFIGUTATION-% + + %-------------------------------------------------------------------------% + + %-aspect ratio-% + asr = obj.PlotOptions.AspectRatio; + + if ~isempty(asr) + if ischar(asr) + scene.aspectmode = asr; + elseif isvector(ar) && length(asr) == 3 + xar = asr(1); + yar = asr(2); + zar = asr(3); + end + else + + %-define as default-% + xar = max(xData(:)); + yar = max(yData(:)); + xyar = max([xar, yar]); + zar = 0.7*xyar; + end + + scene.aspectratio.x = 1.15*xyar; + scene.aspectratio.y = 1.0*xyar; + scene.aspectratio.z = zar; + + %---------------------------------------------------------------------% + + %-camera eye-% + ey = obj.PlotOptions.CameraEye; + + if ~isempty(ey) + if isvector(ey) && length(ey) == 3 + scene.camera.eye.x = ey(1); + scene.camera.eye.y = ey(2); + scene.camera.eye.z = ey(3); + end + else + + %-define as default-% + xey = - xyar; if xey>0 xfac = 0.1; else xfac = -0.1; end + yey = - xyar; if yey>0 yfac = -0.5; else yfac = 0.5; end + if zar>0 zfac = 0.1; else zfac = -0.1; end + + scene.camera.eye.x = xey + xfac*xey; + scene.camera.eye.y = yey + yfac*yey; + scene.camera.eye.z = zar + zfac*zar; + end + + %-------------------------------------------------------------------------% + + %-scene axis configuration-% + + scene.xaxis.range = axisData.XLim; + scene.yaxis.range = axisData.YLim; + scene.zaxis.range = axisData.ZLim; + + scene.xaxis.tickvals = axisData.XTick; + scene.xaxis.ticktext = axisData.XTickLabel; + + scene.yaxis.tickvals = axisData.YTick; + scene.yaxis.ticktext = axisData.YTickLabel; + + scene.zaxis.tickvals = axisData.ZTick; + scene.zaxis.ticktext = axisData.ZTickLabel; + + scene.xaxis.zeroline = false; + scene.yaxis.zeroline = false; + scene.zaxis.zeroline = false; + + scene.xaxis.showline = true; + scene.yaxis.showline = true; + scene.zaxis.showline = true; + + scene.xaxis.tickcolor = 'rgba(0,0,0,1)'; + scene.yaxis.tickcolor = 'rgba(0,0,0,1)'; + scene.zaxis.tickcolor = 'rgba(0,0,0,1)'; + + scene.xaxis.ticklabelposition = 'outside'; + scene.yaxis.ticklabelposition = 'outside'; + scene.zaxis.ticklabelposition = 'outside'; + + scene.xaxis.title = axisData.XLabel.String; + scene.yaxis.title = axisData.YLabel.String; + scene.zaxis.title = axisData.ZLabel.String; + + scene.xaxis.tickfont.size = axisData.FontSize; + scene.yaxis.tickfont.size = axisData.FontSize; + scene.zaxis.tickfont.size = axisData.FontSize; + + scene.xaxis.tickfont.family = matlab2plotlyfont(axisData.FontName); + scene.yaxis.tickfont.family = matlab2plotlyfont(axisData.FontName); + scene.zaxis.tickfont.family = matlab2plotlyfont(axisData.FontName); + + %-------------------------------------------------------------------------% + + %-SET SCENE TO LAYOUT-% + obj.layout = setfield(obj.layout, sprintf('scene%d', xsource), scene); + + %-------------------------------------------------------------------------% + + %-surface name-% + obj.data{surfaceIndex}.name = meshData.DisplayName; + obj.data{contourIndex}.name = meshData.DisplayName; + + %-------------------------------------------------------------------------% + + %-surface showscale-% + obj.data{surfaceIndex}.showscale = false; + obj.data{contourIndex}.showscale = false; + + %-------------------------------------------------------------------------% + + %-surface visible-% + obj.data{surfaceIndex}.visible = strcmp(meshData.Visible,'on'); + obj.data{contourIndex}.visible = strcmp(meshData.Visible,'on'); + + %-------------------------------------------------------------------------% + + leg = get(meshData.Annotation); + legInfo = get(leg.LegendInformation); + + switch legInfo.IconDisplayStyle + case 'on' + showleg = true; + case 'off' + showleg = false; + end + + obj.data{surfaceIndex}.showlegend = showleg; + + %-------------------------------------------------------------------------% +end