GraphControl: refactoring and optimizations (#831)
* GraphControl cleaning * replace textbox value after submission * rebase * rebase * rebase * Add filters * rebase! * rebase
This commit is contained in:
85
src/GraphControl/Models/Equation.cpp
Normal file
85
src/GraphControl/Models/Equation.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pch.h"
|
||||
#include "Equation.h"
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
// Remove mml: formatting specific to RichEditBox control, which is not understood by the graph engine.
|
||||
static constexpr wstring_view s_mathPrefix = L"mml:";
|
||||
|
||||
Equation::Equation()
|
||||
{
|
||||
}
|
||||
|
||||
String ^ Equation::GetRequest()
|
||||
{
|
||||
wstringstream ss;
|
||||
wstring expr{ Expression->Data() };
|
||||
|
||||
// Check for unicode characters of less than, less than or equal to, greater than and greater than or equal to.
|
||||
if (expr.find(L">><") != wstring::npos || expr.find(L"><<") != wstring::npos || expr.find(L">≥<") != wstring::npos
|
||||
|| expr.find(L">≤<") != wstring::npos)
|
||||
{
|
||||
ss << L"<mrow><mi>plotIneq2D</mi><mfenced separators=\"\">"s;
|
||||
}
|
||||
else if (expr.find(L">=<") != wstring::npos)
|
||||
{
|
||||
ss << L"<mrow><mi>plotEq2d</mi><mfenced separators=\"\">";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << L"<mrow><mi>plot2d</mi><mfenced separators=\"\">";
|
||||
}
|
||||
ss << GetExpression() << L"</mfenced></mrow>";
|
||||
|
||||
return ref new String(ss.str().c_str());
|
||||
}
|
||||
|
||||
wstring Equation::GetExpression()
|
||||
{
|
||||
wstring mathML = Expression->Data();
|
||||
|
||||
size_t mathPrefix = 0;
|
||||
while ((mathPrefix = mathML.find(s_mathPrefix, mathPrefix)) != std::string::npos)
|
||||
{
|
||||
mathML.replace(mathPrefix, s_mathPrefix.length(), L"");
|
||||
mathPrefix += s_mathPrefix.length();
|
||||
}
|
||||
|
||||
return mathML;
|
||||
}
|
||||
|
||||
Color Equation::LineColor::get()
|
||||
{
|
||||
return m_LineColor;
|
||||
}
|
||||
void Equation::LineColor::set(Color value)
|
||||
{
|
||||
if (m_LineColor.R != value.R || m_LineColor.G != value.G || m_LineColor.B != value.B || m_LineColor.A != value.A)
|
||||
{
|
||||
m_LineColor = value;
|
||||
RaisePropertyChanged(L"LineColor");
|
||||
}
|
||||
}
|
||||
|
||||
Platform::String ^ Equation::LineColorPropertyName::get()
|
||||
{
|
||||
return Platform::StringReference(L"LineColor");
|
||||
}
|
||||
|
||||
bool Equation::IsGraphableEquation()
|
||||
{
|
||||
return !Expression->IsEmpty() && IsLineEnabled && !HasGraphError;
|
||||
}
|
||||
}
|
41
src/GraphControl/Models/Equation.h
Normal file
41
src/GraphControl/Models/Equation.h
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
#include "Utils.h"
|
||||
#include <string>
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
[Windows::UI::Xaml::Data::Bindable] public ref class Equation sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
|
||||
{
|
||||
public:
|
||||
Equation();
|
||||
|
||||
OBSERVABLE_OBJECT();
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String ^, Expression);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsLineEnabled);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(bool, IsValidated);
|
||||
OBSERVABLE_NAMED_PROPERTY_RW(bool, HasGraphError);
|
||||
|
||||
property Windows::UI::Color LineColor
|
||||
{
|
||||
Windows::UI::Color get();
|
||||
void set(Windows::UI::Color value);
|
||||
}
|
||||
|
||||
static property Platform::String
|
||||
^ LineColorPropertyName { Platform::String ^ get(); }
|
||||
|
||||
public : Platform::String
|
||||
^ GetRequest();
|
||||
|
||||
bool IsGraphableEquation();
|
||||
|
||||
private:
|
||||
std::wstring GetExpression();
|
||||
|
||||
private:
|
||||
Windows::UI::Color m_LineColor;
|
||||
};
|
||||
}
|
179
src/GraphControl/Models/EquationCollection.h
Normal file
179
src/GraphControl/Models/EquationCollection.h
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Equation.h"
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
delegate void EquationChangedEventHandler(Equation ^ sender);
|
||||
delegate void VisibilityChangedEventHandler(Equation ^ sender);
|
||||
|
||||
public
|
||||
ref class EquationCollection sealed : public Windows::Foundation::Collections::IObservableVector<GraphControl::Equation ^>
|
||||
{
|
||||
public:
|
||||
virtual ~EquationCollection()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma region IIterable
|
||||
virtual Windows::Foundation::Collections::IIterator< GraphControl::Equation^ >^ First()
|
||||
{
|
||||
return m_vector->First();
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IVector
|
||||
virtual property unsigned int Size
|
||||
{
|
||||
unsigned int get()
|
||||
{
|
||||
return m_vector->Size;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Append(GraphControl::Equation ^ value)
|
||||
{
|
||||
m_vector->Append(value);
|
||||
m_tokens.emplace_back(
|
||||
value->PropertyChanged += ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &EquationCollection::OnEquationPropertyChanged));
|
||||
}
|
||||
|
||||
virtual void Clear()
|
||||
{
|
||||
auto numEqs = m_vector->Size;
|
||||
for (auto i = 0u; i < numEqs; i++)
|
||||
{
|
||||
m_vector->GetAt(i)->PropertyChanged -= m_tokens[i];
|
||||
}
|
||||
|
||||
m_vector->Clear();
|
||||
m_tokens.clear();
|
||||
}
|
||||
|
||||
virtual GraphControl::Equation
|
||||
^ GetAt(unsigned int index) { return m_vector->GetAt(index); }
|
||||
|
||||
virtual unsigned int GetMany(unsigned int startIndex, Platform::WriteOnlyArray<GraphControl::Equation ^> ^ items)
|
||||
{
|
||||
return m_vector->GetMany(startIndex, items);
|
||||
}
|
||||
|
||||
virtual Windows::Foundation::Collections::IVectorView< GraphControl::Equation^ >^ GetView()
|
||||
{
|
||||
return m_vector->GetView();
|
||||
}
|
||||
|
||||
virtual Platform::Boolean IndexOf(GraphControl::Equation^ value, unsigned int *index)
|
||||
{
|
||||
return m_vector->IndexOf(value, index);
|
||||
}
|
||||
|
||||
virtual void InsertAt(unsigned int index, GraphControl::Equation ^ value)
|
||||
{
|
||||
m_vector->InsertAt(index, value);
|
||||
m_tokens.insert(
|
||||
m_tokens.begin() + index,
|
||||
value->PropertyChanged += ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &EquationCollection::OnEquationPropertyChanged));
|
||||
}
|
||||
|
||||
virtual void RemoveAt(unsigned int index)
|
||||
{
|
||||
m_vector->GetAt(index)->PropertyChanged -= m_tokens[index];
|
||||
|
||||
m_vector->RemoveAt(index);
|
||||
m_tokens.erase(m_tokens.begin() + index);
|
||||
}
|
||||
|
||||
virtual void RemoveAtEnd()
|
||||
{
|
||||
auto size = m_vector->Size;
|
||||
if (size > 0)
|
||||
{
|
||||
m_vector->GetAt(size - 1)->PropertyChanged -= *m_tokens.rbegin();
|
||||
m_tokens.erase(m_tokens.end() - 1);
|
||||
}
|
||||
|
||||
m_vector->RemoveAtEnd();
|
||||
}
|
||||
|
||||
virtual void ReplaceAll(const Platform::Array<GraphControl::Equation ^> ^ items)
|
||||
{
|
||||
auto size = m_vector->Size;
|
||||
for (auto i = 0u; i < size; i++)
|
||||
{
|
||||
m_vector->GetAt(i)->PropertyChanged -= m_tokens[i];
|
||||
}
|
||||
|
||||
size = items->Length;
|
||||
m_tokens.resize(size);
|
||||
for (auto i = 0u; i < size; i++)
|
||||
{
|
||||
m_tokens[i] = items[i]->PropertyChanged +=
|
||||
ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &EquationCollection::OnEquationPropertyChanged);
|
||||
}
|
||||
|
||||
m_vector->ReplaceAll(items);
|
||||
}
|
||||
|
||||
virtual void SetAt(unsigned int index, GraphControl::Equation ^ value)
|
||||
{
|
||||
m_vector->GetAt(index)->PropertyChanged -= m_tokens[index];
|
||||
|
||||
m_vector->SetAt(index, value);
|
||||
m_tokens[index] = value->PropertyChanged +=
|
||||
ref new Windows::UI::Xaml::Data::PropertyChangedEventHandler(this, &EquationCollection::OnEquationPropertyChanged);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IObservableVector
|
||||
virtual event Windows::Foundation::Collections::VectorChangedEventHandler< GraphControl::Equation^ >^ VectorChanged
|
||||
{
|
||||
Windows::Foundation::EventRegistrationToken add(Windows::Foundation::Collections::VectorChangedEventHandler< GraphControl::Equation^ >^ handler)
|
||||
{
|
||||
return m_vector->VectorChanged += handler;
|
||||
}
|
||||
|
||||
void remove(Windows::Foundation::EventRegistrationToken token)
|
||||
{
|
||||
m_vector->VectorChanged -= token;
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
internal:
|
||||
EquationCollection() :
|
||||
m_vector(ref new Platform::Collections::Vector< GraphControl::Equation^ >())
|
||||
{
|
||||
}
|
||||
|
||||
event EquationChangedEventHandler ^ EquationChanged;
|
||||
event EquationChangedEventHandler ^ EquationStyleChanged;
|
||||
event EquationChangedEventHandler ^ EquationLineEnabledChanged;
|
||||
|
||||
private:
|
||||
void OnEquationPropertyChanged(Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs ^ args)
|
||||
{
|
||||
auto equation = static_cast<Equation ^>(sender);
|
||||
auto propertyName = args->PropertyName;
|
||||
if (propertyName == GraphControl::Equation::LineColorPropertyName)
|
||||
{
|
||||
EquationStyleChanged(equation);
|
||||
}
|
||||
else if (propertyName == GraphControl::Equation::ExpressionPropertyName)
|
||||
{
|
||||
EquationChanged(equation);
|
||||
}
|
||||
else if (propertyName == GraphControl::Equation::IsLineEnabledPropertyName)
|
||||
{
|
||||
EquationLineEnabledChanged(equation);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Platform::Collections::Vector<GraphControl::Equation ^> ^ m_vector;
|
||||
std::vector<Windows::Foundation::EventRegistrationToken> m_tokens;
|
||||
};
|
||||
}
|
70
src/GraphControl/Models/KeyGraphFeaturesInfo.cpp
Normal file
70
src/GraphControl/Models/KeyGraphFeaturesInfo.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "pch.h"
|
||||
#include "KeyGraphFeaturesInfo.h"
|
||||
#include "../../CalcViewModel/GraphingCalculatorEnums.h"
|
||||
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace std;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace GraphControl;
|
||||
using namespace Graphing;
|
||||
|
||||
IObservableVector<String ^> ^ KeyGraphFeaturesInfo::ConvertWStringVector(vector<wstring> inVector)
|
||||
{
|
||||
auto outVector = ref new Vector<String ^>();
|
||||
|
||||
for (auto v : inVector)
|
||||
{
|
||||
outVector->Append(ref new String(v.c_str()));
|
||||
}
|
||||
|
||||
return outVector;
|
||||
}
|
||||
|
||||
IObservableMap<String ^, String ^> ^ KeyGraphFeaturesInfo::ConvertWStringIntMap(map<wstring, int> inMap)
|
||||
{
|
||||
Map<String ^, String ^> ^ outMap = ref new Map<String ^, String ^>();
|
||||
;
|
||||
for (auto m : inMap)
|
||||
{
|
||||
outMap->Insert(ref new String(m.first.c_str()), m.second.ToString());
|
||||
}
|
||||
|
||||
return outMap;
|
||||
}
|
||||
|
||||
KeyGraphFeaturesInfo ^ KeyGraphFeaturesInfo::Create(IGraphFunctionAnalysisData data)
|
||||
{
|
||||
auto res = ref new KeyGraphFeaturesInfo();
|
||||
res->XIntercept = ref new String(data.Zeros.c_str());
|
||||
res->YIntercept = ref new String(data.YIntercept.c_str());
|
||||
res->Domain = ref new String(data.Domain.c_str());
|
||||
res->Range = ref new String(data.Range.c_str());
|
||||
res->Parity = data.Parity;
|
||||
res->PeriodicityDirection = data.PeriodicityDirection;
|
||||
res->PeriodicityExpression = ref new String(data.PeriodicityExpression.c_str());
|
||||
res->Minima = ConvertWStringVector(data.Minima);
|
||||
res->Maxima = ConvertWStringVector(data.Maxima);
|
||||
res->InflectionPoints = ConvertWStringVector(data.InflectionPoints);
|
||||
res->Monotonicity = ConvertWStringIntMap(data.MonotoneIntervals);
|
||||
res->VerticalAsymptotes = ConvertWStringVector(data.VerticalAsymptotes);
|
||||
res->HorizontalAsymptotes = ConvertWStringVector(data.HorizontalAsymptotes);
|
||||
res->ObliqueAsymptotes = ConvertWStringVector(data.ObliqueAsymptotes);
|
||||
res->TooComplexFeatures = data.TooComplexFeatures;
|
||||
res->AnalysisError = CalculatorApp::AnalysisErrorType::NoError;
|
||||
return res;
|
||||
}
|
||||
|
||||
KeyGraphFeaturesInfo ^ KeyGraphFeaturesInfo::Create(CalculatorApp::AnalysisErrorType type)
|
||||
{
|
||||
auto res = ref new KeyGraphFeaturesInfo();
|
||||
res->AnalysisError = type;
|
||||
return res;
|
||||
}
|
51
src/GraphControl/Models/KeyGraphFeaturesInfo.h
Normal file
51
src/GraphControl/Models/KeyGraphFeaturesInfo.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
namespace Graphing
|
||||
{
|
||||
struct IGraphFunctionAnalysisData;
|
||||
}
|
||||
|
||||
namespace CalculatorApp
|
||||
{
|
||||
enum AnalysisErrorType;
|
||||
}
|
||||
|
||||
namespace GraphControl
|
||||
{
|
||||
|
||||
public
|
||||
ref class KeyGraphFeaturesInfo sealed
|
||||
{
|
||||
public:
|
||||
PROPERTY_R(Platform::String ^, XIntercept);
|
||||
PROPERTY_R(Platform::String ^, YIntercept);
|
||||
PROPERTY_R(int, Parity);
|
||||
PROPERTY_R(int, PeriodicityDirection);
|
||||
PROPERTY_R(Platform::String ^, PeriodicityExpression);
|
||||
PROPERTY_R(Windows::Foundation::Collections::IVector<Platform::String ^> ^, Minima);
|
||||
PROPERTY_R(Windows::Foundation::Collections::IVector<Platform::String ^> ^, Maxima);
|
||||
PROPERTY_R(Platform::String ^, Domain);
|
||||
PROPERTY_R(Platform::String ^, Range);
|
||||
PROPERTY_R(Windows::Foundation::Collections::IVector<Platform::String ^> ^, InflectionPoints);
|
||||
PROPERTY_R(SINGLE_ARG(Windows::Foundation::Collections::IObservableMap<Platform::String ^, Platform::String ^> ^), Monotonicity);
|
||||
PROPERTY_R(Windows::Foundation::Collections::IVector<Platform::String ^> ^, VerticalAsymptotes);
|
||||
PROPERTY_R(Windows::Foundation::Collections::IVector<Platform::String ^> ^, HorizontalAsymptotes);
|
||||
PROPERTY_R(Windows::Foundation::Collections::IVector<Platform::String ^> ^, ObliqueAsymptotes);
|
||||
PROPERTY_R(int, TooComplexFeatures);
|
||||
PROPERTY_R(int, AnalysisError);
|
||||
|
||||
internal:
|
||||
static KeyGraphFeaturesInfo ^ Create(Graphing::IGraphFunctionAnalysisData data);
|
||||
static KeyGraphFeaturesInfo ^ Create(CalculatorApp::AnalysisErrorType type);
|
||||
|
||||
private:
|
||||
static Windows::Foundation::Collections::IObservableVector<Platform::String ^> ^ ConvertWStringVector(std::vector<std::wstring> inVector);
|
||||
static Windows::Foundation::Collections::
|
||||
IObservableMap<Platform::String ^, Platform::String ^> ^ ConvertWStringIntMap(std::map<std::wstring, int> inMap);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user