Свойства управления классов графика

Когда вы разрабатываете пользовательский график как подкласс ChartContainer базовый класс, можно использовать определенные методы, чтобы сделать код более устойчивым, эффективным, и созданным в соответствии с нуждами пользователей. Это особое внимание методов о том, как вы задаете и управляете свойствами своего класса. Используйте любого, которые полезны для типа визуализации, которую вы хотите создать и пользовательский опыт, который вы хотите обеспечить.

  • Инициализируйте значения свойств — Набор состояние по умолчанию графика в случае, если ваши пользователи вызывают неявного конструктора без любых входных параметров.

  • Подтвердите значения свойств — Убедитесь, что значения допустимы перед использованием их, чтобы выполнить вычисление или сконфигурировать один из базовых графических объектов в вашем графике.

  • Настройте отображение свойства — Предоставляют индивидуально настраиваемый список свойств когда справочники пользователя объект диаграммы без точки с запятой.

  • Оптимизируйте update метод — Улучшает производительность update метод, когда только подмножество ваших свойств используются в длительном вычислении.

Инициализация значений свойств

Присвойте значения по умолчанию для всех публичных свойств вашего класса. Выполнение так конфигурирует допустимый график, если пользователь не использует некоторые аргументы пары "имя-значение", когда они вызывают метод конструктора.

Для свойств, которые хранят координатные данные, установите начальные значения к NaN значения или пустые массивы так, чтобы график по умолчанию был пуст, когда пользователь не задает координаты. Выберите координаты по умолчанию согласно требованиям функций построения графика, которые вы планируете вызвать в своих методах класса. Чтобы узнать о требованиях, см. документацию для функций построения графика, которые вы планируете использовать.

Проверка значений свойств

Хорошая практика должна проверить значения ваших свойств класса, прежде чем ваш код будет использовать те значения. Удобный способ сделать это должно подтвердить размер и класс свойств, когда вы задаете их. Например, этот блок свойства подтверждает размер и класс четырех свойств.

properties
        IsoValue (1,1) double = 0.5
        Enclose {mustBeMember(Enclose,{'above','below'})} = 'below'
        CapVisible (1,1) matlab.lang.OnOffSwitchState = 'on'
        Color (1,3) double {mustBeGreaterThanOrEqual(Color,0),...
            mustBeLessThanOrEqual(Color,1)} = [.2 .5 .8]
end

  • IsoValue должен быть массив 1 на 1 класса double.

  • Enclose должен иметь значение любого 'above' или 'below'.

  • CapVisible должен быть массив 1 на 1 класса matlab.lang.OnOffSwitchState.

  • Color должен быть 1 3 массив класса double, где каждое значение находится в области значений [0,1].

Можно также подтвердить свойства, которые хранят базовые графические объекты в графике. Чтобы определить имя класса объекта, вызовите соответствующую функцию построения графика в командной строке, и затем вызовите class функция, чтобы получить имя класса. Например, если вы планируете вызвать patch функционируйте в своем setup метод, вызовите patch функция в командной строке с выходным аргументом (входные параметры не имеют значения). Затем передайте выход class функция, чтобы получить ее имя класса.

x = patch(NaN,NaN,NaN);
class(x)
ans =

    'matlab.graphics.primitive.Patch'

Используйте выход class функция, чтобы подтвердить класс для соответствующего свойства в вашем классе. Например, каждое из следующих свойств хранит Patch объект.

properties (Access = private,Transient,NonCopyable)
   IsoPatch (1,1) matlab.graphics.primitive.Patch
   CapPatch (1,1) matlab.graphics.primitive.Patch
end

Иногда, вы можете хотеть задать свойство, которое может сохранить различные формы и классы значений. Например, если вы задаете свойство, которое может сохранить вектор символов, массив ячеек из символьных векторов, или массив строк, не использовать размер и валидацию класса или использовать пользовательский метод валидации свойства.

Для получения дополнительной информации о проверке свойств, см. Проверку значений свойств.

Настройте отображение свойства

Одно из преимуществ определения вашего графика как подкласс ChartContainer базовый класс - то, что это также наследовалось matlab.mixin.CustomDisplay класс. Таким образом можно настроить список свойств отображения MATLAB® в Командном окне, когда вы ссылаетесь на график без точки с запятой. Чтобы настроить отображение свойства, перегрузите getPropertyGroups метод. В рамках того метода можно настроить, какие свойства перечислены и порядок списка. Например, рассмотрите IsoSurfCapChart класс, который имеет следующие публичные свойства.

properties
        IsoValue (1,1) double = 0.5
        Enclose {mustBeMember(Enclose,{'above','below'})} = 'below'
        CapVisible (1,1) matlab.lang.OnOffSwitchState = 'on'
        Color (1,3) double {mustBeGreaterThanOrEqual(Color,0),...
            mustBeLessThanOrEqual(Color,1)} = [.2 .5 .8]
end

Следующий getPropertyGroups метод задает скалярный список свойств объекта как Color, IsoValue, Enclose, и CapVisible.

function propgrp = getPropertyGroups(obj)
    if ~isscalar(obj)
        % List for array of objects
        propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(obj);    
    else
        % List for scalar object
        propList = {'Color','IsoValue','Enclose','CapVisible'};
        propgrp = matlab.mixin.util.PropertyGroup(propList);
    end
end

Когда справочники пользователя экземпляр этого графика без точки с запятой, MATLAB отображает индивидуально настраиваемый список.

c = IsoSurfCapChart
c = 

  IsoSurfCapChart with properties:

            Color: [0.2000 0.5000 0.8000]
         IsoValue: 0.5000
          Enclose: 'below'
       CapVisible: on

Для получения дополнительной информации о настройке отображения свойства, см. Отображение пользовательских свойств.

Оптимизируйте update Метод

В большинстве случаев, update метод вашего класса реконфигурировал все соответствующие аспекты вашего графика, которые зависят от публичных свойств. Иногда, реконфигурирование включает дорогое вычисление, которое является трудоемким. Если вычисление включает только подмножество свойств, можно спроектировать класс, чтобы выполнить тот код только, когда это необходимо.

Один способ оптимизировать update метод должен добавить эти компоненты в ваш класс:

  • Задайте частную собственность под названием ExpensivePropChanged это принимает logical значение. Это свойство указывает, изменилось ли какое-либо из свойств, используемых в дорогом вычислении.

  • Запишите set метод для каждого свойства, вовлеченного в дорогое вычисление. В каждом set метод, набор ExpensivePropChanged свойство к true.

  • Запишите защищенный метод, который выполняет дорогое вычисление.

  • Напишите условный оператор в update метод, который проверяет значение ExpensivePropChanged. Если значением является true, выполните метод, который выполняет дорогое вычисление.

Следующий код предоставляет упрощенное внедрение этого проекта.

classdef OptimizedChart < matlab.graphics.chartcontainer.ChartContainer
    
    properties
        Prop1
        Prop2
    end
    properties(Access=private,Transient,NonCopyable)
        ExpensivePropChanged (1,1) logical = true
    end
    
    methods(Access = protected)
        function setup(obj)
            % Configure chart
            % ...
        end
        function update( obj )
            % Perform expensive computation if needed
            if obj.ExpensivePropChanged
                doExpensiveCalculation(obj);
                obj.ExpensivePropChanged = false;
            end
            
            % Update other aspects of chart
            % ...
        end
        function doExpensiveCalculation(obj)
            % Expensive code
            % ...
        end
    end
    
    methods
        function set.Prop2(obj,val)
            obj.Prop2 = val;
            obj.ExpensivePropChanged = true;
        end
    end
end
В этом случае, Prop2 вовлечен в дорогое вычисление. set.Prop2 метод устанавливает значение Prop2, и затем это устанавливает ExpensivePropChanged к true. Таким образом, в следующий раз update запуски метода, это вызывает doExpensiveCalculation только если ExpensivePropChanged true. Затем update метод продолжает обновлять другие аспекты графика.

Пример: оптимизированный график изоповерхности с индивидуально настраиваемым отображением свойства

Задайте IsoSurfCapChart класс для отображения isosurface со связанным isocaps. Включайте следующие функции:

  • Свойства, которые используют валидация класса и размер

  • Индивидуально настраиваемое отображение свойства

  • Оптимизированный update метод, который повторно вычисляет isosurface и isocaps только если один или несколько соответствующих измененных свойств

Чтобы задать этот класс, создайте программный файл под названием IsoSurfCapChart.m в папке, которая находится на пути MATLAB. Затем реализуйте класс путем выполнения шагов в таблице.

ШагРеализация

Выведите из ChartContainer базовый класс.

classdef IsoSurfCapChart < matlab.graphics.chartcontainer.ChartContainer

Задайте публичные свойства с помощью валидации размера и класса.

  • VolumeData, IsoValue, и Color параметры для isosurface.

  • Enclose, WhichCapPlane, и CapVisible параметры для isocaps.

    properties
        VolumeData double = rand(25,25,25)
        IsoValue (1,1) double = 0.5
        Enclose {mustBeMember(Enclose,{'above','below'})} = 'below'
        WhichCapPlane {mustBeMember(WhichCapPlane,{'all','xmin',...
            'xmax','ymin','ymax','zmin','zmax'})} = 'all'
        CapVisible (1,1) matlab.lang.OnOffSwitchState = 'on'
        Color (1,3) double {mustBeGreaterThanOrEqual(Color,0),...
            mustBeLessThanOrEqual(Color,1)} = [.2 .5 .8]
    end

Задайте частные свойства.

  • IsoPatch и CapPatch сохраните Patch объекты для isosurface и isocaps.

  • SmoothData хранит сглаживавшую версию данных об объеме.

  • ExpensivePropChanged указывает, должен ли метод обновления повторно вычислить isosurface и isocaps.

    properties(Access = private,Transient,NonCopyable)
        IsoPatch (1,1) matlab.graphics.primitive.Patch
        CapPatch (1,1) matlab.graphics.primitive.Patch
        SmoothData double = [];
        ExpensivePropChanged (1,1) logical = true
    end

Реализуйте setup метод. В этом случае вызовите patch функционируйте дважды, чтобы создать Patch объекты для isosurface и isocaps. Храните объекты в соответствующих свойствах и сконфигурируйте оси.

    methods(Access = protected)
        function setup(obj)
            ax = getAxes(obj);
            
            % Create two Patch objects
            obj.IsoPatch = patch(ax,NaN,NaN,NaN, 'EdgeColor', 'none', ...
                'FaceColor',[.2 .5 .8],'FaceAlpha',0.9);
            hold(ax,'on');
            obj.CapPatch = patch(ax,NaN,NaN,NaN,'EdgeColor', 'none', ...
                'FaceColor','interp');
            
            % Configure the axes
            view(ax,3)
            camlight(ax, 'infinite');
            camlight(ax,'left');
            lighting(ax, 'gouraud');
            hold(ax,'off');
        end

Реализуйте update метод. Решите, вызвать ли doExpensiveCalculation метод путем тестирования значения ExpensivePropChanged. Затем продолжите обновлять другие (менее дорогие) аспекты графика.

        function update(obj)
            % Perform expensive computation if needed
            if obj.ExpensivePropChanged
                doExpensiveCalculation(obj);
                obj.ExpensivePropChanged = false;
            end
            
            % Update visibility of CapPatch and update color
            obj.CapPatch.Visible = obj.CapVisible;
            obj.IsoPatch.FaceColor = obj.Color;
        end

Реализуйте doExpensiveCalculation метод, который сглаживает данные об объеме и повторно вычисляет поверхности и вершины isosurface и isocaps.

        function doExpensiveCalculation(obj)
            % Update isosurface
            obj.SmoothData = smooth3(obj.VolumeData,'box',7);
            [F,V] = isosurface(obj.SmoothData, obj.IsoValue);
            set(obj.IsoPatch,'Faces',F,'Vertices',V);
            isonormals(obj.SmoothData,obj.IsoPatch);
            
            % Update isocaps
            [m,n,p] = size(obj.SmoothData);
            [Xc,Yc,Zc] = meshgrid(1:n,1:m,1:p);
            [Fc,Vc,Cc] = isocaps(Xc,Yc,Zc,obj.SmoothData,obj.IsoValue,...
                obj.Enclose,obj.WhichCapPlane);
            set(obj.CapPatch,'Faces',Fc,'Vertices',Vc,'CData',Cc);
        end

Реализуйте getPropertyGroups метод, чтобы настроить отображение свойства.

        function propgrp = getPropertyGroups(obj)
            if ~isscalar(obj)
                % List for array of objects
                propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(obj);
                
            else
                % List for scalar object
                propList = {'Color','IsoValue','Enclose','CapVisible',...
                    'WhichCapPlane','VolumeData'};
                propgrp = matlab.mixin.util.PropertyGroup(propList);
            end
        end
    end

Реализуйте set методы для каждой дорогой недвижимости (VolumeData, IsoValue, и Enclose). В рамках каждого метода, набор соответствующее значение свойства, и затем набор ExpensivePropChanged к true.

    methods
        function set.VolumeData(obj,val)
            obj.VolumeData = val;
            obj.ExpensivePropChanged = true;
        end
        function set.IsoValue(obj, val)
            obj.IsoValue = val;
            obj.ExpensivePropChanged = true;
        end
        function set.Enclose(obj, val)
            obj.Enclose = val;
            obj.ExpensivePropChanged = true;
        end
    end
end

Затем создайте массив данных об объеме, и затем создайте экземпляр IsoSurfCapChart.

[X,Y,Z] = meshgrid(-2:0.1:2);
v = (1/9)*X.^2 + (1/16)*Y.^2 + Z.^2;
c = IsoSurfCapChart('VolumeData',v,'IsoValue',0.5)
c = 

  IsoSurfCapChart with properties:

            Color: [0.2000 0.5000 0.8000]
         IsoValue: 0.5000
          Enclose: 'below'
       CapVisible: on
    WhichCapPlane: 'all'
       VolumeData: [41×41×41 double]

Измените цвет c и скройте isocaps.

c.Color = [1 0.60 0];
c.CapVisible = false;

Смотрите также

Классы

Функции

Похожие темы