From ae092450e23b2fe89c979320625e2f24f09d8920 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Thu, 14 Oct 2021 16:47:04 +0900 Subject: [PATCH 01/11] Relocate the source and project files to adjust the environment for Visual Studio 2019. Signed-off-by: Yoshiteru Kageyama --- Source/OxyPlot.Windows.sln => OxyPlot.Windows.sln | 0 .../Converters/OxyColorConverter.cs | 0 .../Converters/ThicknessConverter.cs | 0 .../Examples/Windows/SimpleDemo/App.xaml | 0 .../Examples/Windows/SimpleDemo/App.xaml.cs | 0 .../SimpleDemo/Assets/LockScreenLogo.scale-200.png | Bin .../SimpleDemo/Assets/SplashScreen.scale-200.png | Bin .../Assets/Square150x150Logo.scale-200.png | Bin .../SimpleDemo/Assets/Square44x44Logo.scale-200.png | Bin ...uare44x44Logo.targetsize-24_altform-unplated.png | Bin .../Windows/SimpleDemo/Assets/StoreLogo.png | Bin .../SimpleDemo/Assets/Wide310x150Logo.scale-200.png | Bin .../Examples/Windows/SimpleDemo/MainPage.xaml | 0 .../Examples/Windows/SimpleDemo/MainPage.xaml.cs | 0 .../Examples/Windows/SimpleDemo/MainViewModel.cs | 0 .../Windows/SimpleDemo/Package.appxmanifest | 0 .../Windows/SimpleDemo/Properties/AssemblyInfo.cs | 0 .../Windows/SimpleDemo/Properties/Default.rd.xml | 0 .../Examples/Windows/SimpleDemo/SimpleDemo.csproj | 0 .../OxyPlot.Windows.csproj | 0 .../OxyPlot.Windows.nuspec | 0 .../OxyPlot.Windows.snk | Bin .../OxyPlot.Windows => OxyPlot.Windows}/PlotView.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Properties/OxyPlot.Windows.rd.xml | 0 .../RenderContext.cs | 0 .../Themes/Generic.xaml | 0 .../Tracker/TrackerControl.cs | 0 .../Tracker/TrackerDefinition.cs | 0 .../Utilities/ConverterExtensions.cs | 0 .../Utilities/MouseButtonHelper.cs | 0 31 files changed, 0 insertions(+), 0 deletions(-) rename Source/OxyPlot.Windows.sln => OxyPlot.Windows.sln (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Converters/OxyColorConverter.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Converters/ThicknessConverter.cs (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/App.xaml (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/App.xaml.cs (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/LockScreenLogo.scale-200.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/SplashScreen.scale-200.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/Square150x150Logo.scale-200.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.scale-200.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.targetsize-24_altform-unplated.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/StoreLogo.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Assets/Wide310x150Logo.scale-200.png (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/MainPage.xaml (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/MainPage.xaml.cs (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/MainViewModel.cs (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Package.appxmanifest (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Properties/AssemblyInfo.cs (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/Properties/Default.rd.xml (100%) rename {Source => OxyPlot.Windows}/Examples/Windows/SimpleDemo/SimpleDemo.csproj (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/OxyPlot.Windows.csproj (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/OxyPlot.Windows.nuspec (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/OxyPlot.Windows.snk (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/PlotView.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Properties/AssemblyInfo.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Properties/OxyPlot.Windows.rd.xml (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/RenderContext.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Themes/Generic.xaml (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Tracker/TrackerControl.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Tracker/TrackerDefinition.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Utilities/ConverterExtensions.cs (100%) rename {Source/OxyPlot.Windows => OxyPlot.Windows}/Utilities/MouseButtonHelper.cs (100%) diff --git a/Source/OxyPlot.Windows.sln b/OxyPlot.Windows.sln similarity index 100% rename from Source/OxyPlot.Windows.sln rename to OxyPlot.Windows.sln diff --git a/Source/OxyPlot.Windows/Converters/OxyColorConverter.cs b/OxyPlot.Windows/Converters/OxyColorConverter.cs similarity index 100% rename from Source/OxyPlot.Windows/Converters/OxyColorConverter.cs rename to OxyPlot.Windows/Converters/OxyColorConverter.cs diff --git a/Source/OxyPlot.Windows/Converters/ThicknessConverter.cs b/OxyPlot.Windows/Converters/ThicknessConverter.cs similarity index 100% rename from Source/OxyPlot.Windows/Converters/ThicknessConverter.cs rename to OxyPlot.Windows/Converters/ThicknessConverter.cs diff --git a/Source/Examples/Windows/SimpleDemo/App.xaml b/OxyPlot.Windows/Examples/Windows/SimpleDemo/App.xaml similarity index 100% rename from Source/Examples/Windows/SimpleDemo/App.xaml rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/App.xaml diff --git a/Source/Examples/Windows/SimpleDemo/App.xaml.cs b/OxyPlot.Windows/Examples/Windows/SimpleDemo/App.xaml.cs similarity index 100% rename from Source/Examples/Windows/SimpleDemo/App.xaml.cs rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/App.xaml.cs diff --git a/Source/Examples/Windows/SimpleDemo/Assets/LockScreenLogo.scale-200.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/LockScreenLogo.scale-200.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/LockScreenLogo.scale-200.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/LockScreenLogo.scale-200.png diff --git a/Source/Examples/Windows/SimpleDemo/Assets/SplashScreen.scale-200.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/SplashScreen.scale-200.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/SplashScreen.scale-200.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/SplashScreen.scale-200.png diff --git a/Source/Examples/Windows/SimpleDemo/Assets/Square150x150Logo.scale-200.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Square150x150Logo.scale-200.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/Square150x150Logo.scale-200.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Square150x150Logo.scale-200.png diff --git a/Source/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.scale-200.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.scale-200.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.scale-200.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.scale-200.png diff --git a/Source/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.targetsize-24_altform-unplated.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.targetsize-24_altform-unplated.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Square44x44Logo.targetsize-24_altform-unplated.png diff --git a/Source/Examples/Windows/SimpleDemo/Assets/StoreLogo.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/StoreLogo.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/StoreLogo.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/StoreLogo.png diff --git a/Source/Examples/Windows/SimpleDemo/Assets/Wide310x150Logo.scale-200.png b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Wide310x150Logo.scale-200.png similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Assets/Wide310x150Logo.scale-200.png rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Assets/Wide310x150Logo.scale-200.png diff --git a/Source/Examples/Windows/SimpleDemo/MainPage.xaml b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml similarity index 100% rename from Source/Examples/Windows/SimpleDemo/MainPage.xaml rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml diff --git a/Source/Examples/Windows/SimpleDemo/MainPage.xaml.cs b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml.cs similarity index 100% rename from Source/Examples/Windows/SimpleDemo/MainPage.xaml.cs rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml.cs diff --git a/Source/Examples/Windows/SimpleDemo/MainViewModel.cs b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainViewModel.cs similarity index 100% rename from Source/Examples/Windows/SimpleDemo/MainViewModel.cs rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/MainViewModel.cs diff --git a/Source/Examples/Windows/SimpleDemo/Package.appxmanifest b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Package.appxmanifest similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Package.appxmanifest rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Package.appxmanifest diff --git a/Source/Examples/Windows/SimpleDemo/Properties/AssemblyInfo.cs b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Properties/AssemblyInfo.cs similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Properties/AssemblyInfo.cs rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Properties/AssemblyInfo.cs diff --git a/Source/Examples/Windows/SimpleDemo/Properties/Default.rd.xml b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Properties/Default.rd.xml similarity index 100% rename from Source/Examples/Windows/SimpleDemo/Properties/Default.rd.xml rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/Properties/Default.rd.xml diff --git a/Source/Examples/Windows/SimpleDemo/SimpleDemo.csproj b/OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo.csproj similarity index 100% rename from Source/Examples/Windows/SimpleDemo/SimpleDemo.csproj rename to OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo.csproj diff --git a/Source/OxyPlot.Windows/OxyPlot.Windows.csproj b/OxyPlot.Windows/OxyPlot.Windows.csproj similarity index 100% rename from Source/OxyPlot.Windows/OxyPlot.Windows.csproj rename to OxyPlot.Windows/OxyPlot.Windows.csproj diff --git a/Source/OxyPlot.Windows/OxyPlot.Windows.nuspec b/OxyPlot.Windows/OxyPlot.Windows.nuspec similarity index 100% rename from Source/OxyPlot.Windows/OxyPlot.Windows.nuspec rename to OxyPlot.Windows/OxyPlot.Windows.nuspec diff --git a/Source/OxyPlot.Windows/OxyPlot.Windows.snk b/OxyPlot.Windows/OxyPlot.Windows.snk similarity index 100% rename from Source/OxyPlot.Windows/OxyPlot.Windows.snk rename to OxyPlot.Windows/OxyPlot.Windows.snk diff --git a/Source/OxyPlot.Windows/PlotView.cs b/OxyPlot.Windows/PlotView.cs similarity index 100% rename from Source/OxyPlot.Windows/PlotView.cs rename to OxyPlot.Windows/PlotView.cs diff --git a/Source/OxyPlot.Windows/Properties/AssemblyInfo.cs b/OxyPlot.Windows/Properties/AssemblyInfo.cs similarity index 100% rename from Source/OxyPlot.Windows/Properties/AssemblyInfo.cs rename to OxyPlot.Windows/Properties/AssemblyInfo.cs diff --git a/Source/OxyPlot.Windows/Properties/OxyPlot.Windows.rd.xml b/OxyPlot.Windows/Properties/OxyPlot.Windows.rd.xml similarity index 100% rename from Source/OxyPlot.Windows/Properties/OxyPlot.Windows.rd.xml rename to OxyPlot.Windows/Properties/OxyPlot.Windows.rd.xml diff --git a/Source/OxyPlot.Windows/RenderContext.cs b/OxyPlot.Windows/RenderContext.cs similarity index 100% rename from Source/OxyPlot.Windows/RenderContext.cs rename to OxyPlot.Windows/RenderContext.cs diff --git a/Source/OxyPlot.Windows/Themes/Generic.xaml b/OxyPlot.Windows/Themes/Generic.xaml similarity index 100% rename from Source/OxyPlot.Windows/Themes/Generic.xaml rename to OxyPlot.Windows/Themes/Generic.xaml diff --git a/Source/OxyPlot.Windows/Tracker/TrackerControl.cs b/OxyPlot.Windows/Tracker/TrackerControl.cs similarity index 100% rename from Source/OxyPlot.Windows/Tracker/TrackerControl.cs rename to OxyPlot.Windows/Tracker/TrackerControl.cs diff --git a/Source/OxyPlot.Windows/Tracker/TrackerDefinition.cs b/OxyPlot.Windows/Tracker/TrackerDefinition.cs similarity index 100% rename from Source/OxyPlot.Windows/Tracker/TrackerDefinition.cs rename to OxyPlot.Windows/Tracker/TrackerDefinition.cs diff --git a/Source/OxyPlot.Windows/Utilities/ConverterExtensions.cs b/OxyPlot.Windows/Utilities/ConverterExtensions.cs similarity index 100% rename from Source/OxyPlot.Windows/Utilities/ConverterExtensions.cs rename to OxyPlot.Windows/Utilities/ConverterExtensions.cs diff --git a/Source/OxyPlot.Windows/Utilities/MouseButtonHelper.cs b/OxyPlot.Windows/Utilities/MouseButtonHelper.cs similarity index 100% rename from Source/OxyPlot.Windows/Utilities/MouseButtonHelper.cs rename to OxyPlot.Windows/Utilities/MouseButtonHelper.cs From 8546b2efc2590b70312097d14017dcc7e9684772 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Thu, 14 Oct 2021 16:56:23 +0900 Subject: [PATCH 02/11] Change the way how to call the base Oxyplot.Core APIs * To fit OxyPlot.Core Ver.2.1.0. Signed-off-by: Yoshiteru Kageyama --- AUTHORS | 15 + CHANGELOG.md | 8 + CONTRIBUTORS | 138 +++ OxyPlot.Windows.nuspec | 31 + OxyPlot.Windows.sln | 112 +-- OxyPlot.Windows.snk | Bin 0 -> 596 bytes .../Converters/OxyColorConverters.cs | 85 ++ .../Converters/ThicknessConverter.cs | 4 +- OxyPlot.Windows/Icons/OxyPlot_128.png | Bin 0 -> 3486 bytes OxyPlot.Windows/OxyPlot.Windows.2.1.0.nupkg | Bin 0 -> 61506 bytes OxyPlot.Windows/OxyPlot.Windows.csproj | 186 +++- OxyPlot.Windows/OxyPlot.Windows.csproj.user | 6 + OxyPlot.Windows/OxyPlot.Windows.nuspec | 23 +- OxyPlot.Windows/PlotView.cs | 138 +-- OxyPlot.Windows/Properties/AssemblyInfo.cs | 28 +- .../Properties/OxyPlot.Windows2.rd.xml | 33 + .../PublishProfiles/FolderProfile.pubxml | 12 + .../PublishProfiles/FolderProfile.pubxml.user | 9 + OxyPlot.Windows/RenderContext.cs | 224 +++-- OxyPlot.Windows/Themes/Generic.xaml | 2 +- OxyPlot.Windows/Tracker/TrackerControl.cs | 24 +- OxyPlot.Windows/Tracker/TrackerDefinition.cs | 2 +- .../Utilities/ConverterExtensions.cs | 2 +- .../Utilities/MouseButtonHelper.cs | 2 +- .../Utilities/OxyPlot.Windows.2.1.0.nupkg | Bin 0 -> 61506 bytes .../Utilities/OxyPlot.Windows.csproj | 165 +++ .../Utilities/OxyPlot.Windows.csproj.user | 6 + .../Utilities/OxyPlot.Windows.nuspec | 32 + OxyPlot.Windows/Utilities/PlotView.cs | 942 ++++++++++++++++++ OxyPlot.Windows/Utilities/RenderContext.cs | 906 +++++++++++++++++ README.md | 5 + 31 files changed, 2837 insertions(+), 303 deletions(-) create mode 100644 AUTHORS create mode 100644 CHANGELOG.md create mode 100644 CONTRIBUTORS create mode 100644 OxyPlot.Windows.nuspec create mode 100644 OxyPlot.Windows.snk create mode 100644 OxyPlot.Windows/Converters/OxyColorConverters.cs create mode 100644 OxyPlot.Windows/Icons/OxyPlot_128.png create mode 100644 OxyPlot.Windows/OxyPlot.Windows.2.1.0.nupkg create mode 100644 OxyPlot.Windows/OxyPlot.Windows.csproj.user create mode 100644 OxyPlot.Windows/Properties/OxyPlot.Windows2.rd.xml create mode 100644 OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml create mode 100644 OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml.user create mode 100644 OxyPlot.Windows/Utilities/OxyPlot.Windows.2.1.0.nupkg create mode 100644 OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj create mode 100644 OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj.user create mode 100644 OxyPlot.Windows/Utilities/OxyPlot.Windows.nuspec create mode 100644 OxyPlot.Windows/Utilities/PlotView.cs create mode 100644 OxyPlot.Windows/Utilities/RenderContext.cs create mode 100644 README.md diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..7d9f5d3 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,15 @@ +# This is the official list of OxyPlot authors for copyright purposes. +# This file is distinct from the CONTRIBUTORS file. +# See the latter for an explanation. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. +# Please notify the first person on the list to be added here. + +Oystein Bjorke +DNV GL AS +LECO® Corporation +TrainerRoad, LLC \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3d255ff --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Change Log +All notable changes to this project will be documented in this file. + +## [Unreleased] +### Added +- + +[Unreleased]: https://github.com/oxyplot/oxyplot-contrib/compare/v0.0.1...HEAD diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..6ec34fd --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,138 @@ +# This is the official list of people who have contributed +# to the OxyPlot repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. + +# People submitting code should be listed in this file (by email address). + +# Names should be added to this file like so: +# Name + +# Please keep the list sorted. + +Alexei Shcherbakov +Anders Musikka +Auriou +Bartłomiej Szypelow +benjaminrupp +Benoit Blanchon <> +br +brantheman +Brannon King +Bryan Freeman +Brian Lim +Caleb Clarke +Carlos Anderson +Carlos Teixeira +Chase Long +Choden Konigsmark +classicboss302 +csabar +Curt Mullin +Cyril Martin +Dan Aizenstros +danpaul88 +darrelbrown +David Funk +David Laundav +David Wong +DJDAS +DNV GL AS +Doeharrrck +Don Syme +DotNetDoctor +efontana2 +elliatab +Elmar Strittmatter +episage +eric +Federico Coppola +Francois Botha +Frank Tore Sæther +Garrett +Geert van Horrik +Gimly +Herman Eldering +Iain Nicol +Ilja Nosik +Ilya Skriblovsky +Iurii Gazin +Jānis Kiršteins +jaykul +Jeremy Koritzinsky +Jeremie Magnette +jezza323 +Johan +Johan20D +Jonathan Arweck +Jonathan Shore +julien.bataille +Just Slon +Kaplas80 +kc1212 +kenny_evoleap +Kenny Nygaard +Kevin Crowell +Kyle Pulvermacher +LECO® Corporation +Levi Botelho +Linquize +lsowen +Luka B +Nils Haferkemper +Matt Williams +Matthew Leibowitz +Memphisch +Mendel Monteiro-Beckerman +Menno Deij - van Rijswijk +methdotnet +Mikant +mirolev +Mitch-Connor +moes_leco +moljac +mroth +mrtncls +Oleg Tarasov +Oystein Bjorke +Patrice Marin +Peter-B- +Philippe AURIOU +Piotr Warzocha +Poul Erik Venø +Régis Boudin +Rik Borger +ryang +Sarah Müller +Senen Fernandez +Scott W Harden +Shankar Mathiah Nanjundan +Shun-ichi Goto +Soarc +Stefan Rado +stefan-schweiger +Steve Hoelzer +Surfin Bird +Sven Dummis +Taldoras +Tandy Carmichael +Tasos Stamadianos +Thorsten Claff +thepretender +tephyrnex +Thomas Ibel +Tomasz Cielecki +ToplandJ +twsl <45483159+twsI@users.noreply.github.com> +Udo Liess +VisualMelon +vhoehn +Vsevolod Kukol +Xavier +zur003 +Markus Ebner +Duncan Robertson +LauXjpn +R. Usamentiaga +Dmytro Shaurin +Rustam Sayfutdinov \ No newline at end of file diff --git a/OxyPlot.Windows.nuspec b/OxyPlot.Windows.nuspec new file mode 100644 index 0000000..f1ab370 --- /dev/null +++ b/OxyPlot.Windows.nuspec @@ -0,0 +1,31 @@ + + + + OxyPlot.Windows + OxyPlot for Windows apps + 2.1.0 + Oystein Bjorke + OxyPlot is a plotting library for .NET. This package targets the Universal Windows Platform (UAP10). + + https://raw.githubusercontent.com/oxyplot/oxyplot/master/LICENSE + http://oxyplot.org/ + https://raw.githubusercontent.com/oxyplot/oxyplot/develop/Icons/OxyPlot_128.png + false + en-US + winrt uap uap10 UWP win10 plotting plot charting chart + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OxyPlot.Windows.sln b/OxyPlot.Windows.sln index a26f024..1887cbb 100644 --- a/OxyPlot.Windows.sln +++ b/OxyPlot.Windows.sln @@ -3,15 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29403.142 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{07CE67B3-8AA2-4572-865F-B3F7FA80CE19}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OxyPlot", "OxyPlot\OxyPlot.csproj", "{7A0B35C0-DD17-4964-8E9A-44D6CECDC692}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExampleLibrary", "Examples\ExampleLibrary\ExampleLibrary.csproj", "{FACB89E5-53A5-4748-9F5B-E0714EBB37B2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot.Windows", "OxyPlot.Windows\OxyPlot.Windows.csproj", "{5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleDemo", "Examples\Windows\SimpleDemo\SimpleDemo.csproj", "{FAC17BDF-4003-4359-A366-2E2F380E1BB5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot.Windows", "OxyPlot.Windows\OxyPlot.Windows.csproj", "{4F5B1D20-EA97-4DBB-94E1-8D86B4152847}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,91 +19,31 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|ARM.ActiveCfg = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|ARM64.Build.0 = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|x64.ActiveCfg = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Debug|x86.ActiveCfg = Debug|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|Any CPU.Build.0 = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|ARM.ActiveCfg = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|ARM.Build.0 = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|ARM64.ActiveCfg = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|ARM64.Build.0 = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|x64.ActiveCfg = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|x64.Build.0 = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|x86.ActiveCfg = Release|Any CPU - {7A0B35C0-DD17-4964-8E9A-44D6CECDC692}.Release|x86.Build.0 = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|ARM.ActiveCfg = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|ARM64.Build.0 = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|x64.ActiveCfg = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Debug|x86.ActiveCfg = Debug|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|Any CPU.Build.0 = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|ARM.ActiveCfg = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|ARM.Build.0 = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|ARM64.ActiveCfg = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|ARM64.Build.0 = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|x64.ActiveCfg = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|x64.Build.0 = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|x86.ActiveCfg = Release|Any CPU - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2}.Release|x86.Build.0 = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|ARM.ActiveCfg = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|ARM.Build.0 = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|ARM64.Build.0 = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|x64.ActiveCfg = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|x64.Build.0 = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|x86.ActiveCfg = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Debug|x86.Build.0 = Debug|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|Any CPU.Build.0 = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|ARM.ActiveCfg = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|ARM.Build.0 = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|ARM64.ActiveCfg = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|ARM64.Build.0 = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|x64.ActiveCfg = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|x64.Build.0 = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|x86.ActiveCfg = Release|Any CPU - {5AA87152-20D5-48F7-AD0F-6E6BAA61FC25}.Release|x86.Build.0 = Release|Any CPU - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|Any CPU.ActiveCfg = Debug|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM.ActiveCfg = Debug|ARM - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM.Build.0 = Debug|ARM - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM.Deploy.0 = Debug|ARM - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM64.ActiveCfg = Debug|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x64.ActiveCfg = Debug|x64 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x64.Build.0 = Debug|x64 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x64.Deploy.0 = Debug|x64 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x86.ActiveCfg = Debug|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x86.Build.0 = Debug|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x86.Deploy.0 = Debug|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|Any CPU.ActiveCfg = Release|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM.ActiveCfg = Release|ARM - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM.Build.0 = Release|ARM - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM.Deploy.0 = Release|ARM - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM64.ActiveCfg = Release|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x64.ActiveCfg = Release|x64 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x64.Build.0 = Release|x64 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x64.Deploy.0 = Release|x64 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x86.ActiveCfg = Release|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x86.Build.0 = Release|x86 - {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x86.Deploy.0 = Release|x86 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|ARM.ActiveCfg = Debug|ARM + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|ARM.Build.0 = Debug|ARM + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|ARM64.Build.0 = Debug|ARM64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|x64.ActiveCfg = Debug|x64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|x64.Build.0 = Debug|x64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|x86.ActiveCfg = Debug|x86 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Debug|x86.Build.0 = Debug|x86 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|Any CPU.Build.0 = Release|Any CPU + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|ARM.ActiveCfg = Release|ARM + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|ARM.Build.0 = Release|ARM + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|ARM64.ActiveCfg = Release|ARM64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|ARM64.Build.0 = Release|ARM64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x64.ActiveCfg = Release|x64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x64.Build.0 = Release|x64 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x86.ActiveCfg = Release|x86 + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {FACB89E5-53A5-4748-9F5B-E0714EBB37B2} = {07CE67B3-8AA2-4572-865F-B3F7FA80CE19} - {FAC17BDF-4003-4359-A366-2E2F380E1BB5} = {07CE67B3-8AA2-4572-865F-B3F7FA80CE19} - EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {183609A0-795E-4886-8165-1377A3A0B948} + SolutionGuid = {64FB9F5C-FD83-4AF6-967F-20344209E367} EndGlobalSection EndGlobal diff --git a/OxyPlot.Windows.snk b/OxyPlot.Windows.snk new file mode 100644 index 0000000000000000000000000000000000000000..1a8edeaefefc4816520e65bc748c0bcfc0b31ef9 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098yqo{VJjPLdS?(t^>Kk6%A*c~IJ!YlOM zCP*nJ;2wHRj#E`r0`{te4Q-dA+_wVe7wHdk)+bqpsRA<Z^9(SfmT zL31BB)B~I`45#aOO7At6Ur@qMq6R?NhG&q)3@c8nIqG6GYjru-wBtaqh|y6B(nb_X zx5q`%4sq0nrHRW~SvdZj&N>0`%qDHfoJFbL2PYbaLpP?2BNx`?TUcaH+% z4T3#JI5l(-tD<12=8KR7EGgoC7$eV)Pr@8-b; i-tu~RmYzJnjh73z8=Ot_uCjm%;}-+kZs0#iEC&>}Xcxl( literal 0 HcmV?d00001 diff --git a/OxyPlot.Windows/Converters/OxyColorConverters.cs b/OxyPlot.Windows/Converters/OxyColorConverters.cs new file mode 100644 index 0000000..31d5686 --- /dev/null +++ b/OxyPlot.Windows/Converters/OxyColorConverters.cs @@ -0,0 +1,85 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2014 OxyPlot contributors +// +// +// Converts from OxyPlot colors to Windows.UI.Color and vice versa. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace OxyPlot.Windows +{ + using System; + + using global::Windows.UI; + using global::Windows.UI.Xaml.Data; + using global::Windows.UI.Xaml.Media; + + /// + /// Converts from OxyPlot colors to Windows.UI.Color and vice versa. + /// + public sealed class OxyColorConverter : IValueConverter + { + /// + /// The convert. + /// + /// The value. + /// The target type. + /// The parameter. + /// The language. + /// The converted value. + public object Convert(object value, Type targetType, object parameter, string language) + { + if (!(value is OxyColor)) + { + return null; + } + + var color = (OxyColor)value; + Color col = Color.FromArgb(color.A, color.R, color.G, color.B); + if (targetType == typeof(Color)) + { + return col; + } + + if (targetType == typeof(Brush)) + { + Brush ret = new SolidColorBrush(col); + return ret; + } + + return null; + } + + /// + /// Converts back. + /// + /// The value. + /// The target type. + /// The parameter. + /// The language. + /// The converted value. + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + if (targetType != typeof(OxyColor)) + { + return null; + } + + if (value is Color) + { + var color = (Color)value; + return OxyColor.FromArgb(color.A, color.R, color.G, color.B); + } + + var scb = value as SolidColorBrush; + if (scb != null) + { + var color = scb.Color; + return OxyColor.FromArgb(color.A, color.R, color.G, color.B); + } + + return null; + } + } +} diff --git a/OxyPlot.Windows/Converters/ThicknessConverter.cs b/OxyPlot.Windows/Converters/ThicknessConverter.cs index 9f8fe92..538bee3 100644 --- a/OxyPlot.Windows/Converters/ThicknessConverter.cs +++ b/OxyPlot.Windows/Converters/ThicknessConverter.cs @@ -19,7 +19,7 @@ namespace OxyPlot.Windows /// /// This is used to convert BorderThickness properties to Path.StrokeThickness (double). /// The maximum thickness value is used. - public class ThicknessConverter : IValueConverter + public sealed class ThicknessConverter : IValueConverter { /// /// Converts the specified value. @@ -56,4 +56,4 @@ public object ConvertBack(object value, Type targetType, object parameter, strin return null; } } -} \ No newline at end of file +} diff --git a/OxyPlot.Windows/Icons/OxyPlot_128.png b/OxyPlot.Windows/Icons/OxyPlot_128.png new file mode 100644 index 0000000000000000000000000000000000000000..e0fa4f351f12c93d4a1cd4f3da9a54142491155a GIT binary patch literal 3486 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 F{{T`yHm?8x literal 0 HcmV?d00001 diff --git a/OxyPlot.Windows/OxyPlot.Windows.2.1.0.nupkg b/OxyPlot.Windows/OxyPlot.Windows.2.1.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..7ff58652c60d6f7ecab93ff2046d36b4171fab5d GIT binary patch literal 61506 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 literal 0 HcmV?d00001 diff --git a/OxyPlot.Windows/OxyPlot.Windows.csproj b/OxyPlot.Windows/OxyPlot.Windows.csproj index ea0b5a3..aeb88e7 100644 --- a/OxyPlot.Windows/OxyPlot.Windows.csproj +++ b/OxyPlot.Windows/OxyPlot.Windows.csproj @@ -1,21 +1,165 @@ - - - uap10.0 - OxyPlot is a plotting library for .NET. This is package contains the UWP implementation. - MIT - Copyright (c) 2014 OxyPlot contributors - https://oxyplot.github.io/ - OxyPlot_128.png - plotting plot charting chart - git - https://github.com/oxyplot/oxyplot.git - True - true - - - - - - - - + + + + + Debug + AnyCPU + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847} + Library + Properties + OxyPlot.Windows + OxyPlot.Windows + ja-JP + UAP + 10.0.19041.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM64 + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM64 + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + PackageReference + + + + + + + + + + + + + + + + 6.2.12 + + + 2.1.0 + + + 2.1.0 + + + + + + + + Designer + MSBuild:Compile + + + + 14.0 + + + + \ No newline at end of file diff --git a/OxyPlot.Windows/OxyPlot.Windows.csproj.user b/OxyPlot.Windows/OxyPlot.Windows.csproj.user new file mode 100644 index 0000000..9b86104 --- /dev/null +++ b/OxyPlot.Windows/OxyPlot.Windows.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/OxyPlot.Windows/OxyPlot.Windows.nuspec b/OxyPlot.Windows/OxyPlot.Windows.nuspec index 5f41f91..c422d48 100644 --- a/OxyPlot.Windows/OxyPlot.Windows.nuspec +++ b/OxyPlot.Windows/OxyPlot.Windows.nuspec @@ -3,7 +3,7 @@ OxyPlot.Windows OxyPlot for Windows apps - $version$ + 2.1.0 Oystein Bjorke OxyPlot is a plotting library for .NET. This package targets the Universal Windows Platform (UAP10). @@ -14,18 +14,19 @@ en-US winrt uap uap10 UWP win10 plotting plot charting chart - + - - - + + + + - - - - - + + + + + - + \ No newline at end of file diff --git a/OxyPlot.Windows/PlotView.cs b/OxyPlot.Windows/PlotView.cs index 976d110..266c719 100644 --- a/OxyPlot.Windows/PlotView.cs +++ b/OxyPlot.Windows/PlotView.cs @@ -26,10 +26,10 @@ namespace OxyPlot.Windows using global::Windows.UI.Xaml.Media.Imaging; /// - /// Represents a control that displays a . + /// /// [TemplatePart(Name = PartGrid, Type = typeof(Grid))] - public class PlotView : Control, IPlotView + public class PlotView : Control, OxyPlot.IPlotView { /// /// Identifies the dependency property. @@ -73,7 +73,6 @@ public class PlotView : Control, IPlotView /// Flags if the cursor is not implemented (Windows Phone). /// private static bool cursorNotImplemented; - /// /// The Grid PART constant. /// @@ -167,7 +166,6 @@ public PlotView() this.ManipulationMode = ManipulationModes.Scale | ManipulationModes.TranslateX | ManipulationModes.TranslateY; } - /// /// Gets or sets the PlotView controller. /// @@ -286,6 +284,7 @@ Model IView.ActualModel } } + /// /// Gets the actual model. /// @@ -335,9 +334,6 @@ public IPlotController ActualController } } - /// - /// Hides the tracker. - /// public void HideTracker() { if (this.currentTracker != null) @@ -347,21 +343,18 @@ public void HideTracker() } } - /// - /// Hides the zoom rectangle. - /// public void HideZoomRectangle() { this.zoomRectangle.Visibility = Visibility.Collapsed; } /// - /// Invalidate the PlotView (not blocking the UI thread) + /// update a plot view. /// - /// if set to true, the data collections will be updated. - public void InvalidatePlot(bool update = true) + /// if the data in a plot view must be updated. + public void InvalidatePlot(bool updateData = true) { - this.UpdateModel(update); + this.UpdateModel(updateData); if (DesignMode.DesignModeEnabled) { @@ -379,10 +372,19 @@ public void InvalidatePlot(bool update = true) } /// - /// Sets the cursor. + /// + /// + /// + public void SetClipboardText(string text) + { + throw new NotImplementedException(); + } + + /// + /// Set the type of cursor. /// - /// The cursor. - public void SetCursorType(CursorType cursor) + /// cursor type + public void SetCursorType(CursorType cursorType) { if (cursorNotImplemented) { @@ -391,7 +393,7 @@ public void SetCursorType(CursorType cursor) } var type = CoreCursorType.Arrow; - switch (cursor) + switch (cursorType) { case CursorType.Default: type = CoreCursorType.Arrow; @@ -409,7 +411,6 @@ public void SetCursorType(CursorType cursor) type = CoreCursorType.SizeNorthwestSoutheast; break; } - // TODO: determine if creating a CoreCursor is possible, do not use exception try { @@ -423,9 +424,9 @@ public void SetCursorType(CursorType cursor) } /// - /// Shows the tracker. + /// Show a tracker. /// - /// The tracker data. + /// public void ShowTracker(TrackerHitResult trackerHitResult) { if (trackerHitResult == null) @@ -466,19 +467,18 @@ public void ShowTracker(TrackerHitResult trackerHitResult) } /// - /// Shows the zoom rectangle. + /// Show a zoom rectangle. /// - /// The rectangle. - public void ShowZoomRectangle(OxyRect r) + /// + public void ShowZoomRectangle(OxyRect rectangle) { - this.zoomRectangle.Width = r.Width; - this.zoomRectangle.Height = r.Height; - Canvas.SetLeft(this.zoomRectangle, r.Left); - Canvas.SetTop(this.zoomRectangle, r.Top); + this.zoomRectangle.Width = rectangle.Width; + this.zoomRectangle.Height = rectangle.Height; + Canvas.SetLeft(this.zoomRectangle, rectangle.Left); + Canvas.SetTop(this.zoomRectangle, rectangle.Top); this.zoomRectangle.Template = this.ZoomRectangleTemplate; this.zoomRectangle.Visibility = Visibility.Visible; } - /// /// Renders the PlotView to a bitmap. /// @@ -791,44 +791,44 @@ protected override void OnPointerExited(PointerRoutedEventArgs e) e.Handled = this.ActualController.HandleMouseLeave(this, e.ToMouseEventArgs(this)); } - /// - /// A one time condition for update visuals so it is called no matter the state of the control - /// Currently with out this, the plotview on Xamarin Forms UWP does not render until the app's window resizes - /// - private bool isUpdateVisualsCalledOnce = false; - - /// - /// Provides the behavior for the Arrange pass of layout. Classes can override this method to define their own Arrange pass behavior. - /// - /// The final area within the parent that this object should use to arrange itself and its children. - /// The actual size that is used after the element is arranged in layout. - protected override Size ArrangeOverride(Size finalSize) - { - if (this.ActualWidth > 0 && this.ActualHeight > 0) - { - if (Interlocked.CompareExchange(ref this.isPlotInvalidated, 0, 1) == 1) - { - this.UpdateVisuals(); - } - } - - //see summary for isUpdateVisualsCalledOnce - if (!isUpdateVisualsCalledOnce) - { - this.UpdateVisuals(); - - isUpdateVisualsCalledOnce = true; - } - - return base.ArrangeOverride(finalSize); - } - - /// - /// Called when the property is changed. - /// - /// The sender. - /// The instance containing the event data. - private static void ModelChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + /// + /// A one time condition for update visuals so it is called no matter the state of the control + /// Currently with out this, the plotview on Xamarin Forms UWP does not render until the app's window resizes + /// + private bool isUpdateVisualsCalledOnce = false; + + /// + /// Provides the behavior for the Arrange pass of layout. Classes can override this method to define their own Arrange pass behavior. + /// + /// The final area within the parent that this object should use to arrange itself and its children. + /// The actual size that is used after the element is arranged in layout. + protected override Size ArrangeOverride(Size finalSize) + { + if (this.ActualWidth > 0 && this.ActualHeight > 0) + { + if (Interlocked.CompareExchange(ref this.isPlotInvalidated, 0, 1) == 1) + { + this.UpdateVisuals(); + } + } + + //see summary for isUpdateVisualsCalledOnce + if (!isUpdateVisualsCalledOnce) + { + this.UpdateVisuals(); + + isUpdateVisualsCalledOnce = true; + } + + return base.ArrangeOverride(finalSize); + } + + /// + /// Called when the property is changed. + /// + /// The sender. + /// The instance containing the event data. + private static void ModelChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((PlotView)sender).OnModelChanged(); } @@ -914,7 +914,7 @@ private void UpdateVisuals() if (this.ActualModel != null) { - ((IPlotModel)this.ActualModel).Render(this.renderContext, this.canvas.ActualWidth, this.canvas.ActualHeight); + ((IPlotModel)this.ActualModel).Render(this.renderContext, ClientArea); } } @@ -939,4 +939,4 @@ private void BeginInvoke(Action action) } } } -} \ No newline at end of file +} diff --git a/OxyPlot.Windows/Properties/AssemblyInfo.cs b/OxyPlot.Windows/Properties/AssemblyInfo.cs index d587aff..ebea1b6 100644 --- a/OxyPlot.Windows/Properties/AssemblyInfo.cs +++ b/OxyPlot.Windows/Properties/AssemblyInfo.cs @@ -2,28 +2,28 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 [assembly: AssemblyTitle("OxyPlot.Windows")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OxyPlot.Windows")] -[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -// Version information for an assembly consists of the following four values: +// アセンブリのバージョン情報は次の 4 つの値で構成されています: // -// Major Version -// Minor Version -// Build Number -// Revision +// メジャー バージョン +// マイナー バージョン +// ビルド番号 +// リビジョン // -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます +// 既定値にすることができます: +//[アセンブリ: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.1.0.0")] +[assembly: AssemblyFileVersion("2.1.0.0")] [assembly: ComVisible(false)] \ No newline at end of file diff --git a/OxyPlot.Windows/Properties/OxyPlot.Windows2.rd.xml b/OxyPlot.Windows/Properties/OxyPlot.Windows2.rd.xml new file mode 100644 index 0000000..e89e21a --- /dev/null +++ b/OxyPlot.Windows/Properties/OxyPlot.Windows2.rd.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml b/OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 0000000..a015706 --- /dev/null +++ b/OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,12 @@ + + + + + Release + Any CPU + bin\Release\net4.8\publish\ + FileSystem + + \ No newline at end of file diff --git a/OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml.user b/OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml.user new file mode 100644 index 0000000..b642d7a --- /dev/null +++ b/OxyPlot.Windows/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -0,0 +1,9 @@ + + + + + False|2021-10-05T05:34:21.1603930Z; + + \ No newline at end of file diff --git a/OxyPlot.Windows/RenderContext.cs b/OxyPlot.Windows/RenderContext.cs index 5dc685a..8fd3078 100644 --- a/OxyPlot.Windows/RenderContext.cs +++ b/OxyPlot.Windows/RenderContext.cs @@ -7,25 +7,26 @@ // // -------------------------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Threading.Tasks; + +using global::Windows.Foundation; +using global::Windows.Storage.Streams; +using global::Windows.UI; +using global::Windows.UI.Text; +using global::Windows.UI.Xaml; +using global::Windows.UI.Xaml.Controls; +using global::Windows.UI.Xaml.Media; +using global::Windows.UI.Xaml.Media.Imaging; +using global::Windows.UI.Xaml.Shapes; +using OxyPlot.Core.Drawing; +using Path = global::Windows.UI.Xaml.Shapes.Path; + namespace OxyPlot.Windows { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Runtime.InteropServices.WindowsRuntime; - using System.Threading.Tasks; - - using global::Windows.Foundation; - using global::Windows.Storage.Streams; - using global::Windows.UI.Text; - using global::Windows.UI.Xaml; - using global::Windows.UI.Xaml.Controls; - using global::Windows.UI.Xaml.Media; - using global::Windows.UI.Xaml.Media.Imaging; - using global::Windows.UI.Xaml.Shapes; - - using Path = global::Windows.UI.Xaml.Shapes.Path; - /// /// Implements for . /// @@ -66,6 +67,8 @@ public class RenderContext : IRenderContext /// private bool clip; + private readonly Stack clipStack; + /// /// Initializes a new instance of the class. /// @@ -76,6 +79,7 @@ public RenderContext(Canvas canvas) this.Width = canvas.ActualWidth; this.Height = canvas.ActualHeight; this.RendersToScreen = true; + this.clipStack = new Stack(); } /// @@ -108,6 +112,12 @@ public bool PaintBackground /// true if the context renders to screen; otherwise, false. public bool RendersToScreen { get; set; } + + /// + /// Gets the number of clipped. + /// + public int ClipCount => this.clipStack.Count; + /// /// Draws an ellipse. /// @@ -115,7 +125,9 @@ public bool PaintBackground /// The fill color. /// The stroke color. /// The thickness. - public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness) + /// The rendering mode. + public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode) { var el = new Ellipse { @@ -148,7 +160,8 @@ public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thi /// The fill color. /// The stroke color. /// The stroke thickness. - public void DrawEllipses(IList rectangles, OxyColor fill, OxyColor stroke, double thickness) + /// The rendering mode. + public void DrawEllipses(IList rectangles, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode) { var path = new Path { @@ -183,28 +196,23 @@ public void DrawEllipses(IList rectangles, OxyColor fill, OxyColor stro /// The points. /// The stroke color. /// The stroke thickness. + /// The rendering mode. /// The dash array. /// The line join type. - /// if set to true the shape will be aliased. - public void DrawLine( - IList points, - OxyColor stroke, - double thickness, - double[] dashArray, - LineJoin lineJoin, - bool aliased) + public void DrawLine(IList points, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode, + double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) { var e = new Polyline { CompositeMode = ElementCompositeMode.SourceOver }; - this.SetStroke(e, stroke, thickness, lineJoin, dashArray, aliased); - - var pc = new PointCollection(); + this.SetStroke(e, stroke, thickness, lineJoin, dashArray, false); + PointCollection pc = new PointCollection(); foreach (var p in points) { - pc.Add(p.ToPoint(aliased)); + Point pnt = new Point(p.X, p.Y); + pc.Add(pnt); } e.Points = pc; @@ -219,23 +227,18 @@ public void DrawLine( /// The points. /// The stroke color. /// The stroke thickness. + /// The rendering mode. /// The dash array. /// The line join type. - /// if set to true the shape will be aliased. - public void DrawLineSegments( - IList points, - OxyColor stroke, - double thickness, - double[] dashArray, - LineJoin lineJoin, - bool aliased) + public void DrawLineSegments(IList points, OxyColor stroke, double thickness, + EdgeRenderingMode edgeRenderingMode, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) { var path = new Path { CompositeMode = ElementCompositeMode.SourceOver }; - this.SetStroke(path, stroke, thickness, lineJoin, dashArray, aliased); + this.SetStroke(path, stroke, thickness, lineJoin, dashArray); var pg = new PathGeometry(); for (int i = 0; i + 1 < points.Count; i += 2) { @@ -251,8 +254,10 @@ public void DrawLineSegments( // Add(line); // continue; // } - var figure = new PathFigure { StartPoint = points[i].ToPoint(aliased), IsClosed = false }; - figure.Segments.Add(new LineSegment { Point = points[i + 1].ToPoint(aliased) }); + Point pnt1 = new Point(points[i].X, points[i].Y); + Point pnt2 = new Point(points[i + 1].X, points[i + 1].Y); + var figure = new PathFigure { StartPoint = pnt1, IsClosed = false }; + figure.Segments.Add(new LineSegment { Point = pnt2 }); pg.Figures.Add(figure); } @@ -267,34 +272,29 @@ public void DrawLineSegments( /// The fill color. /// The stroke color. /// The stroke thickness. + /// The rendering mode. /// The dash array. /// The line join type. - /// if set to true the shape will be aliased. - public void DrawPolygon( - IList points, - OxyColor fill, - OxyColor stroke, - double thickness, - double[] dashArray, - LineJoin lineJoin, - bool aliased) + public void DrawPolygon(IList points, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) { var po = new Polygon { CompositeMode = ElementCompositeMode.SourceOver }; - this.SetStroke(po, stroke, thickness, lineJoin, dashArray, aliased); + this.SetStroke(po, stroke, thickness, lineJoin, dashArray); if (fill.IsVisible()) { po.Fill = this.GetCachedBrush(fill); } - var pc = new PointCollection(); + PointCollection pc = new PointCollection(); foreach (var p in points) { - pc.Add(p.ToPoint(aliased)); + Point pnt = new Point(p.X, p.Y); + pc.Add(pnt); } po.Points = pc; @@ -310,24 +310,19 @@ public void DrawPolygon( /// The fill color. /// The stroke color. /// The stroke thickness. + /// The rendering mode. /// The dash array. /// The line join type. - /// if set to true the shape will be aliased. - public void DrawPolygons( - IList> polygons, - OxyColor fill, - OxyColor stroke, - double thickness, - double[] dashArray, - LineJoin lineJoin, - bool aliased) + public void DrawPolygons(IList> polygons, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) + { var path = new Path { CompositeMode = ElementCompositeMode.SourceOver }; - this.SetStroke(path, stroke, thickness, lineJoin, dashArray, aliased); + this.SetStroke(path, stroke, thickness, lineJoin, dashArray); if (fill.IsVisible()) { path.Fill = this.GetCachedBrush(fill); @@ -340,14 +335,15 @@ public void DrawPolygons( bool first = true; foreach (var p in polygon) { + Point pnt = new Point(p.X, p.Y); if (first) { - figure.StartPoint = p.ToPoint(aliased); + figure.StartPoint = pnt; first = false; } else { - figure.Segments.Add(new LineSegment { Point = p.ToPoint(aliased) }); + figure.Segments.Add(new LineSegment { Point = pnt }); } } @@ -361,11 +357,13 @@ public void DrawPolygons( /// /// Draws the rectangle. /// - /// The rectangle. + /// The rectangle. /// The fill color. /// The stroke color. /// The stroke thickness. - public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness) + /// Rendering mode. + public void DrawRectangle(OxyRect rectangle, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode) { var el = new Rectangle { @@ -374,20 +372,22 @@ public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double t if (stroke.IsVisible()) { - el.Stroke = new SolidColorBrush(stroke.ToColor()); + Color col = Color.FromArgb(stroke.A, stroke.R, stroke.G, stroke.B); + el.Stroke = new SolidColorBrush(col); el.StrokeThickness = thickness; } if (fill.IsVisible()) { - el.Fill = new SolidColorBrush(fill.ToColor()); + Color col = Color.FromArgb(fill.A, fill.R, fill.G, fill.B); + el.Fill = new SolidColorBrush(col); } - el.Width = rect.Width; - el.Height = rect.Height; - Canvas.SetLeft(el, rect.Left); - Canvas.SetTop(el, rect.Top); - this.Add(el, rect.Left, rect.Top); + el.Width = rectangle.Width; + el.Height = rectangle.Height; + Canvas.SetLeft(el, rectangle.Left); + Canvas.SetTop(el, rectangle.Top); + this.Add(el, rectangle.Left, rectangle.Top); } /// @@ -398,7 +398,9 @@ public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double t /// The fill color. /// The stroke color. /// The stroke thickness. - public void DrawRectangles(IList rectangles, OxyColor fill, OxyColor stroke, double thickness) + /// The rendering mode. + public void DrawRectangles(IList rectangles, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode) { var path = new Path { @@ -414,7 +416,8 @@ public void DrawRectangles(IList rectangles, OxyColor fill, OxyColor st var gg = new GeometryGroup { FillRule = FillRule.Nonzero }; foreach (var rect in rectangles) { - gg.Children.Add(new RectangleGeometry { Rect = rect.ToRect(true) }); + Rect r = rect.ToRect(false); + gg.Children.Add(new RectangleGeometry { Rect = new Rect(r.X, r.Y, r.Width, r.Height) }); } path.Data = gg; @@ -635,7 +638,8 @@ public void DrawImage( /// True if the clipping rectangle was set. public bool SetClip(OxyRect clippingRect) { - this.clipRect = clippingRect.ToRect(false); + Rect rect = clippingRect.ToRect(false); + this.clipRect = new Rect(rect.X, rect.Y, rect.Width, rect.Height); this.clip = true; return true; } @@ -689,7 +693,17 @@ private static DoubleCollection CreateDashArrayCollection(IEnumerable da /// A private static FontWeight GetFontWeight(double fontWeight) { - return fontWeight > OxyPlot.FontWeights.Normal ? FontWeights.Bold : FontWeights.Normal; + FontWeight fw; + + if (fontWeight > OxyPlot.FontWeights.Normal) + { + fw = new FontWeight() { Weight = (ushort)FontWeights.Bold }; + } + else + { + fw = new FontWeight() { Weight = (ushort)FontWeights.Normal }; + } + return fw; } /// @@ -767,7 +781,7 @@ private void SetStroke( shape.StrokeLineJoin = PenLineJoin.Bevel; break; - // The default StrokeLineJoin is Miter + // The default StrokeLineJoin is Miter } shape.StrokeThickness = thickness; @@ -838,5 +852,55 @@ private static async Task ConvertToRandomAccessStream(byte[ randomAccessStream.Seek(0); return randomAccessStream; } + /// + /// Push a Clip data. + /// + /// + public void PushClip(OxyRect clippingRectangle) + { + if (this.clipStack.Count > 0) + { + OxyRect currentClippingRectangle = this.clipStack.Peek(); + OxyRect newClippingRectangle = clippingRectangle.Intersect(currentClippingRectangle); + if (!currentClippingRectangle.Equals(newClippingRectangle)) + { + this.ResetClip(); + this.SetClip(newClippingRectangle); + } + + this.clipStack.Push(newClippingRectangle); + } + else + { + this.SetClip(clippingRectangle); + this.clipStack.Push(clippingRectangle); + } + } + + /// + /// Pop a Clip data. + /// + public void PopClip() + { + if (this.clipStack.Count == 0) + { + throw new InvalidOperationException($"Unbalanced call to {nameof(PopClip)}"); + } + + OxyRect currentClippingRectangle = this.clipStack.Pop(); + if (this.clipStack.Count > 0) + { + OxyRect newClippingRectangle = this.clipStack.Peek(); + if (!newClippingRectangle.Equals(currentClippingRectangle)) + { + this.ResetClip(); + this.SetClip(newClippingRectangle); + } + } + else + { + this.ResetClip(); + } + } } } \ No newline at end of file diff --git a/OxyPlot.Windows/Themes/Generic.xaml b/OxyPlot.Windows/Themes/Generic.xaml index a2249ba..2ba0663 100644 --- a/OxyPlot.Windows/Themes/Generic.xaml +++ b/OxyPlot.Windows/Themes/Generic.xaml @@ -1,4 +1,4 @@ - diff --git a/OxyPlot.Windows/Tracker/TrackerControl.cs b/OxyPlot.Windows/Tracker/TrackerControl.cs index 854412a..ed52db4 100644 --- a/OxyPlot.Windows/Tracker/TrackerControl.cs +++ b/OxyPlot.Windows/Tracker/TrackerControl.cs @@ -525,16 +525,16 @@ private void UpdatePositionAndBorder() Size contentSize = this.contentContainer.DesiredSize; this.contentContainer.RenderTransform = new TranslateTransform - { - X = dx * contentSize.Width, - Y = dy * contentSize.Height - }; + { + X = dx * contentSize.Width, + Y = dy * contentSize.Height + }; #if WPF ScreenPoint pos = this.Position; #endif #if SILVERLIGHT || NETFX_CORE - Point pos = this.Position.ToPoint(true); + Point pos = new Point(this.Position.X, this.Position.Y); #endif if (this.horizontalLine != null) @@ -588,12 +588,12 @@ private Geometry CreateBorderGeometry( var rect = new Rect( ha == HorizontalAlignment.Left ? m : 0, va == VerticalAlignment.Top ? m : 0, width, height); margin = new Thickness - { - Left = ha == HorizontalAlignment.Left ? m : 0, - Top = va == VerticalAlignment.Top ? m : 0, - Right = ha == HorizontalAlignment.Right ? m : 0, - Bottom = va == VerticalAlignment.Bottom ? m : 0 - }; + { + Left = ha == HorizontalAlignment.Left ? m : 0, + Top = va == VerticalAlignment.Top ? m : 0, + Right = ha == HorizontalAlignment.Right ? m : 0, + Bottom = va == VerticalAlignment.Bottom ? m : 0 + }; return new RectangleGeometry { Rect = rect /*, RadiusX = this.CornerRadius, RadiusY = this.CornerRadius*/ }; } @@ -749,4 +749,4 @@ private Geometry CreatePointerBorderGeometry( return new PathGeometry { Figures = new PathFigureCollection { pf } }; } } -} \ No newline at end of file +} diff --git a/OxyPlot.Windows/Tracker/TrackerDefinition.cs b/OxyPlot.Windows/Tracker/TrackerDefinition.cs index 0a4f9ac..94a9254 100644 --- a/OxyPlot.Windows/Tracker/TrackerDefinition.cs +++ b/OxyPlot.Windows/Tracker/TrackerDefinition.cs @@ -67,4 +67,4 @@ public ControlTemplate TrackerTemplate } } } -} \ No newline at end of file +} diff --git a/OxyPlot.Windows/Utilities/ConverterExtensions.cs b/OxyPlot.Windows/Utilities/ConverterExtensions.cs index 3243c80..85200e2 100644 --- a/OxyPlot.Windows/Utilities/ConverterExtensions.cs +++ b/OxyPlot.Windows/Utilities/ConverterExtensions.cs @@ -553,4 +553,4 @@ public static ScreenPoint[] ToScreenPointArray(this Point[] points) return pts; } } -} \ No newline at end of file +} diff --git a/OxyPlot.Windows/Utilities/MouseButtonHelper.cs b/OxyPlot.Windows/Utilities/MouseButtonHelper.cs index cdd2f66..56f2893 100644 --- a/OxyPlot.Windows/Utilities/MouseButtonHelper.cs +++ b/OxyPlot.Windows/Utilities/MouseButtonHelper.cs @@ -89,4 +89,4 @@ private static double Distance(this Point pointA, Point pointB) return Math.Sqrt((x * x) + (y * y)); } } -} \ No newline at end of file +} diff --git a/OxyPlot.Windows/Utilities/OxyPlot.Windows.2.1.0.nupkg b/OxyPlot.Windows/Utilities/OxyPlot.Windows.2.1.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..7ff58652c60d6f7ecab93ff2046d36b4171fab5d GIT binary patch literal 61506 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 literal 0 HcmV?d00001 diff --git a/OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj b/OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj new file mode 100644 index 0000000..aeb88e7 --- /dev/null +++ b/OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj @@ -0,0 +1,165 @@ + + + + + Debug + AnyCPU + {4F5B1D20-EA97-4DBB-94E1-8D86B4152847} + Library + Properties + OxyPlot.Windows + OxyPlot.Windows + ja-JP + UAP + 10.0.19041.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + ARM64 + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + ARM64 + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + false + prompt + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + false + prompt + + + PackageReference + + + + + + + + + + + + + + + + 6.2.12 + + + 2.1.0 + + + 2.1.0 + + + + + + + + Designer + MSBuild:Compile + + + + 14.0 + + + + \ No newline at end of file diff --git a/OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj.user b/OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj.user new file mode 100644 index 0000000..9b86104 --- /dev/null +++ b/OxyPlot.Windows/Utilities/OxyPlot.Windows.csproj.user @@ -0,0 +1,6 @@ + + + + ShowAllFiles + + \ No newline at end of file diff --git a/OxyPlot.Windows/Utilities/OxyPlot.Windows.nuspec b/OxyPlot.Windows/Utilities/OxyPlot.Windows.nuspec new file mode 100644 index 0000000..c422d48 --- /dev/null +++ b/OxyPlot.Windows/Utilities/OxyPlot.Windows.nuspec @@ -0,0 +1,32 @@ + + + + OxyPlot.Windows + OxyPlot for Windows apps + 2.1.0 + Oystein Bjorke + OxyPlot is a plotting library for .NET. This package targets the Universal Windows Platform (UAP10). + + https://raw.githubusercontent.com/oxyplot/oxyplot/master/LICENSE + http://oxyplot.org/ + https://raw.githubusercontent.com/oxyplot/oxyplot/develop/Icons/OxyPlot_128.png + false + en-US + winrt uap uap10 UWP win10 plotting plot charting chart + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OxyPlot.Windows/Utilities/PlotView.cs b/OxyPlot.Windows/Utilities/PlotView.cs new file mode 100644 index 0000000..266c719 --- /dev/null +++ b/OxyPlot.Windows/Utilities/PlotView.cs @@ -0,0 +1,942 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2014 OxyPlot contributors +// +// +// Represents a control that displays a . +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace OxyPlot.Windows +{ + using System; + using System.Collections.ObjectModel; + using System.Linq; + using System.Threading; + + using global::Windows.ApplicationModel; + using global::Windows.ApplicationModel.DataTransfer; + using global::Windows.Devices.Input; + using global::Windows.Foundation; + using global::Windows.System; + using global::Windows.UI.Core; + using global::Windows.UI.Xaml; + using global::Windows.UI.Xaml.Controls; + using global::Windows.UI.Xaml.Input; + using global::Windows.UI.Xaml.Media.Imaging; + + /// + /// + /// + [TemplatePart(Name = PartGrid, Type = typeof(Grid))] + public class PlotView : Control, OxyPlot.IPlotView + { + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ControllerProperty = + DependencyProperty.Register("Controller", typeof(IPlotController), typeof(PlotView), new PropertyMetadata(null)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty DefaultTrackerTemplateProperty = + DependencyProperty.Register( + "DefaultTrackerTemplate", typeof(ControlTemplate), typeof(PlotView), new PropertyMetadata(null)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty HandleRightClicksProperty = + DependencyProperty.Register("HandleRightClicks", typeof(bool), typeof(PlotView), new PropertyMetadata(true)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty IsMouseWheelEnabledProperty = + DependencyProperty.Register("IsMouseWheelEnabled", typeof(bool), typeof(PlotView), new PropertyMetadata(true)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register( + "Model", typeof(PlotModel), typeof(PlotView), new PropertyMetadata(null, ModelChanged)); + + /// + /// Identifies the dependency property. + /// + public static readonly DependencyProperty ZoomRectangleTemplateProperty = + DependencyProperty.Register( + "ZoomRectangleTemplate", typeof(ControlTemplate), typeof(PlotView), new PropertyMetadata(null)); + + /// + /// Flags if the cursor is not implemented (Windows Phone). + /// + private static bool cursorNotImplemented; + /// + /// The Grid PART constant. + /// + private const string PartGrid = "PART_Grid"; + + /// + /// The model lock. + /// + private readonly object modelLock = new object(); + + /// + /// The tracker definitions. + /// + private readonly ObservableCollection trackerDefinitions; + + /// + /// The canvas. + /// + private Canvas canvas; + + /// + /// The current model. + /// + private PlotModel currentModel; + + /// + /// The current tracker. + /// + private FrameworkElement currentTracker; + + /// + /// The grid. + /// + private Grid grid; + + /// + /// The default controller. + /// + private IPlotController defaultController; + + /// + /// The state of the Alt key. + /// + private bool isAltPressed; + + /// + /// The state of the Windows key. + /// + private bool isWindowsPressed; + + /// + /// The state of the Control key. + /// + private bool isControlPressed; + + /// + /// The is PlotView invalidated. + /// + private int isPlotInvalidated; + + /// + /// The is shift pressed. + /// + private bool isShiftPressed; + + /// + /// The overlays. + /// + private Canvas overlays; + + /// + /// The render context + /// + private RenderContext renderContext; + + /// + /// The zoom control. + /// + private ContentControl zoomRectangle; + + /// + /// Initializes a new instance of the class. + /// + public PlotView() + { + this.DefaultStyleKey = typeof(PlotView); + + this.trackerDefinitions = new ObservableCollection(); + this.Loaded += this.OnLoaded; + this.SizeChanged += this.OnSizeChanged; + this.ManipulationMode = ManipulationModes.Scale | ManipulationModes.TranslateX + | ManipulationModes.TranslateY; + } + /// + /// Gets or sets the PlotView controller. + /// + /// The PlotView controller. + public IPlotController Controller + { + get { return (IPlotController)this.GetValue(ControllerProperty); } + set { this.SetValue(ControllerProperty, value); } + } + + /// + /// Gets or sets the default tracker template. + /// + public ControlTemplate DefaultTrackerTemplate + { + get + { + return (ControlTemplate)this.GetValue(DefaultTrackerTemplateProperty); + } + + set + { + this.SetValue(DefaultTrackerTemplateProperty, value); + } + } + + /// + /// Gets or sets a value indicating whether to handle right clicks. + /// + public bool HandleRightClicks + { + get + { + return (bool)this.GetValue(HandleRightClicksProperty); + } + + set + { + this.SetValue(HandleRightClicksProperty, value); + } + } + + /// + /// Gets or sets a value indicating whether IsMouseWheelEnabled. + /// + public bool IsMouseWheelEnabled + { + get + { + return (bool)this.GetValue(IsMouseWheelEnabledProperty); + } + + set + { + this.SetValue(IsMouseWheelEnabledProperty, value); + } + } + + /// + /// Gets or sets the to show. + /// + /// The . + public PlotModel Model + { + get + { + return (PlotModel)this.GetValue(ModelProperty); + } + + set + { + this.SetValue(ModelProperty, value); + } + } + + /// + /// Gets or sets the zoom rectangle template. + /// + /// The zoom rectangle template. + public ControlTemplate ZoomRectangleTemplate + { + get + { + return (ControlTemplate)this.GetValue(ZoomRectangleTemplateProperty); + } + + set + { + this.SetValue(ZoomRectangleTemplateProperty, value); + } + } + + /// + /// Gets the tracker definitions. + /// + /// The tracker definitions. + public ObservableCollection TrackerDefinitions + { + get + { + return this.trackerDefinitions; + } + } + + /// + /// Gets the actual model in the view. + /// + /// + /// The actual model. + /// + Model IView.ActualModel + { + get + { + return this.Model; + } + } + + + /// + /// Gets the actual model. + /// + /// The actual model. + public PlotModel ActualModel + { + get + { + return this.currentModel; + } + } + + /// + /// Gets the actual controller. + /// + /// + /// The actual . + /// + IController IView.ActualController + { + get + { + return this.ActualController; + } + } + + /// + /// Gets the coordinates of the client area of the view. + /// + public OxyRect ClientArea + { + get + { + return new OxyRect(0, 0, this.ActualWidth, this.ActualHeight); + } + } + + /// + /// Gets the actual PlotView controller. + /// + /// The actual PlotView controller. + public IPlotController ActualController + { + get + { + return this.Controller ?? (this.defaultController ?? (this.defaultController = new PlotController())); + } + } + + public void HideTracker() + { + if (this.currentTracker != null) + { + this.overlays.Children.Remove(this.currentTracker); + this.currentTracker = null; + } + } + + public void HideZoomRectangle() + { + this.zoomRectangle.Visibility = Visibility.Collapsed; + } + + /// + /// update a plot view. + /// + /// if the data in a plot view must be updated. + public void InvalidatePlot(bool updateData = true) + { + this.UpdateModel(updateData); + + if (DesignMode.DesignModeEnabled) + { + this.InvalidateArrange(); + return; + } + + if (Interlocked.CompareExchange(ref this.isPlotInvalidated, 1, 0) == 0) + { + // Invalidate the arrange state for the element. + // After the invalidation, the element will have its layout updated, + // which will occur asynchronously unless subsequently forced by UpdateLayout. + this.BeginInvoke(this.InvalidateArrange); + } + } + + /// + /// + /// + /// + public void SetClipboardText(string text) + { + throw new NotImplementedException(); + } + + /// + /// Set the type of cursor. + /// + /// cursor type + public void SetCursorType(CursorType cursorType) + { + if (cursorNotImplemented) + { + // setting the cursor has failed in a previous attempt, see code below + return; + } + + var type = CoreCursorType.Arrow; + switch (cursorType) + { + case CursorType.Default: + type = CoreCursorType.Arrow; + break; + case CursorType.Pan: + type = CoreCursorType.Hand; + break; + case CursorType.ZoomHorizontal: + type = CoreCursorType.SizeWestEast; + break; + case CursorType.ZoomVertical: + type = CoreCursorType.SizeNorthSouth; + break; + case CursorType.ZoomRectangle: + type = CoreCursorType.SizeNorthwestSoutheast; + break; + } + // TODO: determine if creating a CoreCursor is possible, do not use exception + try + { + var newCursor = new CoreCursor(type, 1); // this line throws an exception on Windows Phone + Window.Current.CoreWindow.PointerCursor = newCursor; + } + catch (NotImplementedException) + { + cursorNotImplemented = true; + } + } + + /// + /// Show a tracker. + /// + /// + public void ShowTracker(TrackerHitResult trackerHitResult) + { + if (trackerHitResult == null) + { + this.HideTracker(); + return; + } + + var trackerTemplate = this.DefaultTrackerTemplate; + if (trackerHitResult.Series != null && !string.IsNullOrEmpty(trackerHitResult.Series.TrackerKey)) + { + var match = this.TrackerDefinitions.FirstOrDefault(t => t.TrackerKey == trackerHitResult.Series.TrackerKey); + if (match != null) + { + trackerTemplate = match.TrackerTemplate; + } + } + + if (trackerTemplate == null) + { + this.HideTracker(); + return; + } + + var tracker = new ContentControl { Template = trackerTemplate }; + + if (tracker != this.currentTracker) + { + this.HideTracker(); + this.overlays.Children.Add(tracker); + this.currentTracker = tracker; + } + + if (this.currentTracker != null) + { + this.currentTracker.DataContext = trackerHitResult; + } + } + + /// + /// Show a zoom rectangle. + /// + /// + public void ShowZoomRectangle(OxyRect rectangle) + { + this.zoomRectangle.Width = rectangle.Width; + this.zoomRectangle.Height = rectangle.Height; + Canvas.SetLeft(this.zoomRectangle, rectangle.Left); + Canvas.SetTop(this.zoomRectangle, rectangle.Top); + this.zoomRectangle.Template = this.ZoomRectangleTemplate; + this.zoomRectangle.Visibility = Visibility.Visible; + } + /// + /// Renders the PlotView to a bitmap. + /// + /// A bitmap. + public WriteableBitmap ToBitmap() + { + throw new NotImplementedException(); + + // var bmp = new RenderTargetBitmap( + // (int)this.ActualWidth, (int)this.ActualHeight, 96, 96, PixelFormats.Pbgra32); + // bmp.Render(this); + // return bmp; + } + + /// + /// Stores text on the clipboard. + /// + /// The text. + void IPlotView.SetClipboardText(string text) + { + var pkg = new DataPackage(); + pkg.SetText(text); + + // TODO: Clipboard.SetContent(pkg); + } + + /// + /// Invoked whenever application code or internal processes (such as a rebuilding layout pass) call ApplyTemplate. In simplest terms, this means the method is called just before a UI element displays in your app. Override this method to influence the default post-template logic of a class. + /// + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + this.grid = this.GetTemplateChild(PartGrid) as Grid; + if (this.grid == null) + { + return; + } + + this.canvas = new Canvas { IsHitTestVisible = false }; + this.grid.Children.Add(this.canvas); + this.canvas.UpdateLayout(); + + this.renderContext = new RenderContext(this.canvas); + + this.overlays = new Canvas(); + this.grid.Children.Add(this.overlays); + + this.zoomRectangle = new ContentControl(); + this.overlays.Children.Add(this.zoomRectangle); + } + + /// + /// Called before the KeyDown event occurs. + /// + /// The data for the event. + protected override void OnKeyDown(KeyRoutedEventArgs e) + { + switch (e.Key) + { + case VirtualKey.Control: + this.isControlPressed = true; + break; + case VirtualKey.Shift: + this.isShiftPressed = true; + break; + case VirtualKey.Menu: + this.isAltPressed = true; + break; + case VirtualKey.LeftWindows: + case VirtualKey.RightWindows: + this.isWindowsPressed = true; + break; + } + + var modifiers = OxyModifierKeys.None; + if (this.isControlPressed) + { + modifiers |= OxyModifierKeys.Control; + } + + if (this.isAltPressed) + { + modifiers |= OxyModifierKeys.Control; + } + + if (this.isShiftPressed) + { + modifiers |= OxyModifierKeys.Shift; + } + + if (this.isWindowsPressed) + { + modifiers |= OxyModifierKeys.Windows; + } + + if (e.Handled) + { + return; + } + + var args = new OxyKeyEventArgs + { + Key = e.Key.Convert(), + ModifierKeys = modifiers, + }; + + e.Handled = this.ActualController.HandleKeyDown(this, args); + } + + /// + /// Called before the KeyUp event occurs. + /// + /// The data for the event. + protected override void OnKeyUp(KeyRoutedEventArgs e) + { + base.OnKeyUp(e); + switch (e.Key) + { + case VirtualKey.Control: + this.isControlPressed = false; + break; + case VirtualKey.Shift: + this.isShiftPressed = false; + break; + case VirtualKey.Menu: + this.isAltPressed = false; + break; + case VirtualKey.LeftWindows: + case VirtualKey.RightWindows: + this.isWindowsPressed = false; + break; + } + } + + /// + /// Called before the ManipulationStarted event occurs. + /// + /// Event data for the event. + protected override void OnManipulationStarted(ManipulationStartedRoutedEventArgs e) + { + base.OnManipulationStarted(e); + + if (e.Handled) + { + return; + } + + if (e.PointerDeviceType == PointerDeviceType.Touch) + { + this.Focus(FocusState.Pointer); + e.Handled = this.ActualController.HandleTouchStarted(this, e.ToTouchEventArgs(this)); + } + } + + /// + /// Called before the ManipulationDelta event occurs. + /// + /// Event data for the event. + protected override void OnManipulationDelta(ManipulationDeltaRoutedEventArgs e) + { + base.OnManipulationDelta(e); + + if (e.Handled) + { + return; + } + + if (e.PointerDeviceType == PointerDeviceType.Touch) + { + e.Handled = this.ActualController.HandleTouchDelta(this, e.ToTouchEventArgs(this)); + } + } + + /// + /// Called before the ManipulationCompleted event occurs. + /// + /// Event data for the event. + protected override void OnManipulationCompleted(ManipulationCompletedRoutedEventArgs e) + { + base.OnManipulationCompleted(e); + + if (e.Handled) + { + return; + } + + if (e.PointerDeviceType == PointerDeviceType.Touch) + { + e.Handled = this.ActualController.HandleTouchCompleted(this, e.ToTouchEventArgs(this)); + } + } + + /// + /// Called before the PointerPressed event occurs. + /// + /// Event data for the event. + protected override void OnPointerPressed(PointerRoutedEventArgs e) + { + base.OnPointerPressed(e); + + if (e.Handled) + { + return; + } + + if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse) + { + this.Focus(FocusState.Pointer); + this.CapturePointer(e.Pointer); + + e.Handled = this.ActualController.HandleMouseDown(this, e.ToMouseDownEventArgs(this)); + } + else if (e.Pointer.PointerDeviceType == PointerDeviceType.Touch) + { + this.Focus(FocusState.Pointer); + + e.Handled = this.ActualController.HandleTouchStarted(this, e.ToTouchEventArgs(this)); + } + } + + /// + /// Called before the PointerMoved event occurs. + /// + /// Event data for the event. + protected override void OnPointerMoved(PointerRoutedEventArgs e) + { + base.OnPointerMoved(e); + + if (e.Handled) + { + return; + } + + if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse) + { + e.Handled = this.ActualController.HandleMouseMove(this, e.ToMouseEventArgs(this)); + } + + // Note: don't handle touch here, this is also handled when moving over when a touch device + } + + /// + /// Called before the PointerReleased event occurs. + /// + /// Event data for the event. + protected override void OnPointerReleased(PointerRoutedEventArgs e) + { + base.OnPointerReleased(e); + + if (e.Handled) + { + return; + } + + if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse) + { + this.ReleasePointerCapture(e.Pointer); + e.Handled = this.ActualController.HandleMouseUp(this, e.ToMouseEventArgs(this)); + } + else if (e.Pointer.PointerDeviceType == PointerDeviceType.Touch) + { + e.Handled = this.ActualController.HandleTouchCompleted(this, e.ToTouchEventArgs(this)); + } + } + + /// + /// Called before the PointerWheelChanged event occurs. + /// + /// Event data for the event. + protected override void OnPointerWheelChanged(PointerRoutedEventArgs e) + { + base.OnPointerWheelChanged(e); + + if (e.Handled || !this.IsMouseWheelEnabled) + { + return; + } + + e.Handled = this.ActualController.HandleMouseWheel(this, e.ToMouseWheelEventArgs(this)); + } + + /// + /// Called before the PointerEntered event occurs. + /// + /// Event data for the event. + protected override void OnPointerEntered(PointerRoutedEventArgs e) + { + base.OnPointerEntered(e); + if (e.Handled) + { + return; + } + + e.Handled = this.ActualController.HandleMouseEnter(this, e.ToMouseEventArgs(this)); + } + + /// + /// Called before the PointerExited event occurs. + /// + /// Event data for the event. + protected override void OnPointerExited(PointerRoutedEventArgs e) + { + base.OnPointerExited(e); + if (e.Handled) + { + return; + } + + e.Handled = this.ActualController.HandleMouseLeave(this, e.ToMouseEventArgs(this)); + } + + /// + /// A one time condition for update visuals so it is called no matter the state of the control + /// Currently with out this, the plotview on Xamarin Forms UWP does not render until the app's window resizes + /// + private bool isUpdateVisualsCalledOnce = false; + + /// + /// Provides the behavior for the Arrange pass of layout. Classes can override this method to define their own Arrange pass behavior. + /// + /// The final area within the parent that this object should use to arrange itself and its children. + /// The actual size that is used after the element is arranged in layout. + protected override Size ArrangeOverride(Size finalSize) + { + if (this.ActualWidth > 0 && this.ActualHeight > 0) + { + if (Interlocked.CompareExchange(ref this.isPlotInvalidated, 0, 1) == 1) + { + this.UpdateVisuals(); + } + } + + //see summary for isUpdateVisualsCalledOnce + if (!isUpdateVisualsCalledOnce) + { + this.UpdateVisuals(); + + isUpdateVisualsCalledOnce = true; + } + + return base.ArrangeOverride(finalSize); + } + + /// + /// Called when the property is changed. + /// + /// The sender. + /// The instance containing the event data. + private static void ModelChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + ((PlotView)sender).OnModelChanged(); + } + + /// + /// Called when the control is loaded. + /// + /// The sender. + /// The instance containing the event data. + private void OnLoaded(object sender, RoutedEventArgs e) + { + // Make sure InvalidateArrange is called when the PlotView is invalidated + Interlocked.Exchange(ref this.isPlotInvalidated, 0); + this.InvalidatePlot(); + } + + /// + /// Called when the model is changed. + /// + private void OnModelChanged() + { + lock (this.modelLock) + { + if (this.currentModel != null) + { + ((IPlotModel)this.currentModel).AttachPlotView(null); + this.currentModel = null; + } + + if (this.Model != null) + { + ((IPlotModel)this.Model).AttachPlotView(this); + this.currentModel = this.Model; + } + } + + this.InvalidatePlot(); + } + + /// + /// Called when the size of the control is changed. + /// + /// The sender. + /// The instance containing the event data. + private void OnSizeChanged(object sender, SizeChangedEventArgs e) + { + this.InvalidatePlot(false); + } + + /// + /// Updates the model. + /// + /// if set to true, the data collections will be updated. + private void UpdateModel(bool update) + { + if (this.ActualModel != null) + { + ((IPlotModel)this.ActualModel).Update(update); + } + } + + /// + /// Updates the visuals. + /// + private void UpdateVisuals() + { + if (this.canvas == null || this.renderContext == null) + { + return; + } + + // Clear the canvas + this.canvas.Children.Clear(); + + if (this.ActualModel != null && !this.ActualModel.Background.IsUndefined()) + { + this.canvas.Background = this.ActualModel.Background.ToBrush(); + } + else + { + this.canvas.Background = null; + } + + if (this.ActualModel != null) + { + ((IPlotModel)this.ActualModel).Render(this.renderContext, ClientArea); + } + } + + /// + /// Invokes the specified action on the UI Thread (without blocking the calling thread). + /// + /// The action. + private void BeginInvoke(Action action) + { + if (!this.Dispatcher.HasThreadAccess) + { + // TODO: Fix warning? + // Because this call is not awaited, execution of the current method continues before the call is completed. + // Consider applying the 'await' operator to the result of the call. +#pragma warning disable 4014 + this.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => action()); +#pragma warning restore 4014 + } + else + { + action(); + } + } + } +} diff --git a/OxyPlot.Windows/Utilities/RenderContext.cs b/OxyPlot.Windows/Utilities/RenderContext.cs new file mode 100644 index 0000000..8fd3078 --- /dev/null +++ b/OxyPlot.Windows/Utilities/RenderContext.cs @@ -0,0 +1,906 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2014 OxyPlot contributors +// +// +// Implements for . +// +// -------------------------------------------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Threading.Tasks; + +using global::Windows.Foundation; +using global::Windows.Storage.Streams; +using global::Windows.UI; +using global::Windows.UI.Text; +using global::Windows.UI.Xaml; +using global::Windows.UI.Xaml.Controls; +using global::Windows.UI.Xaml.Media; +using global::Windows.UI.Xaml.Media.Imaging; +using global::Windows.UI.Xaml.Shapes; +using OxyPlot.Core.Drawing; +using Path = global::Windows.UI.Xaml.Shapes.Path; + +namespace OxyPlot.Windows +{ + /// + /// Implements for . + /// + public class RenderContext : IRenderContext + { + /// + /// The brush cache. + /// + private readonly Dictionary brushCache = new Dictionary(); + + /// + /// The canvas. + /// + private readonly Canvas canvas; + + /// + /// The images in use + /// + private readonly HashSet imagesInUse = new HashSet(); + + /// + /// The image cache + /// + private readonly Dictionary imageCache = new Dictionary(); + + /// + /// The current tool tip + /// + private string currentToolTip; + + /// + /// The clip rectangle. + /// + private Rect clipRect; + + /// + /// The clip flag. + /// + private bool clip; + + private readonly Stack clipStack; + + /// + /// Initializes a new instance of the class. + /// + /// The canvas. + public RenderContext(Canvas canvas) + { + this.canvas = canvas; + this.Width = canvas.ActualWidth; + this.Height = canvas.ActualHeight; + this.RendersToScreen = true; + this.clipStack = new Stack(); + } + + /// + /// Gets the height. + /// + /// The height. + public double Height { get; private set; } + + /// + /// Gets a value indicating whether to paint the background. + /// + /// true if the background should be painted; otherwise, false. + public bool PaintBackground + { + get + { + return false; + } + } + + /// + /// Gets the width. + /// + /// The width. + public double Width { get; private set; } + + /// + /// Gets or sets a value indicating whether the context renders to screen. + /// + /// true if the context renders to screen; otherwise, false. + public bool RendersToScreen { get; set; } + + + /// + /// Gets the number of clipped. + /// + public int ClipCount => this.clipStack.Count; + + /// + /// Draws an ellipse. + /// + /// The rectangle. + /// The fill color. + /// The stroke color. + /// The thickness. + /// The rendering mode. + public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode) + { + var el = new Ellipse + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + if (stroke.IsVisible()) + { + el.Stroke = new SolidColorBrush(stroke.ToColor()); + el.StrokeThickness = thickness; + } + + if (fill.IsVisible()) + { + el.Fill = new SolidColorBrush(fill.ToColor()); + } + + el.Width = rect.Width; + el.Height = rect.Height; + Canvas.SetLeft(el, rect.Left); + Canvas.SetTop(el, rect.Top); + this.Add(el, rect.Left, rect.Top); + } + + /// + /// Draws the collection of ellipses, where all have the same stroke and fill. + /// This performs better than calling DrawEllipse multiple times. + /// + /// The rectangles. + /// The fill color. + /// The stroke color. + /// The stroke thickness. + /// The rendering mode. + public void DrawEllipses(IList rectangles, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode) + { + var path = new Path + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + this.SetStroke(path, stroke, thickness); + if (fill.IsVisible()) + { + path.Fill = this.GetCachedBrush(fill); + } + + var gg = new GeometryGroup { FillRule = FillRule.Nonzero }; + foreach (var rect in rectangles) + { + gg.Children.Add( + new EllipseGeometry + { + Center = new Point(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)), + RadiusX = rect.Width / 2, + RadiusY = rect.Height / 2 + }); + } + + path.Data = gg; + this.Add(path); + } + + /// + /// Draws the polyline from the specified points. + /// + /// The points. + /// The stroke color. + /// The stroke thickness. + /// The rendering mode. + /// The dash array. + /// The line join type. + public void DrawLine(IList points, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode, + double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) + { + var e = new Polyline + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + this.SetStroke(e, stroke, thickness, lineJoin, dashArray, false); + PointCollection pc = new PointCollection(); + foreach (var p in points) + { + Point pnt = new Point(p.X, p.Y); + pc.Add(pnt); + } + + e.Points = pc; + + this.Add(e); + } + + /// + /// Draws the multiple line segments defined by points (0,1) (2,3) (4,5) etc. + /// This should have better performance than calling DrawLine for each segment. + /// + /// The points. + /// The stroke color. + /// The stroke thickness. + /// The rendering mode. + /// The dash array. + /// The line join type. + public void DrawLineSegments(IList points, OxyColor stroke, double thickness, + EdgeRenderingMode edgeRenderingMode, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) + { + var path = new Path + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + this.SetStroke(path, stroke, thickness, lineJoin, dashArray); + var pg = new PathGeometry(); + for (int i = 0; i + 1 < points.Count; i += 2) + { + // if (points[i].Y==points[i+1].Y) + // { + // var line = new Line(); + + // line.X1 = 0.5+(int)points[i].X; + // line.X2 = 0.5+(int)points[i+1].X; + // line.Y1 = 0.5+(int)points[i].Y; + // line.Y2 = 0.5+(int)points[i+1].Y; + // SetStroke(line, OxyColors.DarkRed, thickness, lineJoin, dashArray, aliased); + // Add(line); + // continue; + // } + Point pnt1 = new Point(points[i].X, points[i].Y); + Point pnt2 = new Point(points[i + 1].X, points[i + 1].Y); + var figure = new PathFigure { StartPoint = pnt1, IsClosed = false }; + figure.Segments.Add(new LineSegment { Point = pnt2 }); + pg.Figures.Add(figure); + } + + path.Data = pg; + this.Add(path); + } + + /// + /// Draws the polygon from the specified points. The polygon can have stroke and/or fill. + /// + /// The points. + /// The fill color. + /// The stroke color. + /// The stroke thickness. + /// The rendering mode. + /// The dash array. + /// The line join type. + public void DrawPolygon(IList points, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) + { + var po = new Polygon + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + this.SetStroke(po, stroke, thickness, lineJoin, dashArray); + + if (fill.IsVisible()) + { + po.Fill = this.GetCachedBrush(fill); + } + + PointCollection pc = new PointCollection(); + foreach (var p in points) + { + Point pnt = new Point(p.X, p.Y); + pc.Add(pnt); + } + + po.Points = pc; + + this.Add(po); + } + + /// + /// Draws a collection of polygons, where all polygons have the same stroke and fill. + /// This performs better than calling DrawPolygon multiple times. + /// + /// The polygons. + /// The fill color. + /// The stroke color. + /// The stroke thickness. + /// The rendering mode. + /// The dash array. + /// The line join type. + public void DrawPolygons(IList> polygons, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter) + + { + var path = new Path + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + this.SetStroke(path, stroke, thickness, lineJoin, dashArray); + if (fill.IsVisible()) + { + path.Fill = this.GetCachedBrush(fill); + } + + var pg = new PathGeometry { FillRule = FillRule.Nonzero }; + foreach (var polygon in polygons) + { + var figure = new PathFigure { IsClosed = true }; + bool first = true; + foreach (var p in polygon) + { + Point pnt = new Point(p.X, p.Y); + if (first) + { + figure.StartPoint = pnt; + first = false; + } + else + { + figure.Segments.Add(new LineSegment { Point = pnt }); + } + } + + pg.Figures.Add(figure); + } + + path.Data = pg; + this.Add(path); + } + + /// + /// Draws the rectangle. + /// + /// The rectangle. + /// The fill color. + /// The stroke color. + /// The stroke thickness. + /// Rendering mode. + public void DrawRectangle(OxyRect rectangle, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode) + { + var el = new Rectangle + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + if (stroke.IsVisible()) + { + Color col = Color.FromArgb(stroke.A, stroke.R, stroke.G, stroke.B); + el.Stroke = new SolidColorBrush(col); + el.StrokeThickness = thickness; + } + + if (fill.IsVisible()) + { + Color col = Color.FromArgb(fill.A, fill.R, fill.G, fill.B); + el.Fill = new SolidColorBrush(col); + } + + el.Width = rectangle.Width; + el.Height = rectangle.Height; + Canvas.SetLeft(el, rectangle.Left); + Canvas.SetTop(el, rectangle.Top); + this.Add(el, rectangle.Left, rectangle.Top); + } + + /// + /// Draws a collection of rectangles, where all have the same stroke and fill. + /// This performs better than calling DrawRectangle multiple times. + /// + /// The rectangles. + /// The fill color. + /// The stroke color. + /// The stroke thickness. + /// The rendering mode. + public void DrawRectangles(IList rectangles, OxyColor fill, OxyColor stroke, + double thickness, EdgeRenderingMode edgeRenderingMode) + { + var path = new Path + { + CompositeMode = ElementCompositeMode.SourceOver + }; + + this.SetStroke(path, stroke, thickness); + if (fill.IsVisible()) + { + path.Fill = this.GetCachedBrush(fill); + } + + var gg = new GeometryGroup { FillRule = FillRule.Nonzero }; + foreach (var rect in rectangles) + { + Rect r = rect.ToRect(false); + gg.Children.Add(new RectangleGeometry { Rect = new Rect(r.X, r.Y, r.Width, r.Height) }); + } + + path.Data = gg; + this.Add(path); + } + + /// + /// Draws the text. + /// + /// The position. + /// The text. + /// The fill color. + /// The font family. + /// Size of the font. + /// The font weight. + /// The rotation angle. + /// The horizontal alignment. + /// The vertical alignment. + /// The maximum size of the text. + public void DrawText( + ScreenPoint p, + string text, + OxyColor fill, + string fontFamily, + double fontSize, + double fontWeight, + double rotate, + OxyPlot.HorizontalAlignment halign, + OxyPlot.VerticalAlignment valign, + OxySize? maxSize) + { + var tb = new TextBlock { Text = text, Foreground = new SolidColorBrush(fill.ToColor()) }; + + // tb.SetValue(TextOptions.TextHintingModeProperty, TextHintingMode.Animated); + if (fontFamily != null) + { + tb.FontFamily = new FontFamily(fontFamily); + } + + if (fontSize > 0) + { + tb.FontSize = fontSize; + } + + tb.FontWeight = GetFontWeight(fontWeight); + + tb.Measure(new Size(1000, 1000)); + var size = new Size(tb.ActualWidth, tb.ActualHeight); + if (maxSize != null) + { + if (size.Width > maxSize.Value.Width) + { + size.Width = maxSize.Value.Width; + } + + if (size.Height > maxSize.Value.Height) + { + size.Height = maxSize.Value.Height; + } + + tb.Clip = new RectangleGeometry { Rect = new Rect(0, 0, size.Width, size.Height) }; + } + + double dx = 0; + if (halign == OxyPlot.HorizontalAlignment.Center) + { + dx = -size.Width / 2; + } + + if (halign == OxyPlot.HorizontalAlignment.Right) + { + dx = -size.Width; + } + + double dy = 0; + if (valign == OxyPlot.VerticalAlignment.Middle) + { + dy = -size.Height / 2; + } + + if (valign == OxyPlot.VerticalAlignment.Bottom) + { + dy = -size.Height; + } + + var transform = new TransformGroup(); + transform.Children.Add(new TranslateTransform { X = (int)dx, Y = (int)dy }); + if (!rotate.Equals(0)) + { + transform.Children.Add(new RotateTransform { Angle = rotate }); + } + + transform.Children.Add(new TranslateTransform { X = (int)p.X, Y = (int)p.Y }); + tb.RenderTransform = transform; + this.ApplyTooltip(tb); + + if (this.clip) + { + // add a clipping container that is not rotated + var c = new Canvas(); + c.Children.Add(tb); + this.Add(c); + } + else + { + this.Add(tb); + } + } + + /// + /// Measures the text. + /// + /// The text. + /// The font family. + /// Size of the font. + /// The font weight. + /// The text size. + public OxySize MeasureText(string text, string fontFamily, double fontSize, double fontWeight) + { + if (string.IsNullOrEmpty(text)) + { + return OxySize.Empty; + } + + var tb = new TextBlock { Text = text }; + + if (fontFamily != null) + { + tb.FontFamily = new FontFamily(fontFamily); + } + + if (fontSize > 0) + { + tb.FontSize = fontSize; + } + + tb.FontWeight = GetFontWeight(fontWeight); + + tb.Measure(new Size(1000, 1000)); + + return new OxySize(tb.ActualWidth, tb.ActualHeight); + } + + /// + /// Sets the tool tip for the following items. + /// + /// The text in the tooltip. + public void SetToolTip(string text) + { + this.currentToolTip = text; + } + + /// + /// Draws the specified portion of the specified at the specified location and with the specified size. + /// + /// The source. + /// The x-coordinate of the upper-left corner of the portion of the source image to draw. + /// The y-coordinate of the upper-left corner of the portion of the source image to draw. + /// Width of the portion of the source image to draw. + /// Height of the portion of the source image to draw. + /// The x-coordinate of the upper-left corner of drawn image. + /// The y-coordinate of the upper-left corner of drawn image. + /// The width of the drawn image. + /// The height of the drawn image. + /// The opacity. + /// interpolate if set to true. + public void DrawImage( + OxyImage source, + double srcX, + double srcY, + double srcWidth, + double srcHeight, + double destX, + double destY, + double destWidth, + double destHeight, + double opacity, + bool interpolate) + { + if (destWidth <= 0 || destHeight <= 0 || srcWidth <= 0 || srcHeight <= 0) + { + return; + } + + var image = new Image(); + var bmp = this.GetImageSource(source); + + if (srcX.Equals(0) && srcY.Equals(0) && srcWidth.Equals(bmp.PixelWidth) && srcHeight.Equals(bmp.PixelHeight)) + { + // do not crop + } + else + { + // TODO: cropped image not available in Silverlight?? + // bmp = new CroppedBitmap(bmp, new Int32Rect((int)srcX, (int)srcY, (int)srcWidth, (int)srcHeight)); + return; + } + + image.Opacity = opacity; + image.Width = destWidth; + image.Height = destHeight; + image.Stretch = Stretch.Fill; + + // TODO: not available in Silverlight?? + // RenderOptions.SetBitmapScalingMode(image, interpolate ? BitmapScalingMode.HighQuality : BitmapScalingMode.NearestNeighbor); + // Canvas.SetLeft(image, x); + // Canvas.SetTop(image, y); + image.RenderTransform = new TranslateTransform { X = destX, Y = destY }; + image.Source = bmp; + this.ApplyTooltip(image); + this.Add(image, destX, destY); + } + + /// + /// Sets the clipping rectangle. + /// + /// The clipping rectangle. + /// True if the clipping rectangle was set. + public bool SetClip(OxyRect clippingRect) + { + Rect rect = clippingRect.ToRect(false); + this.clipRect = new Rect(rect.X, rect.Y, rect.Width, rect.Height); + this.clip = true; + return true; + } + + /// + /// Resets the clipping rectangle. + /// + public void ResetClip() + { + this.clip = false; + } + + /// + /// Cleans up resources not in use. + /// + /// This method is called at the end of each rendering. + public void CleanUp() + { + // Find the images in the cache that has not been used since last call to this method + var imagesToRelease = this.imageCache.Keys.Where(i => !this.imagesInUse.Contains(i)).ToList(); + + // Remove the images from the cache + foreach (var i in imagesToRelease) + { + this.imageCache.Remove(i); + } + + this.imagesInUse.Clear(); + } + + /// + /// Creates the dash array collection. + /// + /// The dash array. + /// A DoubleCollection. + private static DoubleCollection CreateDashArrayCollection(IEnumerable dashArray) + { + var dac = new DoubleCollection(); + foreach (double v in dashArray) + { + dac.Add(v); + } + + return dac; + } + + /// + /// Gets the font weight. + /// + /// The font weight. + /// A + private static FontWeight GetFontWeight(double fontWeight) + { + FontWeight fw; + + if (fontWeight > OxyPlot.FontWeights.Normal) + { + fw = new FontWeight() { Weight = (ushort)FontWeights.Bold }; + } + else + { + fw = new FontWeight() { Weight = (ushort)FontWeights.Normal }; + } + return fw; + } + + /// + /// Adds the specified element to the canvas. + /// + /// The element. + /// The clip offset X. + /// The clip offset Y. + private void Add(UIElement element, double clipOffsetX = 0, double clipOffsetY = 0) + { + if (this.clip) + { + this.ApplyClip(element, clipOffsetX, clipOffsetY); + } + + this.canvas.Children.Add(element); + } + + /// + /// Applies the tooltip to the specified element. + /// + /// The element. + private void ApplyTooltip(DependencyObject element) + { + if (!string.IsNullOrEmpty(this.currentToolTip)) + { + ToolTipService.SetToolTip(element, this.currentToolTip); + } + } + + /// + /// Gets the cached brush. + /// + /// The stroke. + /// The brush. + private Brush GetCachedBrush(OxyColor stroke) + { + Brush brush; + if (!this.brushCache.TryGetValue(stroke, out brush)) + { + brush = new SolidColorBrush(stroke.ToColor()); + this.brushCache.Add(stroke, brush); + } + + return brush; + } + + /// + /// Sets the stroke of the specified shape. + /// + /// The shape. + /// The stroke. + /// The thickness. + /// The line join. + /// The dash array. + /// aliased if set to true. + private void SetStroke( + Shape shape, + OxyColor stroke, + double thickness, + LineJoin lineJoin = LineJoin.Miter, + IEnumerable dashArray = null, + bool aliased = false) + { + if (stroke.IsVisible() && thickness > 0) + { + shape.Stroke = this.GetCachedBrush(stroke); + + switch (lineJoin) + { + case LineJoin.Round: + shape.StrokeLineJoin = PenLineJoin.Round; + break; + case LineJoin.Bevel: + shape.StrokeLineJoin = PenLineJoin.Bevel; + break; + + // The default StrokeLineJoin is Miter + } + + shape.StrokeThickness = thickness; + + if (dashArray != null) + { + shape.StrokeDashArray = CreateDashArrayCollection(dashArray); + } + + if (aliased) + { + // shape.UseLayoutRounding = aliased; + } + } + } + + /// + /// Applies the clip rectangle. + /// + /// The image. + /// The x offset of the element. + /// The y offset of the element. + private void ApplyClip(UIElement image, double x, double y) + { + image.Clip = new RectangleGeometry { Rect = new Rect(this.clipRect.X - x, this.clipRect.Y - y, this.clipRect.Width, this.clipRect.Height) }; + } + + /// + /// Gets the bitmap source. + /// + /// The image. + /// The bitmap source. + private BitmapSource GetImageSource(OxyImage image) + { + if (image == null) + { + return null; + } + + if (!this.imagesInUse.Contains(image)) + { + this.imagesInUse.Add(image); + } + + BitmapSource src; + if (this.imageCache.TryGetValue(image, out src)) + { + return src; + } + + var bitmapImage = new BitmapImage(); + var imageStream = ConvertToRandomAccessStream(image.GetData()).GetAwaiter().GetResult(); + bitmapImage.SetSource(imageStream); + this.imageCache.Add(image, bitmapImage); + return bitmapImage; + } + + /// + /// Converts the specified byte array to a . + /// + /// + /// + private static async Task ConvertToRandomAccessStream(byte[] buffer) + { + //https://stackoverflow.com/questions/16397509/how-to-convert-byte-array-to-inmemoryrandomaccessstream-or-irandomaccessstream-i + var randomAccessStream = new InMemoryRandomAccessStream(); + await randomAccessStream.WriteAsync(buffer.AsBuffer()); + randomAccessStream.Seek(0); + return randomAccessStream; + } + /// + /// Push a Clip data. + /// + /// + public void PushClip(OxyRect clippingRectangle) + { + if (this.clipStack.Count > 0) + { + OxyRect currentClippingRectangle = this.clipStack.Peek(); + OxyRect newClippingRectangle = clippingRectangle.Intersect(currentClippingRectangle); + if (!currentClippingRectangle.Equals(newClippingRectangle)) + { + this.ResetClip(); + this.SetClip(newClippingRectangle); + } + + this.clipStack.Push(newClippingRectangle); + } + else + { + this.SetClip(clippingRectangle); + this.clipStack.Push(clippingRectangle); + } + } + + /// + /// Pop a Clip data. + /// + public void PopClip() + { + if (this.clipStack.Count == 0) + { + throw new InvalidOperationException($"Unbalanced call to {nameof(PopClip)}"); + } + + OxyRect currentClippingRectangle = this.clipStack.Pop(); + if (this.clipStack.Count > 0) + { + OxyRect newClippingRectangle = this.clipStack.Peek(); + if (!newClippingRectangle.Equals(currentClippingRectangle)) + { + this.ResetClip(); + this.SetClip(newClippingRectangle); + } + } + else + { + this.ResetClip(); + } + } + } +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5fe33b5 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +OxyPlot is a cross-platform plotting library for .NET + +This library contains user contributions that are published as the NuGet package [OxyPlot.Contrib](https://www.nuget.org/packages/OxyPlot.Contrib). + +[![Build status](https://ci.appveyor.com/api/projects/status/x9esl7iuo1mle8gi?svg=true)](https://ci.appveyor.com/project/objorke/oxyplot-contrib) From 1979079d361032d3b71531772dec54c39ab98d0e Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Thu, 14 Oct 2021 17:04:25 +0900 Subject: [PATCH 03/11] Update README.md Fix the statements in README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 5fe33b5..8da8baf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ OxyPlot is a cross-platform plotting library for .NET -This library contains user contributions that are published as the NuGet package [OxyPlot.Contrib](https://www.nuget.org/packages/OxyPlot.Contrib). +This library contains some adjustment for Universal Windows Platform that are published as the NuGet package [OxyPlot.Windows](https://www.nuget.org/packages/OxyPlot.Windows). -[![Build status](https://ci.appveyor.com/api/projects/status/x9esl7iuo1mle8gi?svg=true)](https://ci.appveyor.com/project/objorke/oxyplot-contrib) From 75196ea0fb34cdad0248010a32ce9e921468aa93 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Thu, 14 Oct 2021 17:09:14 +0900 Subject: [PATCH 04/11] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8da8baf..845f464 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -OxyPlot is a cross-platform plotting library for .NET - -This library contains some adjustment for Universal Windows Platform that are published as the NuGet package [OxyPlot.Windows](https://www.nuget.org/packages/OxyPlot.Windows). +### OxyPlot is a cross-platform plotting library for .NET +This library contains some adjustment for Universal Windows Platform that are to be published as the NuGet package OxyPlot.Windows. +The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. From 84ab910063f5d65a54e5747cc8b2115f04b67684 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Thu, 14 Oct 2021 17:18:57 +0900 Subject: [PATCH 05/11] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 845f464..5a44dd1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ### OxyPlot is a cross-platform plotting library for .NET -This library contains some adjustment for Universal Windows Platform that are to be published as the NuGet package OxyPlot.Windows. -The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. +* This library contains some adjustment for Universal Windows Platform that are to be published as the NuGet package OxyPlot.Windows. +* This library was created simply to use the OxyPlot.Core version 2.1.0. I worked for just adjusting the existing oxyplot-uwp repository in oxyplot, so using all the functionalities in oxyplot is unknown. +* The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. I don't know how this package were built as the original repository oxyplot/oxyplot-uwp itself couldn't make its package. From d03b7b7a9630d864460b06bd7312c6b7f79136d7 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Fri, 15 Oct 2021 16:42:57 +0900 Subject: [PATCH 06/11] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a44dd1..b89222a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -### OxyPlot is a cross-platform plotting library for .NET - +## OxyPlot is a cross-platform plotting library for .NET +### Background * This library contains some adjustment for Universal Windows Platform that are to be published as the NuGet package OxyPlot.Windows. * This library was created simply to use the OxyPlot.Core version 2.1.0. I worked for just adjusting the existing oxyplot-uwp repository in oxyplot, so using all the functionalities in oxyplot is unknown. * The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. I don't know how this package were built as the original repository oxyplot/oxyplot-uwp itself couldn't make its package. From d1fe1d367d2d94eb5a01ef668b7481e4c822ad8d Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Fri, 15 Oct 2021 16:44:18 +0900 Subject: [PATCH 07/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b89222a..d9365f4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ## OxyPlot is a cross-platform plotting library for .NET ### Background * This library contains some adjustment for Universal Windows Platform that are to be published as the NuGet package OxyPlot.Windows. -* This library was created simply to use the OxyPlot.Core version 2.1.0. I worked for just adjusting the existing oxyplot-uwp repository in oxyplot, so using all the functionalities in oxyplot is unknown. +* This library was created simply to use the OxyPlot.Core version 2.1.0. I worked for just adjusting the existing oxyplot-uwp repository in oxyplot, so I'm not sure right now whether you can use all the functionarities of the oxyplot with this library. * The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. I don't know how this package were built as the original repository oxyplot/oxyplot-uwp itself couldn't make its package. From 64978a24de0b30a0ce4e76de565eda8489f8e133 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Fri, 15 Oct 2021 17:53:52 +0900 Subject: [PATCH 08/11] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index d9365f4..b4c929b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,16 @@ ## OxyPlot is a cross-platform plotting library for .NET +### Function +You can draw a graph like below in a .NET UWP application. +![Plot](https://oxyplot.github.io/public/images/normal-distributions.png) + ### Background * This library contains some adjustment for Universal Windows Platform that are to be published as the NuGet package OxyPlot.Windows. * This library was created simply to use the OxyPlot.Core version 2.1.0. I worked for just adjusting the existing oxyplot-uwp repository in oxyplot, so I'm not sure right now whether you can use all the functionarities of the oxyplot with this library. * The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. I don't know how this package were built as the original repository oxyplot/oxyplot-uwp itself couldn't make its package. + +#### Getting started + +1. Use the NuGet package manager to add a reference to OxyPlot (see details below if you want to use pre-release packages) +2. Add a `PlotView` to your user interface +3. Create a `PlotModel` in your code +4. Bind the `PlotModel` to the `Model` property of your `PlotView` From fee18d4d57cfc8ef5ea41d09c9b66440e860e0da Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Fri, 15 Oct 2021 17:54:31 +0900 Subject: [PATCH 09/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b4c929b..bd88f51 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ You can draw a graph like below in a .NET UWP application. * This library was created simply to use the OxyPlot.Core version 2.1.0. I worked for just adjusting the existing oxyplot-uwp repository in oxyplot, so I'm not sure right now whether you can use all the functionarities of the oxyplot with this library. * The current NuGet OxyPlot.Windows package is 2.0.0-unstable1035, which will be out of date in the near future because the OxyPlot.Core version 2.1.0 is totally different from version 2.0.0. I don't know how this package were built as the original repository oxyplot/oxyplot-uwp itself couldn't make its package. -#### Getting started +### Getting started 1. Use the NuGet package manager to add a reference to OxyPlot (see details below if you want to use pre-release packages) 2. Add a `PlotView` to your user interface From b2572a44436354c5a86505c8518db51cbeba81f6 Mon Sep 17 00:00:00 2001 From: Yoshiteru Kageyama Date: Tue, 19 Oct 2021 15:37:03 +0900 Subject: [PATCH 10/11] Make SimpleDemo work on Visual Studio 2019. Signed-off-by: Yoshiteru Kageyama --- OxyPlot.Windows.sln | 25 ++++ OxyPlot.Windows.snk | Bin 596 -> 0 bytes .../Examples/Windows/SimpleDemo/MainPage.xaml | 4 +- .../Windows/SimpleDemo/MainViewModel.cs | 29 ++++- .../Windows/SimpleDemo/Package.appxmanifest | 4 +- .../Windows/SimpleDemo/SimpleDemo.csproj | 107 +++++++++++++++--- .../SimpleDemo/SimpleDemo_TemporaryKey.pfx | Bin 0 -> 2544 bytes OxyPlot.Windows/OxyPlot.Windows.2.1.0.nupkg | Bin 61506 -> 0 bytes OxyPlot.Windows/OxyPlot.Windows.csproj | 17 +++ OxyPlot.Windows/OxyPlot.Windows.keypair.snk | Bin 0 -> 596 bytes OxyPlot.Windows/OxyPlot.Windows.public.snk | Bin 0 -> 160 bytes OxyPlot.Windows/OxyPlot.Windows.snk | Bin 596 -> 0 bytes OxyPlot.Windows/Properties/AssemblyInfo.cs | 8 +- 13 files changed, 167 insertions(+), 27 deletions(-) delete mode 100644 OxyPlot.Windows.snk create mode 100644 OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo_TemporaryKey.pfx delete mode 100644 OxyPlot.Windows/OxyPlot.Windows.2.1.0.nupkg create mode 100644 OxyPlot.Windows/OxyPlot.Windows.keypair.snk create mode 100644 OxyPlot.Windows/OxyPlot.Windows.public.snk delete mode 100644 OxyPlot.Windows/OxyPlot.Windows.snk diff --git a/OxyPlot.Windows.sln b/OxyPlot.Windows.sln index 1887cbb..881859f 100644 --- a/OxyPlot.Windows.sln +++ b/OxyPlot.Windows.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.29403.142 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OxyPlot.Windows", "OxyPlot.Windows\OxyPlot.Windows.csproj", "{4F5B1D20-EA97-4DBB-94E1-8D86B4152847}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleDemo", "OxyPlot.Windows\Examples\Windows\SimpleDemo\SimpleDemo.csproj", "{FAC17BDF-4003-4359-A366-2E2F380E1BB5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,6 +41,29 @@ Global {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x64.Build.0 = Release|x64 {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x86.ActiveCfg = Release|x86 {4F5B1D20-EA97-4DBB-94E1-8D86B4152847}.Release|x86.Build.0 = Release|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|Any CPU.ActiveCfg = Debug|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|Any CPU.Build.0 = Debug|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM.ActiveCfg = Debug|ARM + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM.Build.0 = Debug|ARM + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM.Deploy.0 = Debug|ARM + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|ARM64.ActiveCfg = Debug|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x64.ActiveCfg = Debug|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x64.Build.0 = Debug|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x64.Deploy.0 = Debug|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x86.ActiveCfg = Debug|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x86.Build.0 = Debug|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Debug|x86.Deploy.0 = Debug|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|Any CPU.ActiveCfg = Release|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM.ActiveCfg = Release|ARM + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM.Build.0 = Release|ARM + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM.Deploy.0 = Release|ARM + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|ARM64.ActiveCfg = Release|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x64.ActiveCfg = Release|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x64.Build.0 = Release|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x64.Deploy.0 = Release|x64 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x86.ActiveCfg = Release|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x86.Build.0 = Release|x86 + {FAC17BDF-4003-4359-A366-2E2F380E1BB5}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/OxyPlot.Windows.snk b/OxyPlot.Windows.snk deleted file mode 100644 index 1a8edeaefefc4816520e65bc748c0bcfc0b31ef9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50098yqo{VJjPLdS?(t^>Kk6%A*c~IJ!YlOM zCP*nJ;2wHRj#E`r0`{te4Q-dA+_wVe7wHdk)+bqpsRA<Z^9(SfmT zL31BB)B~I`45#aOO7At6Ur@qMq6R?NhG&q)3@c8nIqG6GYjru-wBtaqh|y6B(nb_X zx5q`%4sq0nrHRW~SvdZj&N>0`%qDHfoJFbL2PYbaLpP?2BNx`?TUcaH+% z4T3#JI5l(-tD<12=8KR7EGgoC7$eV)Pr@8-b; i-tu~RmYzJnjh73z8=Ot_uCjm%;}-+kZs0#iEC&>}Xcxl( diff --git a/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml index b95fdb1..a72fe6d 100644 --- a/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml +++ b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainPage.xaml @@ -11,7 +11,7 @@ - - + + diff --git a/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainViewModel.cs b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainViewModel.cs index 2bb27e4..34adcd8 100644 --- a/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainViewModel.cs +++ b/OxyPlot.Windows/Examples/Windows/SimpleDemo/MainViewModel.cs @@ -3,15 +3,17 @@ namespace SimpleDemo using OxyPlot; using OxyPlot.Axes; using OxyPlot.Series; + using System.Collections.Generic; + using System.ComponentModel; - public class MainViewModel + public class MainViewModel : INotifyPropertyChanged { public MainViewModel() { var model = new PlotModel { Title = "Hello Universal Windows" }; model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom }); model.Axes.Add(new LinearAxis { Position = AxisPosition.Left }); - var lineSeries = new LineSeries { Title = "LineSeries", MarkerType = MarkerType.Circle }; + LineSeries lineSeries = new LineSeries { Title = "LineSeries", MarkerType = MarkerType.Circle }; lineSeries.Points.Add(new DataPoint(0, 0)); lineSeries.Points.Add(new DataPoint(10, 18)); lineSeries.Points.Add(new DataPoint(20, 12)); @@ -19,9 +21,30 @@ public MainViewModel() lineSeries.Points.Add(new DataPoint(40, 15)); model.Series.Add(lineSeries); + model.InvalidatePlot(true); this.Model = model; } - public PlotModel Model { get; private set; } + private PlotModel _model; + + public event PropertyChangedEventHandler PropertyChanged; + + public virtual void OnPropertyChanged(string propName) + { + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); + } + + public PlotModel Model + { + get => _model; + private set + { + if (!object.ReferenceEquals(_model, value)) + { + _model = value; + OnPropertyChanged("Model"); + } + } + } } } \ No newline at end of file diff --git a/OxyPlot.Windows/Examples/Windows/SimpleDemo/Package.appxmanifest b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Package.appxmanifest index 05761f4..5a6c0e6 100644 --- a/OxyPlot.Windows/Examples/Windows/SimpleDemo/Package.appxmanifest +++ b/OxyPlot.Windows/Examples/Windows/SimpleDemo/Package.appxmanifest @@ -8,14 +8,14 @@ SimpleDemo - objo + Yoshiteru Kageyama Assets\StoreLogo.png diff --git a/OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo.csproj b/OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo.csproj index 46106ea..004a1a2 100644 --- a/OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo.csproj +++ b/OxyPlot.Windows/Examples/Windows/SimpleDemo/SimpleDemo.csproj @@ -11,13 +11,16 @@ SimpleDemo en-US UAP - 10.0.18362.0 + 10.0.19041.0 10.0.18362.0 14 512 {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} true - SimpleDemo_TemporaryKey.pfx + + + 86BEAB295D9391A135A1168090375BE01A5C11D4 + True true @@ -75,6 +78,7 @@ false prompt true + false bin\x64\Release\ @@ -105,6 +109,7 @@ Designer + @@ -127,24 +132,92 @@ Designer - - - 5.2.3 - - - - - {5aa87152-20d5-48f7-ad0f-6e6baa61fc25} - OxyPlot.Windows - - - {7a0b35c0-dd17-4964-8e9a-44d6cecdc692} - OxyPlot - - + + + 4.7.0.9 + + + 1.0.31 + + + 5.0.9 + + + 5.0.0 + + + 3.11.0 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + 6.2.12 + + + 7.1.0 + + + 7.1.0 + + + + 2.1.0 + + + 6.2.12 + + + 2.0.4 + + + 5.0.0 + + + 4.5.4 + + + 4.3.0 + + + 5.0.0 + + + 4.3.0 + + + 4.3.1 + + + 5.0.0 + + + 4.3.0 + + + 4.7.0 + + + 4.7.0 + + + 4.3.0 + + + 4.5.0 + + + 1.0.1 + + 14.0 + + true + + + SimpleDemo_TemporaryKey.pfx +