22
.gitattributes
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
167
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
Contribute to OxyPlot
|
||||
=====================
|
||||
|
||||
OxyPlot is driven by the community and contributors like you. We are excited that you're interested to help us move forward and improve OxyPlot.
|
||||
|
||||
The flow when contributing to OxyPlot is as follows:
|
||||
|
||||
1. Add issue (bug or new feature)
|
||||
2. If the issue needs to be clarified, wait for some feedback
|
||||
3. Commit your changes
|
||||
4. Update the change log and contributors files
|
||||
4. Create a pull request
|
||||
|
||||
Note that your contributions must be your own work and licensed under the same terms as OxyPlot.
|
||||
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
First, search the issue tracker to see if the bug is already there.
|
||||
|
||||
It is very helpful to get the generated code (use `CTRL+ALT+C` in the plot control) and report (`CTRL+ALT+R`) of the bug plot. You can also take a screen shot and paste it into the description.
|
||||
|
||||
Please use markdown to format your code blocks with [syntax highlighting](https://help.github.com/articles/github-flavored-markdown/#syntax-highlighting) to make it easier for everyone to read.
|
||||
|
||||
You could also use services like https://snipt.org or https://gist.github.com to share code snippets.
|
||||
|
||||
A bug report should include:
|
||||
|
||||
- the platform you are building for (Windows Forms, WPF, Xamarin Forms etc.)
|
||||
- the framework version (netcore3, net47 etc.)
|
||||
- the version of OxyPlot you are using
|
||||
- description of the issue
|
||||
- sample code to reproduce the issue
|
||||
- what you expect and what is the actual behaviour
|
||||
|
||||
|
||||
## Suggesting new features
|
||||
|
||||
First, search the issue tracker to see if the feature is already there.
|
||||
|
||||
A feature request should include:
|
||||
|
||||
- description of the feature
|
||||
- a drawing/image, if possible
|
||||
|
||||
It could be a good idea to wait for some feedback before starting to work on a new feature.
|
||||
Not all features are general enough to fit into this library.
|
||||
We don't want you to waste time on something that might not be merged in the end.
|
||||
|
||||
|
||||
## Creating your own fork
|
||||
|
||||
1. Log in to GitHub and open the [oxyplot](https://github.com/oxyplot/oxyplot/) origin repository. Click the "Fork" button to create your own fork of the repository.
|
||||
2. Create a clone on your local system: `git clone https://github.com/yourusername/oxyplot.git`
|
||||
|
||||
|
||||
## Branch
|
||||
|
||||
The repository contains two branches:
|
||||
|
||||
- `master` - the release branch (stable channel)
|
||||
- `develop` - the main branch with the latest development changes (pre-release channel)
|
||||
|
||||
You should base your work on the `develop` branch.
|
||||
|
||||
See [A successful git branching model](https://nvie.com/posts/a-successful-git-branching-model/) for more information about the branching model in use.
|
||||
|
||||
Create a branch for the bugfix/feature you want to work on: `git branch bugfix-some-error`
|
||||
|
||||
Checkout the branch: `git checkout bugfix-some-error`
|
||||
|
||||
|
||||
## Commit your changes
|
||||
|
||||
Before you start committing, please define your [full name](https://help.github.com/articles/setting-your-username-in-git/) and [e-mail](https://help.github.com/articles/setting-your-email-in-git/) address in git.
|
||||
|
||||
Please follow the style of the other messages in the commit history. Explain the intentions for the change and include the issue number. Include the issue number in the commit message, e.g. "#9945".
|
||||
|
||||
Please follow the coding-style:
|
||||
|
||||
- write StyleCop compliant code
|
||||
- include XML comments for all methods, properties and fields
|
||||
- do not use #regions
|
||||
- use linq method syntax (not query syntax)
|
||||
- keep it simple
|
||||
|
||||
To commit your changes, use the git command: `git commit -m <msg>`
|
||||
|
||||
When you are ready to make a pull request, please
|
||||
|
||||
- [Rebase](https://git-scm.com/docs/git-rebase) to the latest commit of the origin
|
||||
- [Squash](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) each logical change to a single commit
|
||||
|
||||
More info about rebasing
|
||||
|
||||
- https://git-scm.com/book/en/v2/Git-Branching-Rebasing
|
||||
- https://blog.sourcetreeapp.com/2012/08/21/merge-or-rebase/
|
||||
- https://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html
|
||||
- https://ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one/
|
||||
- https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
|
||||
- https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase-i
|
||||
|
||||
Finally, push your commits: `git push`
|
||||
|
||||
|
||||
## Requirements for a pull request
|
||||
|
||||
- Include the issue number
|
||||
- Include examples or unit tests for the change / new feature
|
||||
- Update the CHANGELOG.md file
|
||||
- Update the CONTRIBUTORS and AUTHORS files if you are not already listed there
|
||||
|
||||
|
||||
## Creating a pull request
|
||||
|
||||
- Open the GitHub page for your fork and create a "Pull Request" (PR)
|
||||
|
||||
|
||||
## Merging
|
||||
|
||||
When the PR is submitted, a build will automatically be trigged.
|
||||
A team member will then review the PR, and merge the branch if everything looks OK.
|
||||
|
||||
If there are some issues with the PR, you should
|
||||
- update your code and commit changes
|
||||
- clean up the git history with rebase or squash
|
||||
- force push: `git push -f`
|
||||
|
||||
The PR will be updated automatically when you push your changes.
|
||||
|
||||
|
||||
## Contributing to the documentation
|
||||
|
||||
The documentation is located in the [docs](https://github.com/oxyplot/docs) repository.
|
||||
See the README.md file for information about how to build the documentation.
|
||||
Please contribute by creating pull requests!
|
||||
|
||||
|
||||
## Contributing to the website
|
||||
|
||||
The source of the [oxyplot.github.io](https://oxyplot.github.io/) web site can be found in the [oxyplot.github.io](https://github.com/oxyplot/oxyplot.github.io) repository.
|
||||
Please contribute by creating pull requests!
|
||||
|
||||
The web-site is built by [GitHub](https://github.com/) with [Jekyll](https://jekyllrb.com/).
|
||||
|
||||
|
||||
## Common rules
|
||||
|
||||
To prevent the issue (backlog) list to grow indefinitely, an issue will be closed when you are not responding to requests by a project developer.
|
||||
We need your help, so we will not close an issue by desire. But when you are not answering to a request by for a month we will close the issue.
|
||||
If this happens in accident, feel free to re-open the issue...
|
||||
|
||||
The issue reporter can close the issue because:
|
||||
|
||||
- he/she verified the fix/change
|
||||
- found out that it is not an OxyPlot issue but some problem in his/her code
|
||||
|
||||
In case the reporter does not respond to a request:
|
||||
|
||||
- a project developer is allowed to close the issue (after one month)
|
||||
|
||||
Someone can take over the issue from the reporter, when:
|
||||
|
||||
- he/she can reproduce the issue
|
||||
- has some sample code
|
||||
- has more time/information to assist in the resolution
|
||||
- responds to requests by a project developer
|
||||
38
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<!--
|
||||
Please see https://github.com/oxyplot/oxyplot/wiki/Contributing before creating issues.
|
||||
For issues related to Xamarin, please use https://github.com/oxyplot/oxyplot-xamarin/issues
|
||||
For issues related to other platforms, please add to the correct repository.
|
||||
|
||||
PLEASE DO NOT USE THE ISSUES TO ADD QUESTIONS ABOUT HOW TO USE THE LIBRARY.
|
||||
YOU SHOULD FORMULATE THE ISSUE AS A "BUG REPORT" OR "NEW FEATURE REQUEST",
|
||||
PLEASE USE ONE OF THE SECTIONS BELOW:
|
||||
-->
|
||||
|
||||
<!-- IF THE ISSUE IS A BUG, INCLUDE THIS PART: -->
|
||||
|
||||
### Steps to reproduce
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Platform:
|
||||
.NET version:
|
||||
|
||||
### Expected behaviour
|
||||
|
||||
Tell us what should happen
|
||||
|
||||
### Actual behaviour
|
||||
|
||||
Tell us what happens instead
|
||||
Can you also include a screen shot?
|
||||
|
||||
|
||||
<!-- IF THE ISSUE IS A NEW FEATURE REQUEST, INCLUDE THIS PART: -->
|
||||
|
||||
### Feature description
|
||||
|
||||
Write a description of the feature. How should it work? How should it look?
|
||||
Include some graphics if this could help!
|
||||
|
||||
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
Fixes # .
|
||||
|
||||
### Checklist
|
||||
|
||||
- [ ] I have included examples or tests
|
||||
- [ ] I have updated the change log
|
||||
- [ ] I am listed in the CONTRIBUTORS file
|
||||
- [ ] I have cleaned up the commit history (use rebase and squash)
|
||||
|
||||
### Changes proposed in this pull request:
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
@oxyplot/admins
|
||||
65
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'develop', 'master' ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ 'develop' ]
|
||||
schedule:
|
||||
- cron: '4 12 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'csharp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: |
|
||||
3.1.x
|
||||
6.0.x
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
- name: Build
|
||||
run: dotnet build Source/OxyPlot.CI.sln --configuration Release
|
||||
|
||||
- name: MSBuild
|
||||
run: msbuild Source\OxyPlot.CI.sln -p:Configuration=Release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
34
.github/workflows/dotnetcore.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: Build on Windows
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: |
|
||||
6.0.x
|
||||
7.0.x
|
||||
|
||||
- name: Build
|
||||
run: dotnet build Source/OxyPlot.CI.sln --configuration Release
|
||||
|
||||
- name: Run unit tests
|
||||
run: dotnet test Source/OxyPlot.CI.sln --configuration Release
|
||||
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
|
||||
- name: MSBuild
|
||||
run: msbuild Source\OxyPlot.CI.sln -p:Configuration=Release
|
||||
247
.gitignore
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
|
||||
# Created by https://www.gitignore.io/api/visualstudio
|
||||
|
||||
### VisualStudio ###
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# OxyPlot specific
|
||||
Output/
|
||||
launchSettings.json
|
||||
|
||||
# Rider
|
||||
.idea/
|
||||
15
AUTHORS
Normal file
@@ -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 <email address>
|
||||
# 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 <oystein.bjorke@gmail.com>
|
||||
DNV GL AS
|
||||
LECO® Corporation
|
||||
TrainerRoad, LLC <lorentz@trainerroad.com>
|
||||
511
CHANGELOG.md
Normal file
@@ -0,0 +1,511 @@
|
||||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Example to Show/Hide Legend (#1470)
|
||||
- Example of BarSeries stacked and with labels (#1979)
|
||||
- Example of issue with AreaSeries tracker (#1982)
|
||||
- Example for CategoryAxis with custom MajorStep and uncentered ticks (#1971)
|
||||
- BarSeries.LabelAngle property (#1870)
|
||||
- Support HiDPI for WinForms examples (#1597)
|
||||
- Border properties on PathAnnotation to match functionality in TextAnnotation (#1900)
|
||||
- Expanded `IntervalBarSeries` and `TornadoBarSeries` to allow for varied label positions and angles (#2027)
|
||||
- VectorSeries (#107)
|
||||
|
||||
### Changed
|
||||
- Make consistent BaseValue and BaseLine across BarSeries, LinearBarSeries, and HistogramSeries
|
||||
- Factor out common project properties to `Directory.Build.props` (#1937)
|
||||
- Remove support for .NET Standard 1.X, as .NET Framework 4.6.2 supports .NET Standard 2.0 (#1937)
|
||||
- Remove support for .NET Core 3.1, as it is end-of-life soon (#1937)
|
||||
- Move example projects to .NET Framework 4.6.2 and .NET 6.0 (#1937)
|
||||
- Run tests on both .NET Framework 4.6.2 and .NET 6.0 (#1937)
|
||||
- Add support for .NET 7.0 (#1937)
|
||||
- Update SkiaSharp to Version 2.88.3
|
||||
|
||||
### Removed
|
||||
- Support for .NET Framework 4.0 and 4.5 (#1839)
|
||||
- Unused LabelColor property from TornadoBarSeries, IntervalBarSeries, and RectangleBarSeries (#2030)
|
||||
|
||||
### Fixed
|
||||
- Placement of BarSeries labels when stacked (#1979)
|
||||
- SystemInvalidException in LineSeries when only Double.Nan values are added (#1991)
|
||||
- Issue with tracking AreaSeries with monotonic data points (#1982)
|
||||
- Incorrect coloring of TwoColorLineSeries
|
||||
- HitTest when IsLegendVisible is false (#1975)
|
||||
- Font weight not being applied in ImageSharp (#2006)
|
||||
- SkiaSharp - Fix use of obsolete functions (#1937)
|
||||
- Dashed lines are solid when exporting via SkiaSharp.SvgExporter (#1674)
|
||||
|
||||
## [2.1.2] - 2022-12-03
|
||||
|
||||
### Added
|
||||
- Add LineThickness property to TrackerControl (#1831)
|
||||
- Add properties for `MinimumSegmentLength` to series and annotations (#1853)
|
||||
- Add fractal examples for PolygonAnnotation and PolylineAnnotations (#1853)
|
||||
- Add `AxisPreference` to `PlotManipulator`
|
||||
- Add MinimumMajorIntervalCount and MaximumMajorIntervalCount Axis Properties (#24)
|
||||
- Add VisualStudioToolsManifest.xml to add components to the Visual Studio Designer toolbox (#1446)
|
||||
|
||||
### Changed
|
||||
- Change default `MinimumSegmentLength` to `2` and remove limits for series and annotations with simple geometry (#1853)
|
||||
- Improve performance of `StairStepSeries`, particularly when zoomed in and X is monotonic or when consecutive points have equal Y components
|
||||
- `StairStepSeries` renders a horizontal line when a point with a valid X component and invalid Y component follows a valid point
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
- WPF - OxyPlot doesn't render inside a Popup (#1796)
|
||||
- Odd behavior of zooming of Logarithmic axis in Cartesian plot (#1825)
|
||||
- SkiaSharp.WPF - OxyPlot doesn't render inside an ElementHost (#1800)
|
||||
- NullReference in SkiaSharp WPF renderer if UIElement has no PresentationSource (#1798)
|
||||
- WPF DPI Regression (#1799)
|
||||
- Code generation for escape sequences in strings (#1824)
|
||||
- Axes not always honoring AbsoluteMinimum/AbsoluteMaximum and/or MinimumRange/MaximumRange properties (#1812)
|
||||
- WindowsForms tracker no longer clipping outside PlotView boundaries (#1863)
|
||||
- CategoryAxis.ItemsSource without BarSeries (#1847)
|
||||
- Histogram now rendering properly when using logarithmic Y axis (#740)
|
||||
- Fix ExampleLibrary build errors in certain code pages (#1890)
|
||||
- LineBarSeries now rendering properly when using logarithmic scale (#740)
|
||||
- Fix for double.Epsilon zero check that fails on some architectures (#1924)
|
||||
|
||||
## [2.1.0] - 2021-10-02
|
||||
|
||||
### Added
|
||||
- Made Legend Items clickable to toggle series visibility (#644)
|
||||
- Added properties LegendKey and SeriesGroupName to Series, allowing grouping series between multiple legends and/or within same legend (#644)
|
||||
- OxyPlot.ImageSharp (#1188)
|
||||
- WPF ExampleBrowser can display transposed versions of examples (#1402)
|
||||
- Support for transposable Annotations (#1417)
|
||||
- Support for NET40 (#1452)
|
||||
- Support for high DPI for WPF (#149)
|
||||
- EdgeRenderingMode property to PlotElement, allowing customization of the way edges are treated by the renderer (#1428, #1358, #1077, #843, #145)
|
||||
- Color palettes Viridis, Plasma, Magma, Inferno and Cividis (#1505)
|
||||
- Renderer based on SkiaSharp, including exporters for PNG, JPEG, PDF and SVG (#1509)
|
||||
- Example for Issue #1524: HitTracker IndexOutOfRangeException with HeatMapSeries
|
||||
- Text shaping support to SkiaRenderContext (#1520)
|
||||
- PlotView based on SkiaRenderContext (OxyPlot.SkiaSharp.Wpf) (#1515)
|
||||
- DrawImage support to OxyPlot.ImageSharp (#1530)
|
||||
- Dpi support to OxyPlot.ImageSharp (#1530)
|
||||
- Dash support to OxyPlot.ImageSharp
|
||||
- Clipping support to OxyPlot.ImageSharp
|
||||
- JpegExporter for OxyPlot.ImageSharp
|
||||
- Multi-line aligned text rendering example
|
||||
- WindowsForms ExampleBrowser can display transposed versions of examples (#1535)
|
||||
- Example for Issue #1545 showing the use of different line endings
|
||||
- Support for unix line endings in OxyPlot.ImageSharp, OxyPlot.Svg, and OxyPlot.Pdf (#1545)
|
||||
- Multi-Line Text support to SkiaRenderContext (#1538)
|
||||
- Added title clipping to PlotModel (#1510)
|
||||
- Added LabelStep and LabelSpacing to contour series (#1511)
|
||||
- Example for Issue #1481 showing text rendering with emoji
|
||||
- Native Clipping for OxyPlot.SvgRenderContext (#1564)
|
||||
- Examples of full plot area polar plots with non-zero minimums (#1586)
|
||||
- Read-Only collection interfaces for .NET 4.0 (#1600)
|
||||
- Add PlotModel.AssignColorsToInvisibleSeries property to control whether invisible series are included or skipped when assigning automatic colors (#1599)
|
||||
- Overlapping bar series (#1265)
|
||||
- `AxisPosition.All` for axes which need a margin on all sides of the plot area (#1574)
|
||||
- IRenderContext.ClipCount property (#1593)
|
||||
- Additional parameters for HistogramSeries LabelFormatString
|
||||
- Absolute screen-space axis margins (#1569)
|
||||
- netstandard2.0 TargetFramework (#1668)
|
||||
- Add a PlotView.TextMeasurementMethod property to allow using the much faster GlyphTypeface based measurement at runtime (#1673)
|
||||
- OxyPlot.Wpf.XamlRenderContext - this doesn't use StreamGeometry and can be used for rendering to XAML (#1673)
|
||||
- SkiaRenderContext.MiterLimit property (#1690)
|
||||
- Example for Issue #1685 showing spurious lines in the ContourSeries
|
||||
- Example for Issue #1716 showing poor tick spacing on DateTimeAxis with interval types of Weeks or Years
|
||||
- Example for label placement on BarSeries with non-zero BaseValue (#1726)
|
||||
- ExtrapolationLineSeries as described in #1740 to allow to display pre-defined intervals of a line series with a different style than the rest.
|
||||
- Added DataRange, unit tests and examples as support for ExtrapolationLineSeries.
|
||||
- Add control over how far from the series the tracker fires (#1736)
|
||||
- Add option to check distance for result between data points (#1736)
|
||||
- Legend.AllowUseFullExtent property to control whether legends should be able to use the full extent of the plot (#1743)
|
||||
- Legend.ShowInvisibleSeries property to control whether invisible series should be shown on the legend (#1730)
|
||||
- OxyPlot.SkiaSharp.Wpf PlotView support for simple render transforms (#1785)
|
||||
|
||||
### Changed
|
||||
- Legends model (#644)
|
||||
- Default behaviour is now plot without Legend (#644)
|
||||
- Moved WPF Plot component to Oxyplot.Contrib.Wpf (#1399)
|
||||
- ErrorColumnSeries changed to ErrorBarSeries, also works in transposed mode (#1402)
|
||||
- Moved reporting functionality to separate projects (#1403)
|
||||
- Moved reporting functionality to oxyplot-reporting repository (#1403)
|
||||
- Change IPlotModel.Render to take an OxyRect (#1425)
|
||||
- Merge UIElement and SelectableElement into Element (#1426)
|
||||
- Upgrade to .NET Core 3.1 (#1488)
|
||||
- DrawRectangle(...), DrawLine(...), DrawEllipse(...), DrawPolygon(...) and related overloads in IRenderContext and related extensions in RenderingExtensions now require an EdgeRenderingMode
|
||||
- Default color palette for LinearColorAxis from Jet to Viridis (#1505)
|
||||
- Extract most of the functionality from OxyPlot.Wpf into OxyPlot.Wpf.Shared to allow code sharing with other WPF PlotViews (#1515)
|
||||
- WPF ExampleBrowser can switch between Canvas and SkiaSharp renderers (#1515)
|
||||
- OxyPlot.ImageSharp now targets .NET Standard 1.3 (#1530)
|
||||
- SkiaRenderContext does not apply pixel snapping when rendering to vector graphic (#1539)
|
||||
- Mark OxyPlot.PdfExporter and OxyPlot.Pdf.PdfExporter as obsolete (#1527)
|
||||
- Replace Axis.DesiredSize by Axis.DesiredMargin, change signature of Axis.Measure(...) (#453)
|
||||
- Axis renderers now render all ticks they are provided (#1580)
|
||||
- Auto margins don't reserve space for axis labels if axis range is fixed (#1577)
|
||||
- CategoryAxis should not contain rendering information about BarSeries (#741)
|
||||
- CategorizedSeries changed to BarSeriesBase<T> (#741)
|
||||
- System.Drawing.Common references updated to 4.7.0 (#1608)
|
||||
- Invisible series are assigned automatic colors by default, configurable with PlotModel.AssignColorsToInvisibleSeries property that defaults to true (#1599)
|
||||
- StemSeries, AreaSeries, TwoColorAreaSeries, and StairStepSeries use `ActualMarkerColor` (#1630)
|
||||
- Axes with `AxisPosition.None` make no contribution to margins (#1574)
|
||||
- `AngleAxis` has position `AxisPosition.All` by default (#1574)
|
||||
- Clipping API changed from SetClip(...) and ResetClip() to PushClip(...) and PopClip() (#1593)
|
||||
- Remove TileMapAnnotation examples from automated testing (#1667)
|
||||
- Optimize clipping calls (#1661)
|
||||
- Mark CandleStickAndVolumeSeries as obsolete (#1661)
|
||||
- Implement StreamGeometry-based implementations of DrawEllipses, DrawLine, DrawLineSegments and DrawRectangle(s) which improves the rendering speed on WPF (#1673)
|
||||
- Change algorithm of ContourSeries.JoinContourSegments(). This should improve performance in most cases, but will cause labels to appear in different spots than before (#1685)
|
||||
- Updated Series.cd with ExtrapolationLineSeries and removed classes that do not exist anymore
|
||||
|
||||
### Removed
|
||||
- Remove PlotModel.Legends (#644)
|
||||
- ColumnSeries - functionality is replaced by transposed BarSeries (#1402)
|
||||
- Copy to text report Ctrl+Alt+R (#1403)
|
||||
- Remove exporter Background properties (#1409)
|
||||
- Remove OxyThickness Width and Height properties (#1429)
|
||||
- RenderingExtensions.DrawRectangleAsPolygon(...) extension methods. IRenderContext.DrawRectangle(...) with an appropriate EdgeRenderingMode can be used instead.
|
||||
- SkiaSharp.PdfExporter.Dpi property (#1591)
|
||||
- Axis.UpdateFromSeries(...) and Series.UpdateValidData() (#741)
|
||||
- Support for IRenderContext implementations without native clipping (#1593)
|
||||
- CohenSutherlandClipping and SutherlandHodgmanClipping (#1593)
|
||||
- DrawClippedXxx(...) extensions in RenderingExtensions (#1661)
|
||||
- PathAnnotation.ClipText property - text is now always clipped (#1661)
|
||||
- CanvasRenderContext.UseStreamGeometry property - this functionality is replaced by the new XamlRenderContext (#1673)
|
||||
|
||||
### Fixed
|
||||
- Legend font size is not affected by DefaultFontSize (#1396)
|
||||
- ErrorBarSeries, IntervalBarSeries and TornadoBarSeries work correctly in transposed mode (#1402)
|
||||
- Exception when rendering polygon with no points (#1410)
|
||||
- Custom tracker strings can cause exception in histogram chart (#1455)
|
||||
- OxyPlot.WindowsForms package description (#1457)
|
||||
- NullReference in VolumeSeries if no data in Items list (#1491)
|
||||
- Possible out-of-bounds exception in HeatMapSeries HitTest (#1524)
|
||||
- WPF CanvasRenderContext draws ellipses too small by half stroke thickness (#1537)
|
||||
- Text measurement and rendering in OxyPlot.ImageSharp
|
||||
- ExampleLibrary reporting annotation-only PlotModels as transposable (#1544)
|
||||
- Auto plot margin not taking width of labels into account (#453)
|
||||
- WPF PlotView still focusable when Focusable is false (#1440)
|
||||
- Disposing a SkiaRenderContext can mess up fonts from another SkiaRenderContext instance (#1573)
|
||||
- Display of ampersands in OxyPlot.WindowsForms Tracker (#1585)
|
||||
- Full Plotarea Polar plot rendering with non-zero minimum values (#1586)
|
||||
- Auto margins are set incorrectly if Axis.TitleFontSize is set to non-default value (related to #1577)
|
||||
- Incomplete rendering of AreaSeries in some situations (#1512)
|
||||
- ColumnSeries / BarSeries not working with more than one value-axis (#729)
|
||||
- OxyPlot.SkiaSharp.SvgExporter plot background color (#1619)
|
||||
- MinimumPadding incorrect when MaximumPadding is non-zero (#1625)
|
||||
- Don't clip zerocrossing axis lines within plot bounds (#1441)
|
||||
- Incorrect margins when using Color Axes with AxisPosition.None (#1574)
|
||||
- OpenStreetMap example (#1642)
|
||||
- Incorrect clipping in TwoColorAreaSeries (#1678)
|
||||
- ScreenMin and ScreenMax on Horizontal and Vertical Axes depends on plot bounds (#1652)
|
||||
- Windows Forms clipping last line of measured text (#1659)
|
||||
- Inconsistent Zooming behaviour (#1648)
|
||||
- ContourSeries produce fake connections (#1685)
|
||||
- Zero-crossing axis bounds (#1708)
|
||||
- Incorrect label placement on BarSeries with non-zero BaseValue (#1726)
|
||||
- LineAnnotation Text Placement on Reversed Axes (#1741)
|
||||
- Image opacity in WinForms and Core Drawing (#1766)
|
||||
- Fix specified Visual is not an ancestor of this Visual issue in WPF rendering (#1787)
|
||||
|
||||
## [2.0.0] - 2019-10-19
|
||||
### Added
|
||||
- WindowsForms and Wpf support .NET Core 3.0 (#1331)
|
||||
- PngExporter based on System.Common.Drawing (.NET Core) (#1263)
|
||||
- New polar plot axes filling the full plot area (#1056)
|
||||
- Support for three colors in histogram series (#1305)
|
||||
- Command to copy plot to the clipboard in Windows Forms (Ctrl-C) (#1297)
|
||||
- New `InterpolationAlgorithm` property in LineSeries and PolylineAnnotation (#494)
|
||||
- Catmull-Rom spline interpolation algorithms (#494)
|
||||
- FontSize, FontWeight and FontFamily on Wpf.TextAnnotation (#1023)
|
||||
- RectangleSeries (#1060)
|
||||
- InvalidNumberColor on Wpf.LinearColorAxis (#1087)
|
||||
- ContinuousHistogramSeries (#1145)
|
||||
- Multiline text support for PortableDocumentFont (#1146)
|
||||
- Workaround for text vertical alignment in SVG Export to accomodate viewers which don't support dominant-baseline (#459, #1198)
|
||||
- Support for transposed (X and Y axis switched) plots with XYAxisSeries (#1334)
|
||||
- Color property on HistogramItem (#1347)
|
||||
- Count property on HistogramSeries (#1347)
|
||||
- Bug in HistogramHelpers.Collect when using out-of-order bin breaks (#1476)
|
||||
|
||||
### Changed
|
||||
- OxyPlot.Core changed to target netstandard 1.0 and net45 (#946, #1147)
|
||||
- OxyPlot.ExampleLibrary changed to target netstandard 1.0 and net45 (#946, #1147)
|
||||
- OxyPlot.Wpf, OxyPlot.WindowsForms, OxyPlot.Pdf changed to target net45 (#946)
|
||||
- Place label below negative ColumnSeries (#1119)
|
||||
- Use PackageReference instead of packages.config
|
||||
- Migrated NUnit v2 to v3 and added test adapter
|
||||
- TrackerControl reuses existing ContentControl when a new hit tracker result uses the same template as the currently shown tracker (#1281)
|
||||
- Overhaul HistogramHelpers (#1345)
|
||||
- OxyPlot.Windows (UWP) moved to oxyplot-uwp repository (#1378)
|
||||
- Make the PngExporters consistent (#1390)
|
||||
- Silverlight project moved to separate repository (#1049)
|
||||
- WP8 project moved to separate repository (#1050)
|
||||
- Windows8 project moved to separate repository (#1103)
|
||||
- Avalonia project moved to separate repository
|
||||
- Xamarin projects moved to separate repository
|
||||
- Xwt project moved to separate repository
|
||||
- GTK# projects moved to separate repository
|
||||
- SharpDX project moved to separate repository
|
||||
|
||||
### Deprecated
|
||||
- OxyPlot.WP8 package. Use OxyPlot.Windows (UWP) instead (#996)
|
||||
|
||||
### Removed
|
||||
- LabelFontSize property from HistogramSeries (#1309)
|
||||
- Smooth property from LineSeries and PolylineAnnotation (#494)
|
||||
- Support for net40 (#960)
|
||||
|
||||
### Fixed
|
||||
- Manipulation when using touch is not working in Windows (#1011)
|
||||
- Ensure a suitable folder is used when creating a temporary file for PNG export in Oxyplot.GtkSharp (#1034)
|
||||
- RangeColorAxis is not rendered correctly if the axis is reversed (#1035)
|
||||
- OxyMouseEvents not caught due to InvalidatePlot() in WPF (#382)
|
||||
- When Color Property of LineSeries is set Markers are not shown (#937)
|
||||
- Change from linear to logarithmic axis does not work (#1067)
|
||||
- OxyPalette.Interpolate() throws exception when paletteSize = 1 (#1068)
|
||||
- Infinite loop in LineAnnotation (#1029)
|
||||
- OverflowException when zoomed in on logarithmic axis (#1090)
|
||||
- ScatterSeries with DateTimeAxis/TimeSpanAxis (#1132)
|
||||
- Exporting TextAnnotation with TextColor having 255 alpha to SVG produces opaque text (#1160)
|
||||
- Chart is not updated when top and bottom are not visible (#1219)
|
||||
- Candle overlap each candle (#623)
|
||||
- CandleStick is overlapped when item.Open == item.Close in the CandleStickAndVolumeSeries (#1245)
|
||||
- Out of memory exception and performance issue with Catmull-Rom Spline (#1237)
|
||||
- Cache and Dispose Brush and Pen objects used by GraphicsRenderContext (#1230)
|
||||
- Add checks for non-positive StrokeThickess and LineStyle.None in various places (#1312)
|
||||
- Fixed references to RectangleItem in HistogramSeries
|
||||
- Fix AxisChangedEventArgs.DeltaMaximum in Axes.Reset (#1306)
|
||||
- Fixed Tracker for RectangleBarSeries (#1171)
|
||||
- RectangleSeries doesn't render Labels (related to #1334)
|
||||
- LineSeries line legend placement with reversed X axis (related to #1334)
|
||||
- HistogramSeries label placement inconsistent (related to #1334)
|
||||
- TwoColorLineSeries and ThreeColorLineSeries don't work with reversed Y axis (related to #1334)
|
||||
- Issue with SVG always containing the xml headers (#1212)
|
||||
- In WPF, make sure the axes are initalized when the Model is set before the PlotView has been loaded (#1303)
|
||||
- MinimumSegmentLength not working for LineSeries (#1044)
|
||||
- rendering issues with MagnitudeAxisFullPlotArea (#1364)
|
||||
- OxyPlot.Core.Drawing PngExporter background when exporting to stream (#1382)
|
||||
- Windows Forms clipping last line of rendered text (#1124, #1385)
|
||||
- Dispose background brush in OxyPlot.Core.Drawing PngExporter (#1392)
|
||||
|
||||
## [1.0.0] - 2016-09-11
|
||||
### Added
|
||||
- Added OxyPlot.SharpDX.Wpf NuGet package
|
||||
- Added DirectX 9.1-10.1 feature level support for SharpDX renderer
|
||||
- Added SharpDX based renderer and WPF control with SharpDX render (#124)
|
||||
- Added MinimumMajorStep and MinimumMinorStep to Axes.Axis (#816)
|
||||
- Added support for vertical X axis to HeatMapSeries (#535)
|
||||
- Added fall-back rectangle rendering to HeatMapSeries (#801)
|
||||
- Added logarithmic HeatMapSeries support (#802) and example
|
||||
- Axis.MaximumRange to limit the zoom (#401)
|
||||
- Added OxyPlot.Mobile NuGet package to combine the mobile platforms into a single package (#362)
|
||||
- Support for XWT (#295)
|
||||
- TwoColorAreaSeries (#299)
|
||||
- Delta values in AxisChangedEventArgs (#276)
|
||||
- Git source server (added GitLink build step) (#267,#266)
|
||||
- iOS PlotView ZoomThreshold/AllowPinchPastZero for use with KeepAspectRatioWhenPinching=false (#359)
|
||||
- CandleStickAndVolumeSeries and VolumeSeries (#377)
|
||||
- Axis.DesiredSize property (#383)
|
||||
- WPF wrapper for BoxPlotSeries (#434)
|
||||
- Capability to display mean value to BoxPlotSeries (#440)
|
||||
- LinearBarSeries for WPF (#506)
|
||||
- TitleToolTip in PlotModel (#508)
|
||||
- TextColor property on WPF Axis (#452)
|
||||
- ThreeColorLineSeries (#378)
|
||||
- CI of the Xamarin.Android, Xamarin.iOS and Xamarin.Forms packages (#274)
|
||||
- PlotModel.LegendLineSpacing (#622)
|
||||
- Legend rendering for LinearBarSeries (#663)
|
||||
- LegendMaxHeight property in PlotModel and Wpf.Plot (#668)
|
||||
- Support for a Xamarin Forms UWP project with sample app (#697)
|
||||
- ListBuilder for building lists by reflection (#705)
|
||||
- F# example (#699)
|
||||
- Support for discontinuities in AreaSeries (#215)
|
||||
- Support for Windows Universal 10.0 apps (#615)
|
||||
- Support Unicode in OxyPlot.Pdf (#789)
|
||||
- TouchTrackerManipulator (#787)
|
||||
- Extracted visible window search code from CandleStickSeries and made a generic version in XYSeries. Used it to optimize AreaSeries performance. (#834)
|
||||
- Optimized rendering performance of RectangleBarSeries (#834).
|
||||
- PdfExporter implementing IExporter (#845)
|
||||
- Color minor and major ticks differently (#417)
|
||||
- Support for PieSeries in OxyPlot.Wpf (#878)
|
||||
- Filter in example browser (#118)
|
||||
- Support for tooltips on WPF annotations
|
||||
- Support for tracker in OxyPlot.GtkSharp
|
||||
- Improve tracker style (Windows Forms) (#106)
|
||||
- Font rendering in OxyPlot.GtkSharp improved by using Pango (#972)
|
||||
- Improved LineSeries performance (#834)
|
||||
- Fixed bug causing axes titles to not display in OxyPlot.GtkSharp (#989)
|
||||
|
||||
### Changed
|
||||
- Fixed closing file stream for PdfReportWriter when PdfReportWriter is closed or disposed of. (#892)
|
||||
- Renamed OxyPlot.WindowsUniversal to OxyPlot.Windows (#242)
|
||||
- Changed OxyPlot.Xamarin.Forms to require OxyPlot.Mobile dependency instead of each separate NuGet. (#362)
|
||||
- Renamed OxyPlot.XamarinIOS to OxyPlot.MonoTouch (#327)
|
||||
- Renamed OxyPlot.XamarinAndroid to OxyPlot.Xamarin.Android (#327)
|
||||
- Renamed OxyPlot.XamarinForms to OxyPlot.Xamarin.Forms (#327)
|
||||
- Renamed OxyPlot.XamarinForms.iOS to OxyPlot.Xamarin.Forms.Platform.iOS (#327)
|
||||
- Renamed OxyPlot.XamarinFormsIOS to OxyPlot.Xamarin.Forms.Platform.iOS.Classic (#327)
|
||||
- Renamed OxyPlot.XamarinFormsAndroid to OxyPlot.Xamarin.Forms.Platform.Android (#327)
|
||||
- Renamed OxyPlot.XamarinFormsWinPhone to OxyPlot.Xamarin.Forms.Platform.WP8 (#327)
|
||||
- Changed OxyPlot.Xamarin.Android target to Android level 10 (#223)
|
||||
- Separated WPF Plot and PlotView (#252, #239)
|
||||
- Current CandleStickSeries renamed to OldCandleStickSeries, replaced by a faster implementation (#369)
|
||||
- Invalidate plot when ItemsSource contents change (INotifyCollectionChanged) on WPF only (#406)
|
||||
- Xamarin.Forms references updated to 1.5.0.6447 (#293, #439)
|
||||
- Change OxyPlot.Xamarin.Forms.Platform.Android target to Android level 15 (#439)
|
||||
- Changed OxyPlot.Xamarin.Forms to portable Profile259 (#439)
|
||||
- PlotController should not intercept input per default (#446)
|
||||
- Changed DefaultTrackerFormatString for BoxPlotSeries (to include Mean) (#440)
|
||||
- Changed Constructor of BoxPlotItem (to include Mean) (#440)
|
||||
- Changed Axis, Annotation and Series Render() method (removed model parameter)
|
||||
- Changed PCL project to profile 259, SL5 is separate now (#115)
|
||||
- Extracted CreateReport() and CreateTextReport() from PlotModel (#517)
|
||||
- Renamed GetLastUpdateException to GetLastPlotException and added the ability to see render exceptions(#543)
|
||||
- Move TileMapAnnotation class to example library (#567)
|
||||
- Change to semantic versioning (#595)
|
||||
- Change GTKSharp3 project to x86 (#599)
|
||||
- Change OxyPlot.Xamarin.Android to API Level 15 (#614)
|
||||
- Add Xamarin.Forms renderer initialization to PlotViewRenderer (#632)
|
||||
- Marked OxyPlot.Xamarin.Forms.Platform.*.Forms.Init() obsolete (#632)
|
||||
- Throw exception if Xamarin.Forms renderer is not 'initialized' (#492)
|
||||
- Make numeric values of DateTimeAxis compatible with ToOADate (#660)
|
||||
- Make struct types immutable (#692)
|
||||
- Implement IEquatable<T> for struct types (#692)
|
||||
- BoxPlotItem changed to reference type (#692)
|
||||
- Move Xamarin projects to new repository (#777)
|
||||
- Remove CandleStickSeries.Append (#826)
|
||||
- Change MinorInterval calculation, add unit test (#133)
|
||||
- Rewrite LogarithmicAxis tick calculation (#820)
|
||||
- Change Axis methods to protected virtual (#837)
|
||||
- Move CalculateMinorInterval and CreateTickValues to AxisUtilities (#837)
|
||||
- Change default number format to "g6" in Axis base class (#841)
|
||||
- Push packages to myget.org (#847)
|
||||
- Change the default format string to `null` for TimeSpanAxis and DateTimeAxis (#951)
|
||||
|
||||
### Removed
|
||||
- StyleCop tasks (#556)
|
||||
- OxyPlot.Metro project (superseded by OxyPlot.WindowsUniversal) (#241)
|
||||
- PlotModel.ToSvg method. Use the SvgExporter instead. (#347)
|
||||
- Constructors with parameters, use default constructors instead. (#347)
|
||||
- Axis.ShowMinorTicks property, use MinorTickSize = 0 instead (#347)
|
||||
- ManipulatorBase.GetCursorType method (#447)
|
||||
- Model.GetElements() method
|
||||
- Remove SL4 support (#115)
|
||||
- Remove NET35 support (#115)
|
||||
- PlotElement.Format method, use StringHelper.Format instead
|
||||
- EnumerableExtensions.Reverse removed (#677)
|
||||
- ListFiller (#705)
|
||||
|
||||
### Fixed
|
||||
- Added check to LineAnnotation.GetScreenPoints to check if ActualMaximumX==ActualMinimumX for non-curved lines. (#1029)
|
||||
- Incorrect placment of axis title of axes with AxisDistance (#1065)
|
||||
- SharpDX control not being rendered when loaded
|
||||
- SharpDX out of viewport scrolling.
|
||||
- Multiple mouse clicks not being reported in OxyPlot.GtkSharp (#854)
|
||||
- StemSeries Tracking to allow tracking on tiny stems (#809)
|
||||
- Fixed PDFRenderContext text alignment issues for rotated text (#723)
|
||||
- HeatMapSeries.GetValue returns NaN instead of calculating a wrong value in proximity to NaN (#256)
|
||||
- Tracker position is wrong when PlotView is offset from origin (#455)
|
||||
- CategoryAxis should use StringFormat (#415)
|
||||
- Fixed the dependency of OxyPlot.Xamarin.Forms NuGet (#370)
|
||||
- Add default ctor for Xamarin.Forms iOS renderer (#348)
|
||||
- Windows Phone cursor exception (#345)
|
||||
- Bar/ColumSeries tracker format string bug (#333)
|
||||
- Fix exception for default tracker format strings (#265)
|
||||
- Fix center-aligned legends (#79)
|
||||
- Fix Markdown links to tag comparison URL with footnote-style links
|
||||
- WPF dispatcher issue (#311, #309)
|
||||
- Custom colors for scatters (#307)
|
||||
- Rotated axis labels (#303,#301)
|
||||
- Floating point error on axis labels (#289, #227)
|
||||
- Performance of CandleStickSeries (#290)
|
||||
- Tracker text for StairStepSeries (#263)
|
||||
- XamarinForms/iOS view not updating when model is changed (#262)
|
||||
- Improved WPF rendering performance (#260, #259)
|
||||
- Null reference with MVVM binding (#255)
|
||||
- WPF PngExporter background (#234)
|
||||
- XamlExporter background (#233)
|
||||
- .NET 3.5 build (#229)
|
||||
- Support WinPhone 8.1 in core NuGet package (#161)
|
||||
- Draw legend line with custom pattern (#356)
|
||||
- iOS pan/zoom stability (#336)
|
||||
- Xamarin.Forms iOS PlotViewRenderer crash (#458)
|
||||
- Inaccurate tracker when using LogarithmicAxis (#443)
|
||||
- Fix reset of transforms in WinForms render context (#489)
|
||||
- Fix StringFormat for TimeSpanAxis not recognizing f, ff, fff, etc (#330)
|
||||
- Fix LineSeries SMOOTH=True will crash WinForms on right click (#499)
|
||||
- Fix PlotView leak on iOS (#503)
|
||||
- This PlotModel is already in use by some other PlotView control (#497)
|
||||
- LegendTextColor not synchronized between wpf.Plot and InternalModel (#548)
|
||||
- Legend in CandleStickSeries does not scale correctly (#554)
|
||||
- Fix CodeGenerator exception for types without parameterless ctor (#573)
|
||||
- Migrate automatic package restore (#557)
|
||||
- Fix rendering of rotated 'math' text (#569, #448)
|
||||
- WPF export demo (#568)
|
||||
- Fixing a double comparison issue causing infinite loop (#587)
|
||||
- Fix null reference exception when ActualPoints was null rendering a StairStepSeries (#582)
|
||||
- Background color in the Xamarin.Forms views (#546)
|
||||
- IsVisible change in Xamarin.Forms.Platform.iOS (#546)
|
||||
- Rendering math text with syntax error gets stuck in an endless loop (#624)
|
||||
- Fix issue with MinimumRange not taking Minimum and Maximum values into account (#550)
|
||||
- Do not set default Controller in PlotView ctor (#436)
|
||||
- Corrected owner type of Wpf.PathAnnotation dependency properties (#645)
|
||||
- Fixed partial plot rendering on Xamarin.Android (#649)
|
||||
- Default controller should not be shared in WPF PlotViews (#682)
|
||||
- PositionAtZeroCrossing adds zero crossing line at wrong position (#635)
|
||||
- Implement AreaSeries.ConstantY2 (#662)
|
||||
- Null reference exception in ScatterSeries{T} actual points (#636)
|
||||
- Code generation for HighLowItem (#634)
|
||||
- Axis.MinimumRange did not work correctly (#711)
|
||||
- FillColor in ErrorColumnSeries (#736)
|
||||
- XAxisKey and YAxisKey added to Wpf.Annotations (#743)
|
||||
- Fix HeatMapSeries cannot plot on Universal Windows (#745)
|
||||
- Set Resolution in WinForms PngExporter (#754)
|
||||
- Axis should never go into infinite loop (#758)
|
||||
- Exception in BarSeriesBase (#790)
|
||||
- Vertical Axes Title Font Bug (#474)
|
||||
- Support string[] as ItemsSource in CategoryAxis (#825)
|
||||
- Horizontal RangeColorAxis (#767)
|
||||
- LogarithmicAxis sometimes places major ticks outside of the axis range (#850)
|
||||
- LineSeries with smoothing raises exception (#72)
|
||||
- Exception when legend is outside and plot area is small (#880)
|
||||
- Axis alignment with MinimumRange (#794)
|
||||
- Fixed strange number formatting when using LogarithmicAxis with very large or very small Series (#589)
|
||||
- Fixed LogarithmicAxis to no longer freeze when the axis is reversed (#925)
|
||||
- Prevent endless loop in LogarithmicAxis (#957)
|
||||
- Fixed WPF series data not refreshed when not visible (included WPF LiveDemo)
|
||||
- Fixed bug in selection of plot to display in OxyPlot.GtkSharp ExampleBrowser (#979)
|
||||
- Fixed non-interpolation of HeatMapSeries in OxyPlot.GtkSharp (#980)
|
||||
- Fixed axis min/max calc and axis assignment for CandleStick + VolumeSeries (#389)
|
||||
- Fixed drawing of plot backgrounds in OxyPlot.GtkSharp (#990)
|
||||
|
||||
## [0.2014.1.546] - 2014-10-22
|
||||
### Added
|
||||
- Support data binding paths ("Point.X") (#210)
|
||||
- Support for Xamarin.Forms (#204)
|
||||
- Support for Windows Universal apps (#190)
|
||||
- Improve TrackerFormatString consistency (#214)
|
||||
- Support LineColor.BrokenLineColor
|
||||
- LabelFormatString for ScatterSeries (#12)
|
||||
|
||||
### Changed
|
||||
- Changed tracker format strings arguments (#214)
|
||||
- Rename OxyPenLineJoin to LineJoin
|
||||
- Rename LineStyle.Undefined to LineStyle.Automatic
|
||||
|
||||
### Fixed
|
||||
- Improved text rendering for Android and iOS (#209)
|
||||
- Custom shape outline for PointAnnotation (#174)
|
||||
- Synchronize Wpf.Axis.MinimumRange (#205)
|
||||
- TrackerHitResult bug (#198)
|
||||
- Position of axis when PositionAtZeroCrossing = true (#189)
|
||||
- Expose ScatterSeries.ActualPoints (#201)
|
||||
- Add overridable Axis.FormatValueOverride (#181)
|
||||
- PngExporter text formatting (#170)
|
||||
|
||||
[Unreleased]: https://github.com/oxyplot/oxyplot/compare/v2.1.0...HEAD
|
||||
[2.1.0]: https://github.com/oxyplot/oxyplot/compare/v2.0.0...v2.1.0
|
||||
[2.0.0]: https://github.com/oxyplot/oxyplot/compare/v1.0.0...v2.0.0
|
||||
[1.0.0]: https://github.com/oxyplot/oxyplot/compare/v0.2014.1.546...v1.0.0
|
||||
[0.2014.1.546]: https://github.com/oxyplot/oxyplot/compare/v0.0.1...v0.2014.1.546
|
||||
46
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
156
CONTRIBUTORS
Normal file
@@ -0,0 +1,156 @@
|
||||
# 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 <email address>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Adrien Mercier
|
||||
Alexei Shcherbakov
|
||||
Anders Musikka <anders@andersmusikka.se>
|
||||
Auriou
|
||||
Bartłomiej Szypelow <bszypelow@users.noreply.github.com>
|
||||
benjaminrupp
|
||||
Benoit Blanchon <>
|
||||
BobLd
|
||||
br
|
||||
brantheman
|
||||
Brannon King
|
||||
Bryan Freeman
|
||||
Brian Lim <brian.lim.ca@gmail.com>
|
||||
Caleb Clarke <thealmightybob@users.noreply.github.com>
|
||||
Carl Reinke
|
||||
Carlos Anderson <carlosjanderson@gmail.com>
|
||||
Carlos Teixeira <karlmtc@gmail.com>
|
||||
Chase Long <chaselfromal@gmail.com>
|
||||
Choden Konigsmark <choden.konigsmark@gmail.com>
|
||||
classicboss302
|
||||
csabar <rumancsabi@gmail.com>
|
||||
Curt Mullin <curt.mullin@gmail.com>
|
||||
Cyril Martin <cyril.martin.cm@gmail.com>
|
||||
Dan Aizenstros
|
||||
danpaul88 <danpaul88@users.noreply.github.com>
|
||||
darrelbrown
|
||||
David Funk <funk.david1985@gmail.com>
|
||||
David Laundav <davelaundav@gmail.com>
|
||||
David Wong <dvkwong0@gmail.com>
|
||||
DJDAS
|
||||
DNV GL AS
|
||||
Doeharrrck <doeharrrck@gmx.de>
|
||||
Don Syme <donsyme@fastmail.fm>
|
||||
DotNetDoctor <dotnetdoctor@outlook.com>
|
||||
efontana2
|
||||
elliatab
|
||||
Elia Herzog
|
||||
Elmar Strittmatter
|
||||
episage <tilosag@gmail.com>
|
||||
eric
|
||||
Fabian Nitsche <ifab@freenet.de>
|
||||
Federico Coppola <fede@silentman.it>
|
||||
Francois Botha <igitur@gmail.com>
|
||||
Frank Tore Sæther <frank.sather@gmail.com>
|
||||
Garrett
|
||||
GaryDev <112358055+garydev10@users.noreply.github.com>
|
||||
Geert van Horrik <geert@catenalogic.com>
|
||||
Gimly
|
||||
Herman Eldering <herman@eldering.net>
|
||||
Iain Nicol <git@iainnicol.com>
|
||||
Ilja Nosik <ilja.nosik@outlook.com>
|
||||
Ilya Skriblovsky <IlyaSkriblovsky@gmail.com>
|
||||
Iurii Gazin <archeg@gmail.com>
|
||||
IzStriker <IzStriker@users.noreply.github.com>
|
||||
Jānis Kiršteins <janis@janiskirsteins.org>
|
||||
jaykul
|
||||
Jens Krumsieck <j.krumsieck@outlook.de>
|
||||
Jeremy Koritzinsky
|
||||
Jeremie Magnette
|
||||
jezza323
|
||||
Johan
|
||||
Johan20D
|
||||
Jonathan Arweck
|
||||
Jonathan Shore <jonathan.shore@gmail.com>
|
||||
julien.bataille
|
||||
Just Slon <just.slon@gmail.com>
|
||||
Justin Morgan <jmorgan@herbert-abs.com>
|
||||
Kaplas80 <kaplas80@gmail.com>
|
||||
kc1212 <kc04bc@gmx.com>
|
||||
kenny_evoleap
|
||||
Kenny Nygaard
|
||||
Kevin Crowell <crowell@proteinmetrics.com>
|
||||
Kyle Pulvermacher
|
||||
LECO® Corporation
|
||||
Levi Botelho <levi_botelho@hotmail.com>
|
||||
Linquize
|
||||
lsowen
|
||||
Luka B
|
||||
Nils Haferkemper <nils@haferkemper.de>
|
||||
Matt Ickstadt <mattico8@gmail.com>
|
||||
Matt Williams
|
||||
Matthew Leibowitz <mattleibow@live.com>
|
||||
Memphisch <memphis@machzwo.de>
|
||||
Mendel Monteiro-Beckerman
|
||||
Menno Deij - van Rijswijk <m.deij@marin.nl>
|
||||
methdotnet
|
||||
Michael Fox <16841316+foxmja@users.noreply.github.com>
|
||||
Michael Hieke <mghie@gmx.net>
|
||||
Mikant <a.mikant@gmail.com>
|
||||
mirolev <miroslav.levicky@gmail.com>
|
||||
Mitch-Connor <acm@htri.net>
|
||||
moes_leco
|
||||
moljac
|
||||
mroth
|
||||
mrtncls
|
||||
myd7349 <myd7349@gmail.com>
|
||||
Oleg Tarasov <oleg.v.tarasov@gmail.com>
|
||||
Oystein Bjorke <oystein.bjorke@gmail.com>
|
||||
Patrice Marin <patrice.marin@thomsonreuters.com>
|
||||
Peter-B-
|
||||
Philippe AURIOU <p.auriou@live.fr>
|
||||
Piotr Warzocha <pw@piootr.pl>
|
||||
Poul Erik Venø <poulerikvenoehansen@gmail.com>
|
||||
Régis Boudin <regis@boudin.name>
|
||||
Rik Borger <isolocis@gmail.com>
|
||||
Rok Lampret <rlamp@users.noreply.github.com>
|
||||
ryang <decatf@gmail.com>
|
||||
Sarah Müller <sy-mueller@gmx-topmail.de>
|
||||
Senen Fernandez <senenf@gmail.com>
|
||||
Sergey Miryanov <sergey.miryanov@gmail.com>
|
||||
Scott W Harden <swharden@gmail.com>
|
||||
Shankar Mathiah Nanjundan <shankar.ooty@hotmail.com>
|
||||
Shun-ichi Goto <shunichi.goto@gmail.com>
|
||||
Soarc <gor.rustamyan@gmail.com>
|
||||
Soren Holstebroe <sh@pantoinspect.com>
|
||||
Stefan Rado <oxyplot@sradonia.net>
|
||||
stefan-schweiger
|
||||
Steve Hoelzer <shoelzer@gmail.com>
|
||||
Surfin Bird <illvdg13@gmail.com>
|
||||
Sven Dummis
|
||||
Taldoras <taldoras@googlemail.com>
|
||||
Tandy Carmichael <tcarmichael@frontier.com>
|
||||
Tasos Stamadianos <tasos.a.stam@gmail.com>
|
||||
Thorsten Claff <tclaff@gmail.com>
|
||||
thepretender
|
||||
tephyrnex
|
||||
Thomas Ibel <tibel@users.noreply.github.com>
|
||||
Tomasz Cielecki <tomasz@ostebaronen.dk>
|
||||
ToplandJ <jostein.topland@nov.com>
|
||||
twsl <45483159+twsI@users.noreply.github.com>
|
||||
Udo Liess
|
||||
VisualMelon
|
||||
vhoehn <veit.hoehn@hte-company.de>
|
||||
Vsevolod Kukol <sevo@sevo.org>
|
||||
Xavier <Xavier@xavier-PC.lsi>
|
||||
zur003 <Eric.Zurcher@csiro.au>
|
||||
Markus Ebner
|
||||
Duncan Robertson <duncanjacobrobertson@gmail.com>
|
||||
LauXjpn <laucomm@gmail.com>
|
||||
R. Usamentiaga
|
||||
Dmytro Shaurin
|
||||
Rustam Sayfutdinov
|
||||
Konstantin Stukov <havendv@gmail.com>
|
||||
jorgectf
|
||||
2
GitVersion.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
next-version: 2.0.0
|
||||
branches: {}
|
||||
BIN
Icons/OxyPlot.ico
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Icons/OxyPlot_100.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
Icons/OxyPlot_1024.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
Icons/OxyPlot_114.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
Icons/OxyPlot_120.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
Icons/OxyPlot_128.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
Icons/OxyPlot_144.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Icons/OxyPlot_150.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
Icons/OxyPlot_152.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
Icons/OxyPlot_16.png
Normal file
|
After Width: | Height: | Size: 584 B |
BIN
Icons/OxyPlot_20.png
Normal file
|
After Width: | Height: | Size: 730 B |
BIN
Icons/OxyPlot_210.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
Icons/OxyPlot_24.png
Normal file
|
After Width: | Height: | Size: 843 B |
BIN
Icons/OxyPlot_256.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
Icons/OxyPlot_270.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
Icons/OxyPlot_29.png
Normal file
|
After Width: | Height: | Size: 1006 B |
BIN
Icons/OxyPlot_32.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Icons/OxyPlot_40.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Icons/OxyPlot_48.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Icons/OxyPlot_50.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Icons/OxyPlot_512.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Icons/OxyPlot_57.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Icons/OxyPlot_58.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Icons/OxyPlot_64.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
Icons/OxyPlot_72.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Icons/OxyPlot_76.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
Icons/OxyPlot_80.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
Icons/OxyPlot_96.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
Icons/favicon.ico
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2014 OxyPlot contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
42
README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
OxyPlot is a cross-platform plotting library for .NET
|
||||
|
||||
 [](https://ci.appveyor.com/project/objorke/oxyplot)
|
||||
|
||||

|
||||
|
||||
|
||||
#### 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`
|
||||
|
||||
|
||||
#### Examples
|
||||
|
||||
You can find examples in the `/Source/Examples` folder in the code repository.
|
||||
|
||||
|
||||
#### NuGet packages
|
||||
|
||||
The latest pre-release packages are pushed by AppVeyor CI to [myget.org](https://www.myget.org/). To install these packages, set the myget.org package source `https://www.myget.org/F/oxyplot` and remember the "-pre" flag.
|
||||
|
||||
The stable release packages will be pushed to [nuget.org](https://www.nuget.org/packages?q=oxyplot). Note that we have have a lot of old (v2015.\*) and pre-release packages on this feed, and sometimes these show up even if they are unlisted.
|
||||
|
||||
See the [wiki](https://github.com/oxyplot/oxyplot/wiki/NuGet-packages) for information about the available packages.
|
||||
|
||||
|
||||
#### More information
|
||||
|
||||
- [Web page](https://oxyplot.github.io)
|
||||
- [Documentation](https://oxyplot.readthedocs.io/en/latest/)
|
||||
- [NuGet packages](https://www.nuget.org/packages?q=oxyplot)
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/oxyplot)
|
||||
- [Twitter](https://twitter.com/hashtag/oxyplot)
|
||||
- [Gitter](https://gitter.im/oxyplot/oxyplot) (chat)
|
||||
|
||||
|
||||
#### Contribute
|
||||
|
||||
See [Contributing](.github/CONTRIBUTING.md) for information about how to contribute!
|
||||
20
Source/.editorconfig
Normal file
@@ -0,0 +1,20 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = crlf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.cs]
|
||||
|
||||
#### .NET Coding Conventions ####
|
||||
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = true:warning
|
||||
dotnet_style_qualification_for_field = true:warning
|
||||
dotnet_style_qualification_for_method = true:warning
|
||||
dotnet_style_qualification_for_property = true:warning
|
||||
12
Source/Directory.Build.props
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project>
|
||||
<Sdk Name="DotNet.ReproducibleBuilds.Isolated" Version="1.1.1" />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNet.ReproducibleBuilds" Version="1.1.1" PrivateAssets="All"/>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<Copyright>Copyright (c) 2014-2022 OxyPlot Contributors</Copyright>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/oxyplot/oxyplot.git</RepositoryUrl>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
12
Source/Directory.Build.targets
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project>
|
||||
<ItemGroup Condition="$(GeneratePackageOnBuild)">
|
||||
<None Include="$(MSBuildThisFileDirectory)../Icons/OxyPlot_128.png" Pack="true" PackagePath="\" Visible="false" />
|
||||
<None Include="$(MSBuildThisFileDirectory)../README.md" Pack="true" PackagePath="\" Visible="false" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="$(GeneratePackageOnBuild)">
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://oxyplot.github.io/</PackageProjectUrl>
|
||||
<PackageIcon>OxyPlot_128.png</PackageIcon>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
12
Source/Examples/Core.Drawing/Example1/Example1.csproj
Normal file
@@ -0,0 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\OxyPlot.Core.Drawing\OxyPlot.Core.Drawing.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
86
Source/Examples/Core.Drawing/Example1/Program.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
namespace Example1
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Core.Drawing;
|
||||
using OxyPlot.Series;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var outputToFile = "test-oxyplot-static-export-file.png";
|
||||
var outputExportStreamOOP = "test-oxyplot-ExportToStream.png";
|
||||
var outputExportFileOOP = "test-oxyplot-ExportToFile.png";
|
||||
|
||||
var width = 1024;
|
||||
var height = 768;
|
||||
var background = OxyColors.LightGray;
|
||||
var resolution = 96d;
|
||||
|
||||
var model = BuildPlotModel();
|
||||
|
||||
// export to file using static methods
|
||||
PngExporter.Export(model, outputToFile, width, height, resolution);
|
||||
|
||||
// export using the instance methods
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
var pngExporter = new PngExporter { Width = width, Height = height, Resolution = resolution };
|
||||
pngExporter.Export(model, stream);
|
||||
System.IO.File.WriteAllBytes(outputExportStreamOOP, stream.ToArray());
|
||||
}
|
||||
|
||||
var pngExporter2 = new PngExporter { Width = width, Height = height, Resolution = resolution };
|
||||
var bitmap = pngExporter2.ExportToBitmap(model);
|
||||
bitmap.Save(outputExportFileOOP, System.Drawing.Imaging.ImageFormat.Png);
|
||||
bitmap.Save(Path.ChangeExtension(outputExportFileOOP, ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
|
||||
}
|
||||
|
||||
private static IPlotModel BuildPlotModel()
|
||||
{
|
||||
var rand = new Random(21);
|
||||
|
||||
var model = new PlotModel { Title = "Cake Type Popularity" };
|
||||
|
||||
var cakePopularity = Enumerable.Range(1, 5).Select(i => rand.NextDouble()).ToArray();
|
||||
var sum = cakePopularity.Sum();
|
||||
var barItems = cakePopularity.Select(cp => RandomBarItem(cp, sum)).ToArray();
|
||||
var barSeries = new BarSeries
|
||||
{
|
||||
ItemsSource = barItems,
|
||||
LabelPlacement = LabelPlacement.Base,
|
||||
LabelFormatString = "{0:.00}%"
|
||||
};
|
||||
|
||||
model.Series.Add(barSeries);
|
||||
|
||||
model.Axes.Add(new CategoryAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
Key = "CakeAxis",
|
||||
ItemsSource = new[]
|
||||
{
|
||||
"Apple cake",
|
||||
"Baumkuchen",
|
||||
"Bundt Cake",
|
||||
"Chocolate cake",
|
||||
"Carrot cake"
|
||||
}
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
private static BarItem RandomBarItem(double cp, double sum)
|
||||
=> new BarItem { Value = cp / sum * 100, Color = RandomColor() };
|
||||
|
||||
private static OxyColor RandomColor()
|
||||
{
|
||||
var r = new Random();
|
||||
return OxyColor.FromRgb((byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255));
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Source/Examples/ExampleGenerator/ExampleGenerator.csproj
Normal file
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0-windows;net7.0-windows</TargetFrameworks>
|
||||
<!--<UseWindowsForms>true</UseWindowsForms>-->
|
||||
<OutputType>Exe</OutputType>
|
||||
<ApplicationIcon />
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OxyPlot.WindowsForms\OxyPlot.WindowsForms.csproj" />
|
||||
<ProjectReference Include="..\ExampleLibrary\ExampleLibrary.csproj" />
|
||||
</ItemGroup>
|
||||
<!--<ItemGroup>
|
||||
<Content Include="..\TruePNG\TruePNG.exe">
|
||||
<Link>TruePNG.exe</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>-->
|
||||
|
||||
</Project>
|
||||
165
Source/Examples/ExampleGenerator/Program.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using ExampleLibrary;
|
||||
using OxyPlot;
|
||||
using OxyPlot.WindowsForms;
|
||||
|
||||
namespace ExampleGenerator
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
private static readonly OxyColor defaultBackground = OxyColor.Parse("#00000000");
|
||||
|
||||
public static string OutputDirectory { get; set; }
|
||||
|
||||
public static bool DoOptimizePng { get; set; }
|
||||
|
||||
public static bool ExportPng { get; set; }
|
||||
|
||||
public static bool ExportPdf { get; set; }
|
||||
|
||||
public static bool ExportSvg { get; set; }
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ExportPng = true;
|
||||
ExportPdf = true;
|
||||
ExportSvg = true;
|
||||
//DoOptimizePng = true;
|
||||
OutputDirectory = @".";
|
||||
if (args.Length > 0)
|
||||
{
|
||||
OutputDirectory = args[0];
|
||||
}
|
||||
|
||||
var exportTasks = new List<Task>();
|
||||
|
||||
var exampleAssembly = typeof(DocumentationExampleAttribute).Assembly;
|
||||
foreach (var type in exampleAssembly.GetTypes())
|
||||
{
|
||||
foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
|
||||
{
|
||||
var exportAttribute = method.GetCustomAttribute<DocumentationExampleAttribute>();
|
||||
if (exportAttribute == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var model = (PlotModel)method.Invoke(null, null);
|
||||
var exportTask = Export(model, exportAttribute.Filename.Replace('/', Path.DirectorySeparatorChar));
|
||||
exportTasks.Add(exportTask);
|
||||
}
|
||||
}
|
||||
|
||||
//Wait for exports to finish
|
||||
Task.WaitAll(exportTasks.ToArray());
|
||||
}
|
||||
|
||||
private static async Task Export(PlotModel model, string name)
|
||||
{
|
||||
if (model.Background == defaultBackground)
|
||||
model.Background = OxyColors.White;
|
||||
|
||||
var fileName = Path.Combine(OutputDirectory, name + ".png");
|
||||
var directory = Path.GetDirectoryName(fileName) ?? ".";
|
||||
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
if (ExportPng)
|
||||
{
|
||||
Console.WriteLine(fileName);
|
||||
using (var stream = File.Create(fileName))
|
||||
{
|
||||
var exporter = new PngExporter { Width = 600, Height = 400 };
|
||||
exporter.Export(model, stream);
|
||||
}
|
||||
|
||||
if (DoOptimizePng)
|
||||
await OptimizePng(fileName);
|
||||
}
|
||||
|
||||
if (ExportPdf)
|
||||
{
|
||||
fileName = Path.ChangeExtension(fileName, ".pdf");
|
||||
Console.WriteLine(fileName);
|
||||
using (var stream = File.Create(fileName))
|
||||
{
|
||||
var exporter = new PdfExporter { Width = 600d * 72 / 96, Height = 400d * 72 / 96 };
|
||||
exporter.Export(model, stream);
|
||||
}
|
||||
}
|
||||
|
||||
if (ExportSvg)
|
||||
{
|
||||
fileName = Path.ChangeExtension(fileName, ".svg");
|
||||
Console.WriteLine(fileName);
|
||||
|
||||
using (var stream = File.Create(fileName))
|
||||
{
|
||||
using (var exporter = new OxyPlot.WindowsForms.SvgExporter { Width = 600, Height = 400, IsDocument = true })
|
||||
{
|
||||
exporter.Export(model, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* PNG Optimization */
|
||||
|
||||
private static async Task OptimizePng(string pngFile)
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
await OptimizePngWithOptiPNG(pngFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
await OptimizePngWithTruePNG(pngFile);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task OptimizePngWithTruePNG(string pngFile)
|
||||
{
|
||||
// /o max : optimization level
|
||||
// /nc : don't change ColorType and BitDepth
|
||||
// /md keep pHYs : keep pHYs metadata
|
||||
var psi = new ProcessStartInfo("TruePNG.exe", pngFile + " /o max /nc /md keep pHYs")
|
||||
{
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
};
|
||||
try
|
||||
{
|
||||
var p = Process.Start(psi);
|
||||
await Task.Run(() => p.WaitForExit());
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
throw new Win32Exception(
|
||||
"Failed to run TruePNG optimization. Please ensure that TruePNG is installed and registered in the PATH variable.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task OptimizePngWithOptiPNG(string pngFile)
|
||||
{
|
||||
var psi = new ProcessStartInfo("optipng", "-o7 " + pngFile)
|
||||
{
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
};
|
||||
var p = Process.Start(psi);
|
||||
await Task.Run(() => p.WaitForExit());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="AnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("Annotations"), Tags("Annotations")]
|
||||
public static class AnnotationExamples
|
||||
{
|
||||
[Example("Tool tips")]
|
||||
public static PlotModel ToolTips()
|
||||
{
|
||||
var model = new PlotModel { Title = "Tool tips" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
model.Annotations.Add(new LineAnnotation { Slope = 0.1, Intercept = 1, Text = "LineAnnotation", ToolTip = "This is a tool tip for the LineAnnotation" });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumX = 20, MaximumX = 70, MinimumY = 10, MaximumY = 40, TextRotation = 10, Text = "RectangleAnnotation", ToolTip = "This is a tooltip for the RectangleAnnotation", Fill = OxyColor.FromAColor(99, OxyColors.Blue), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
model.Annotations.Add(new EllipseAnnotation { X = 20, Y = 60, Width = 20, Height = 15, Text = "EllipseAnnotation", ToolTip = "This is a tool tip for the EllipseAnnotation", TextRotation = 10, Fill = OxyColor.FromAColor(99, OxyColors.Green), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
model.Annotations.Add(new PointAnnotation { X = 50, Y = 50, Text = "P1", ToolTip = "This is a tool tip for the PointAnnotation" });
|
||||
model.Annotations.Add(new ArrowAnnotation { StartPoint = new DataPoint(8, 4), EndPoint = new DataPoint(0, 0), Color = OxyColors.Green, Text = "ArrowAnnotation", ToolTip = "This is a tool tip for the ArrowAnnotation" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(60, 60), Text = "TextAnnotation", ToolTip = "This is a tool tip for the TextAnnotation" });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ArrowAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("ArrowAnnotation"), Tags("Annotations")]
|
||||
public static class ArrowAnnotationExamples
|
||||
{
|
||||
[Example("ArrowAnnotation")]
|
||||
public static PlotModel ArrowAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "ArrowAnnotations" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -40, Maximum = 60 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
model.Annotations.Add(
|
||||
new ArrowAnnotation
|
||||
{
|
||||
StartPoint = new DataPoint(8, 4),
|
||||
EndPoint = new DataPoint(0, 0),
|
||||
Color = OxyColors.Green,
|
||||
Text = "StartPoint and EndPoint"
|
||||
});
|
||||
|
||||
model.Annotations.Add(
|
||||
new ArrowAnnotation
|
||||
{
|
||||
ArrowDirection = new ScreenVector(30, 70),
|
||||
EndPoint = new DataPoint(40, -3),
|
||||
Color = OxyColors.Blue,
|
||||
Text = "ArrowDirection and EndPoint"
|
||||
});
|
||||
|
||||
model.Annotations.Add(
|
||||
new ArrowAnnotation
|
||||
{
|
||||
ArrowDirection = new ScreenVector(30, -70),
|
||||
EndPoint = new DataPoint(10, -3),
|
||||
HeadLength = 14,
|
||||
HeadWidth = 6,
|
||||
Veeness = 4,
|
||||
Color = OxyColors.Red,
|
||||
Text = "HeadLength = 20, HeadWidth = 10, Veeness = 4"
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Rotations")]
|
||||
public static PlotModel Rotations()
|
||||
{
|
||||
var model = new PlotModel { Title = "ArrowAnnotation Rotations" };
|
||||
model.Axes.Add(
|
||||
new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
Minimum = -5,
|
||||
Maximum = 45,
|
||||
MajorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
|
||||
model.Axes.Add(
|
||||
new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
StartPosition = 1,
|
||||
EndPosition = 0,
|
||||
Minimum = -1,
|
||||
Maximum = 8,
|
||||
MajorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
|
||||
for (var i = 0; i < 360; i += 5)
|
||||
{
|
||||
var rad = i / 360d * Math.PI * 2;
|
||||
model.Annotations.Add(
|
||||
new ArrowAnnotation
|
||||
{
|
||||
EndPoint = new DataPoint(i % 45, i / 45),
|
||||
Text = $"{i}°",
|
||||
ArrowDirection = new ScreenVector(Math.Cos(rad), Math.Sin(rad)) * 25,
|
||||
HeadLength = 5
|
||||
});
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="EllipseAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("EllipseAnnotation"), Tags("Annotations")]
|
||||
public static class EllipseAnnotationExamples
|
||||
{
|
||||
[Example("EllipseAnnotation")]
|
||||
public static PlotModel EllipseAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "EllipseAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
model.Annotations.Add(new EllipseAnnotation { X = 20, Y = 60, Width = 20, Height = 15, Text = "EllipseAnnotation", TextRotation = 10, Fill = OxyColor.FromAColor(99, OxyColors.Green), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
|
||||
model.Annotations.Add(new EllipseAnnotation { X = 20, Y = 20, Width = 20, Height = 20, Fill = OxyColor.FromAColor(99, OxyColors.Green), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
model.Annotations.Add(new EllipseAnnotation { X = 30, Y = 20, Width = 20, Height = 20, Fill = OxyColor.FromAColor(99, OxyColors.Red), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
model.Annotations.Add(new EllipseAnnotation { X = 25, Y = 30, Width = 20, Height = 20, Fill = OxyColor.FromAColor(99, OxyColors.Blue), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="FunctionAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("FunctionAnnotation"), Tags("Annotations")]
|
||||
public static class FunctionAnnotationExamples
|
||||
{
|
||||
[Example("FunctionAnnotation")]
|
||||
public static PlotModel FunctionAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "FunctionAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
model.Annotations.Add(new FunctionAnnotation { Equation = Math.Sin, StrokeThickness = 2, Color = OxyColor.FromAColor(120, OxyColors.Blue), Text = "f(x)=sin(x)" });
|
||||
model.Annotations.Add(new FunctionAnnotation { Equation = y => y * y, StrokeThickness = 2, Color = OxyColor.FromAColor(120, OxyColors.Red), Type = FunctionAnnotationType.EquationY, Text = "f(y)=y^2" });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ImageAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("ImageAnnotation"), Tags("Annotations")]
|
||||
public static class ImageAnnotationExamples
|
||||
{
|
||||
[Example("ImageAnnotation")]
|
||||
public static PlotModel ImageAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "ImageAnnotation", PlotMargins = new OxyThickness(60, 4, 4, 60) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
OxyImage image;
|
||||
var assembly = typeof(ImageAnnotationExamples).GetTypeInfo().Assembly;
|
||||
using (var stream = assembly.GetManifestResourceStream("ExampleLibrary.Resources.OxyPlot.png"))
|
||||
{
|
||||
image = new OxyImage(stream);
|
||||
}
|
||||
|
||||
// Centered in plot area, filling width
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
Opacity = 0.2,
|
||||
Interpolate = false,
|
||||
X = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
|
||||
Y = new PlotLength(0.5, PlotLengthUnit.RelativeToPlotArea),
|
||||
Width = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Middle
|
||||
});
|
||||
|
||||
// Relative to plot area, inside top/right corner, 120pt wide
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
X = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
|
||||
Y = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
|
||||
Width = new PlotLength(120, PlotLengthUnit.ScreenUnits),
|
||||
HorizontalAlignment = HorizontalAlignment.Right,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
});
|
||||
|
||||
// Relative to plot area, above top/left corner, 20pt high
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
X = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
|
||||
Y = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
|
||||
OffsetY = new PlotLength(-5, PlotLengthUnit.ScreenUnits),
|
||||
Height = new PlotLength(20, PlotLengthUnit.ScreenUnits),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Bottom
|
||||
});
|
||||
|
||||
// At the point (50,50), 200pt wide
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
X = new PlotLength(50, PlotLengthUnit.Data),
|
||||
Y = new PlotLength(50, PlotLengthUnit.Data),
|
||||
Width = new PlotLength(200, PlotLengthUnit.ScreenUnits),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
});
|
||||
|
||||
// At the point (50,20), 50 x units wide
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
X = new PlotLength(50, PlotLengthUnit.Data),
|
||||
Y = new PlotLength(20, PlotLengthUnit.Data),
|
||||
Width = new PlotLength(50, PlotLengthUnit.Data),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
});
|
||||
|
||||
// Relative to the viewport, centered at the bottom, with offset (could also use bottom vertical alignment)
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
X = new PlotLength(0.5, PlotLengthUnit.RelativeToViewport),
|
||||
Y = new PlotLength(1, PlotLengthUnit.RelativeToViewport),
|
||||
OffsetY = new PlotLength(-35, PlotLengthUnit.ScreenUnits),
|
||||
Height = new PlotLength(30, PlotLengthUnit.ScreenUnits),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
});
|
||||
|
||||
// Changing opacity
|
||||
for (int y = 0; y < 10; y++)
|
||||
{
|
||||
model.Annotations.Add(
|
||||
new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
Opacity = (y + 1) / 10.0,
|
||||
X = new PlotLength(10, PlotLengthUnit.Data),
|
||||
Y = new PlotLength(y * 2, PlotLengthUnit.Data),
|
||||
Width = new PlotLength(100, PlotLengthUnit.ScreenUnits),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Bottom
|
||||
});
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ImageAnnotation - gradient backgrounds")]
|
||||
public static PlotModel ImageAnnotationAsBackgroundGradient()
|
||||
{
|
||||
// http://en.wikipedia.org/wiki/Chartjunk
|
||||
var model = new PlotModel { Title = "Using ImageAnnotations to draw a gradient backgrounds", Subtitle = "But do you really want this? This is called 'chartjunk'!", PlotMargins = new OxyThickness(60, 4, 4, 60) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
// create a gradient image of height n
|
||||
int n = 256;
|
||||
var imageData1 = new OxyColor[1, n];
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
imageData1[0, i] = OxyColor.Interpolate(OxyColors.Blue, OxyColors.Red, i / (n - 1.0));
|
||||
}
|
||||
|
||||
var image1 = OxyImage.Create(imageData1, ImageFormat.Png); // png is required for silverlight
|
||||
|
||||
// or create a gradient image of height 2 (requires bitmap interpolation to be supported)
|
||||
var imageData2 = new OxyColor[1, 2];
|
||||
imageData2[0, 0] = OxyColors.Yellow; // top color
|
||||
imageData2[0, 1] = OxyColors.Gray; // bottom color
|
||||
|
||||
var image2 = OxyImage.Create(imageData2, ImageFormat.Png); // png is required for silverlight
|
||||
|
||||
// gradient filling the viewport
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image2,
|
||||
Interpolate = true,
|
||||
Layer = AnnotationLayer.BelowAxes,
|
||||
X = new PlotLength(0, PlotLengthUnit.RelativeToViewport),
|
||||
Y = new PlotLength(0, PlotLengthUnit.RelativeToViewport),
|
||||
Width = new PlotLength(1, PlotLengthUnit.RelativeToViewport),
|
||||
Height = new PlotLength(1, PlotLengthUnit.RelativeToViewport),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
});
|
||||
|
||||
// gradient filling the plot area
|
||||
model.Annotations.Add(new ImageAnnotation
|
||||
{
|
||||
ImageSource = image1,
|
||||
Interpolate = true,
|
||||
Layer = AnnotationLayer.BelowAxes,
|
||||
X = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
|
||||
Y = new PlotLength(0, PlotLengthUnit.RelativeToPlotArea),
|
||||
Width = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
|
||||
Height = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Top
|
||||
});
|
||||
|
||||
// verify that a series is rendered above the gradients
|
||||
model.Series.Add(new FunctionSeries(Math.Sin, 0, 7, 0.01));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ImageAnnotation - normal axes")]
|
||||
public static PlotModel ImageAnnotation_NormalAxes()
|
||||
{
|
||||
var model = new PlotModel { Title = "ImageAnnotation - normal axes" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
// create an image
|
||||
var pixels = new OxyColor[2, 2];
|
||||
pixels[0, 0] = OxyColors.Blue;
|
||||
pixels[1, 0] = OxyColors.Yellow;
|
||||
pixels[0, 1] = OxyColors.Green;
|
||||
pixels[1, 1] = OxyColors.Red;
|
||||
|
||||
var image = OxyImage.Create(pixels, ImageFormat.Png);
|
||||
|
||||
model.Annotations.Add(
|
||||
new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
Interpolate = false,
|
||||
X = new PlotLength(0, PlotLengthUnit.Data),
|
||||
Y = new PlotLength(0, PlotLengthUnit.Data),
|
||||
Width = new PlotLength(80, PlotLengthUnit.Data),
|
||||
Height = new PlotLength(50, PlotLengthUnit.Data),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Bottom
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ImageAnnotation - reverse horizontal axis")]
|
||||
public static PlotModel ImageAnnotation_ReverseHorizontalAxis()
|
||||
{
|
||||
var model = new PlotModel { Title = "ImageAnnotation - reverse horizontal axis" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, StartPosition = 1, EndPosition = 0 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
// create an image
|
||||
var pixels = new OxyColor[2, 2];
|
||||
pixels[0, 0] = OxyColors.Blue;
|
||||
pixels[1, 0] = OxyColors.Yellow;
|
||||
pixels[0, 1] = OxyColors.Green;
|
||||
pixels[1, 1] = OxyColors.Red;
|
||||
|
||||
var image = OxyImage.Create(pixels, ImageFormat.Png);
|
||||
|
||||
model.Annotations.Add(
|
||||
new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
Interpolate = false,
|
||||
X = new PlotLength(100, PlotLengthUnit.Data),
|
||||
Y = new PlotLength(0, PlotLengthUnit.Data),
|
||||
Width = new PlotLength(80, PlotLengthUnit.Data),
|
||||
Height = new PlotLength(50, PlotLengthUnit.Data),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Bottom
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ImageAnnotation - reverse vertical axis")]
|
||||
public static PlotModel ImageAnnotation_ReverseVerticalAxis()
|
||||
{
|
||||
var model = new PlotModel { Title = "ImageAnnotation - reverse vertical axis" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, StartPosition = 1, EndPosition = 0 });
|
||||
|
||||
// create an image
|
||||
var pixels = new OxyColor[2, 2];
|
||||
pixels[0, 0] = OxyColors.Blue;
|
||||
pixels[1, 0] = OxyColors.Yellow;
|
||||
pixels[0, 1] = OxyColors.Green;
|
||||
pixels[1, 1] = OxyColors.Red;
|
||||
|
||||
var image = OxyImage.Create(pixels, ImageFormat.Png);
|
||||
|
||||
model.Annotations.Add(
|
||||
new ImageAnnotation
|
||||
{
|
||||
ImageSource = image,
|
||||
Interpolate = false,
|
||||
X = new PlotLength(0, PlotLengthUnit.Data),
|
||||
Y = new PlotLength(100, PlotLengthUnit.Data),
|
||||
Width = new PlotLength(80, PlotLengthUnit.Data),
|
||||
Height = new PlotLength(50, PlotLengthUnit.Data),
|
||||
HorizontalAlignment = HorizontalAlignment.Left,
|
||||
VerticalAlignment = VerticalAlignment.Bottom
|
||||
});
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LineAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("LineAnnotation"), Tags("Annotations")]
|
||||
public static class LineAnnotationExamples
|
||||
{
|
||||
[Example("LineAnnotation on linear axes")]
|
||||
public static PlotModel LineAnnotationOnLinearAxes()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineAnnotation on linear axes" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Slope = 0.1,
|
||||
Intercept = 1,
|
||||
Text = "First",
|
||||
BorderBackground = OxyColors.White.ChangeOpacity(0.75),
|
||||
BorderPadding = new OxyThickness(5)
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Slope = 0.3,
|
||||
Intercept = 2,
|
||||
MaximumX = 40,
|
||||
Color = OxyColors.Red,
|
||||
Text = "Second",
|
||||
BorderBackground = OxyColors.White.ChangeOpacity(0.75),
|
||||
BorderPadding = new OxyThickness(5)
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Vertical,
|
||||
X = 4,
|
||||
MaximumY = 10,
|
||||
Color = OxyColors.Green,
|
||||
Text = "Vertical",
|
||||
BorderBackground = OxyColors.White.ChangeOpacity(0.75),
|
||||
BorderPadding = new OxyThickness(5)
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Horizontal,
|
||||
Y = 2,
|
||||
MaximumX = 4,
|
||||
Color = OxyColors.Gold,
|
||||
Text = "Horizontal",
|
||||
BorderBackground = OxyColors.White.ChangeOpacity(0.75),
|
||||
BorderPadding = new OxyThickness(5)
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineAnnotation on logarithmic axes")]
|
||||
public static PlotModel LineAnnotationOnLogarithmicAxes()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineAnnotation on logarithmic axes" };
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Bottom, Minimum = 1, Maximum = 80 });
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Left, Minimum = 1, Maximum = 10 });
|
||||
model.Annotations.Add(new LineAnnotation { Slope = 0.1, Intercept = 1, Text = "First", TextMargin = 40 });
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation { Slope = 0.3, Intercept = 2, MaximumX = 40, Color = OxyColors.Red, Text = "Second" });
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Vertical,
|
||||
X = 4,
|
||||
MaximumY = 10,
|
||||
Color = OxyColors.Green,
|
||||
Text = "Vertical"
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Horizontal,
|
||||
Y = 2,
|
||||
MaximumX = 4,
|
||||
Color = OxyColors.Gold,
|
||||
Text = "Horizontal"
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineAnnotation with text orientation specified")]
|
||||
public static PlotModel LineAnnotationOnLinearAxesWithTextOrientation()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineAnnotations", Subtitle = "with TextOrientation specified" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Slope = 0.1,
|
||||
Intercept = 1,
|
||||
Text = "Horizontal",
|
||||
TextOrientation = AnnotationTextOrientation.Horizontal,
|
||||
TextVerticalAlignment = VerticalAlignment.Bottom
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Slope = 0.3,
|
||||
Intercept = 2,
|
||||
MaximumX = 40,
|
||||
Color = OxyColors.Red,
|
||||
Text = "Vertical",
|
||||
TextOrientation = AnnotationTextOrientation.Vertical
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Vertical,
|
||||
X = 4,
|
||||
MaximumY = 10,
|
||||
Color = OxyColors.Green,
|
||||
Text = "Horizontal (x=4)",
|
||||
TextPadding = 8,
|
||||
TextOrientation = AnnotationTextOrientation.Horizontal
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Vertical,
|
||||
X = 45,
|
||||
MaximumY = 10,
|
||||
Color = OxyColors.Green,
|
||||
Text = "Horizontal (x=45)",
|
||||
TextHorizontalAlignment = HorizontalAlignment.Left,
|
||||
TextPadding = 8,
|
||||
TextOrientation = AnnotationTextOrientation.Horizontal
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new LineAnnotation
|
||||
{
|
||||
Type = LineAnnotationType.Horizontal,
|
||||
Y = 2,
|
||||
MaximumX = 4,
|
||||
Color = OxyColors.Gold,
|
||||
Text = "Horizontal",
|
||||
TextLinePosition = 0.5,
|
||||
TextOrientation = AnnotationTextOrientation.Horizontal
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineAnnotation - ClipByAxis property")]
|
||||
public static PlotModel LinearAxesMultipleAxes()
|
||||
{
|
||||
var model = new PlotModel { Title = "ClipByAxis property", Subtitle = "This property specifies if the annotation should be clipped by the current axes or by the full plot area." };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80, StartPosition = 0, EndPosition = 0.45, TextColor = OxyColors.Red });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10, StartPosition = 0, EndPosition = 0.45, TextColor = OxyColors.Green });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80, StartPosition = 0.55, EndPosition = 1, TextColor = OxyColors.Blue });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10, StartPosition = 0.55, EndPosition = 1, TextColor = OxyColors.Orange });
|
||||
|
||||
model.Annotations.Add(new LineAnnotation { ClipByYAxis = true, Type = LineAnnotationType.Vertical, X = 0, Color = OxyColors.Green, Text = "Vertical, ClipByAxis = true" });
|
||||
model.Annotations.Add(new LineAnnotation { ClipByYAxis = false, Type = LineAnnotationType.Vertical, X = 20, Color = OxyColors.Green, Text = "Vertical, ClipByAxis = false" });
|
||||
model.Annotations.Add(new LineAnnotation { ClipByXAxis = true, Type = LineAnnotationType.Horizontal, Y = 2, Color = OxyColors.Gold, Text = "Horizontal, ClipByAxis = true" });
|
||||
model.Annotations.Add(new LineAnnotation { ClipByXAxis = false, Type = LineAnnotationType.Horizontal, Y = 8, Color = OxyColors.Gold, Text = "Horizontal, ClipByAxis = false" });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineAnnotation on reversed axes")]
|
||||
public static PlotModel ReversedAxes()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineAnnotation on reversed axes" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80, StartPosition = 1, EndPosition = 0 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10, StartPosition = 1, EndPosition = 0 });
|
||||
model.Annotations.Add(new LineAnnotation { Slope = 0.1, Intercept = 1, Text = "First", TextHorizontalAlignment = HorizontalAlignment.Left });
|
||||
model.Annotations.Add(new LineAnnotation { Slope = 0.3, Intercept = 2, MaximumX = 40, Color = OxyColors.Red, Text = "Second", TextHorizontalAlignment = HorizontalAlignment.Left, TextVerticalAlignment = VerticalAlignment.Bottom });
|
||||
model.Annotations.Add(new LineAnnotation { Type = LineAnnotationType.Vertical, X = 4, MaximumY = 10, Color = OxyColors.Green, Text = "Vertical", TextHorizontalAlignment = HorizontalAlignment.Right });
|
||||
model.Annotations.Add(new LineAnnotation { Type = LineAnnotationType.Horizontal, Y = 2, MaximumX = 4, Color = OxyColors.Gold, Text = "Horizontal", TextHorizontalAlignment = HorizontalAlignment.Left });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PointAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("PointAnnotation"), Tags("Annotations")]
|
||||
public static class PointAnnotationExamples
|
||||
{
|
||||
[Example("PointAnnotation")]
|
||||
public static PlotModel PointAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "PointAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
model.Annotations.Add(new PointAnnotation { X = 50, Y = 50, Text = "P1" });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PointAnnotation - shapes")]
|
||||
public static PlotModel PointAnnotationShapes()
|
||||
{
|
||||
var model = new PlotModel { Title = "PointAnnotation - shapes" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Maximum = 120 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
// filled
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 20,
|
||||
Y = 60,
|
||||
Text = "Circle",
|
||||
Shape = MarkerType.Circle,
|
||||
Fill = OxyColors.LightGray,
|
||||
Stroke = OxyColors.DarkGray,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 40,
|
||||
Y = 60,
|
||||
Text = "Square",
|
||||
Shape = MarkerType.Square,
|
||||
Fill = OxyColors.LightBlue,
|
||||
Stroke = OxyColors.DarkBlue,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 60,
|
||||
Y = 60,
|
||||
Text = "Triangle",
|
||||
Shape = MarkerType.Triangle,
|
||||
Fill = OxyColors.IndianRed,
|
||||
Stroke = OxyColors.Black,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 80,
|
||||
Y = 60,
|
||||
Text = "Diamond",
|
||||
Shape = MarkerType.Diamond,
|
||||
Fill = OxyColors.ForestGreen,
|
||||
Stroke = OxyColors.Black,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 100,
|
||||
Y = 60,
|
||||
Text = "Custom",
|
||||
Shape = MarkerType.Custom,
|
||||
CustomOutline =
|
||||
new[]
|
||||
{
|
||||
new ScreenPoint(-1, -1), new ScreenPoint(1, 1), new ScreenPoint(-1, 1),
|
||||
new ScreenPoint(1, -1)
|
||||
},
|
||||
Stroke = OxyColors.Black,
|
||||
Fill = OxyColors.CadetBlue,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
|
||||
// not filled
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 20,
|
||||
Y = 40,
|
||||
Text = "Cross",
|
||||
Shape = MarkerType.Cross,
|
||||
Stroke = OxyColors.IndianRed,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 40,
|
||||
Y = 40,
|
||||
Text = "Plus",
|
||||
Shape = MarkerType.Plus,
|
||||
Stroke = OxyColors.Navy,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = 60,
|
||||
Y = 40,
|
||||
Text = "Star",
|
||||
Shape = MarkerType.Star,
|
||||
Stroke = OxyColors.DarkOliveGreen,
|
||||
StrokeThickness = 1
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PointAnnotation - text alignments")]
|
||||
public static PlotModel PointAnnotationTextAlignment()
|
||||
{
|
||||
var model = new PlotModel { Title = "PointAnnotation - text alignments" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -50, Maximum = 50 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -50, Maximum = 50 });
|
||||
|
||||
for (var ha = -1; ha <= 1; ha++)
|
||||
{
|
||||
var h = (HorizontalAlignment)ha;
|
||||
for (var va = -1; va <= 1; va++)
|
||||
{
|
||||
var v = (VerticalAlignment)va;
|
||||
model.Annotations.Add(
|
||||
new PointAnnotation
|
||||
{
|
||||
X = ha * 20,
|
||||
Y = va * 20,
|
||||
Size = 10,
|
||||
Text = h + "," + v,
|
||||
TextHorizontalAlignment = h,
|
||||
TextVerticalAlignment = v
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PolygonAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("PolygonAnnotation"), Tags("Annotations")]
|
||||
public static class PolygonAnnotationExamples
|
||||
{
|
||||
[Example("PolygonAnnotation")]
|
||||
public static PlotModel PolygonAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "PolygonAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 20 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
var a1 = new PolygonAnnotation { Text = "Polygon 1" };
|
||||
a1.Points.AddRange(new[] { new DataPoint(4, -2), new DataPoint(8, -4), new DataPoint(17, 7), new DataPoint(5, 8), new DataPoint(2, 5) });
|
||||
model.Annotations.Add(a1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolygonAnnotation with custom text position and alignment")]
|
||||
public static PlotModel PolygonAnnotationTextPosition()
|
||||
{
|
||||
var model = new PlotModel { Title = "PolygonAnnotation with fixed text position and alignment" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 20 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
var a1 = new PolygonAnnotation { Text = "Polygon 1", TextHorizontalAlignment = HorizontalAlignment.Left, TextVerticalAlignment = VerticalAlignment.Bottom, TextPosition = new DataPoint(4.1, -1.9) };
|
||||
a1.Points.AddRange(new[] { new DataPoint(4, -2), new DataPoint(8, -2), new DataPoint(17, 7), new DataPoint(5, 8), new DataPoint(4, 5) });
|
||||
model.Annotations.Add(a1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("AnnotationLayer property")]
|
||||
public static PlotModel AnnotationLayerProperty()
|
||||
{
|
||||
var model = new PlotModel { Title = "Annotation Layers" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 30, MajorGridlineStyle = LineStyle.Solid, MajorGridlineThickness = 1 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10, MajorGridlineStyle = LineStyle.Solid, MajorGridlineThickness = 1 });
|
||||
|
||||
var a1 = new PolygonAnnotation
|
||||
{
|
||||
Layer = AnnotationLayer.BelowAxes,
|
||||
Text = "Layer = BelowAxes"
|
||||
};
|
||||
a1.Points.AddRange(new[]
|
||||
{
|
||||
new DataPoint(-11, -2), new DataPoint(-7, -4), new DataPoint(-3, 7), new DataPoint(-10, 8),
|
||||
new DataPoint(-13, 5)
|
||||
});
|
||||
model.Annotations.Add(a1);
|
||||
var a2 = new PolygonAnnotation
|
||||
{
|
||||
Layer = AnnotationLayer.BelowSeries,
|
||||
Text = "Layer = BelowSeries"
|
||||
};
|
||||
a2.Points.AddRange(new DataPoint[]
|
||||
{
|
||||
new DataPoint(4, -2), new DataPoint(8, -4), new DataPoint(12, 7), new DataPoint(5, 8),
|
||||
new DataPoint(2, 5)
|
||||
});
|
||||
model.Annotations.Add(a2);
|
||||
var a3 = new PolygonAnnotation { Layer = AnnotationLayer.AboveSeries, Text = "Layer = AboveSeries" };
|
||||
a3.Points.AddRange(new[] { new DataPoint(19, -2), new DataPoint(23, -4), new DataPoint(27, 7), new DataPoint(20, 8), new DataPoint(17, 5) });
|
||||
model.Annotations.Add(a3);
|
||||
|
||||
model.Series.Add(new FunctionSeries(Math.Sin, -20, 30, 400));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Koch Snowflakes")]
|
||||
public static PlotModel KockSnowflakes()
|
||||
{
|
||||
DataPoint[] triangle(DataPoint centre)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new DataPoint(centre.X, centre.Y + 1),
|
||||
new DataPoint(centre.X + Math.Sin(Math.PI * 2 / 3), centre.Y + Math.Cos(Math.PI * 2 / 3)),
|
||||
new DataPoint(centre.X + Math.Sin(Math.PI * 4 / 3), centre.Y + Math.Cos(Math.PI * 4 / 3)),
|
||||
};
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "PolygonAnnotation", PlotType = PlotType.Cartesian };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -4, Maximum = 4 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -2, Maximum = 2 });
|
||||
|
||||
var a1 = new PolygonAnnotation { Text = "MSL = 4", MinimumSegmentLength = 4 };
|
||||
a1.Points.AddRange(KochFractal(triangle(new DataPoint(-2, 0)), 8, true, true));
|
||||
model.Annotations.Add(a1);
|
||||
|
||||
var a2 = new PolygonAnnotation { Text = "MSL = 2", MinimumSegmentLength = 2 };
|
||||
a2.Points.AddRange(KochFractal(triangle(new DataPoint(0, 0)), 8, true, true));
|
||||
model.Annotations.Add(a2);
|
||||
|
||||
var a3 = new PolygonAnnotation { Text = "MSL = 1", MinimumSegmentLength = 1 };
|
||||
a3.Points.AddRange(KochFractal(triangle(new DataPoint(2, 0)), 8, true, true));
|
||||
model.Annotations.Add(a3);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
public static DataPoint[] KochFractal(DataPoint[] seed, int n, bool clockwise, bool closed)
|
||||
{
|
||||
var cos60 = Math.Cos(Math.PI / 3);
|
||||
var sin60 = Math.Sin(Math.PI / 3);
|
||||
var cur = seed;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var next = new DataPoint[closed ? cur.Length * 4 : cur.Length * 4 - 3];
|
||||
for (int j = 0; j < (closed ? cur.Length : cur.Length - 1); j++)
|
||||
{
|
||||
var p0 = cur[j];
|
||||
var p1 = cur[(j + 1) % cur.Length];
|
||||
|
||||
var dx = (p1.X - p0.X) / 3;
|
||||
var dy = (p1.Y - p0.Y) / 3;
|
||||
|
||||
double dx2, dy2;
|
||||
if (clockwise)
|
||||
{
|
||||
dx2 = cos60 * dx - sin60 * dy;
|
||||
dy2 = cos60 * dy + sin60 * dx;
|
||||
}
|
||||
else
|
||||
{
|
||||
dx2 = cos60 * dx - sin60 * dy;
|
||||
dy2 = cos60 * dy + sin60 * dx;
|
||||
}
|
||||
|
||||
next[j * 4] = p0;
|
||||
next[j * 4 + 1] = new DataPoint(p0.X + dx, p0.Y + dy);
|
||||
next[j * 4 + 2] = new DataPoint(p0.X + dx + dx2, p0.Y + dy + dy2);
|
||||
next[j * 4 + 3] = new DataPoint(p0.X + dx * 2, p0.Y + dy * 2);
|
||||
}
|
||||
|
||||
if (!closed)
|
||||
{
|
||||
next[next.Length - 1] = cur[cur.Length - 1];
|
||||
}
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PolylineAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("PolylineAnnotation"), Tags("Annotations")]
|
||||
public static class PolylineAnnotationExamples
|
||||
{
|
||||
[Example("PolylineAnnotation")]
|
||||
public static PlotModel PolylineAnnotations()
|
||||
{
|
||||
var model = new PlotModel { Title = "PolylineAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 30 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 30 });
|
||||
var a1 = new PolylineAnnotation { Text = "Polyline" };
|
||||
a1.Points.AddRange(new[] { new DataPoint(0, 10), new DataPoint(5, 5), new DataPoint(20, 1), new DataPoint(30, 20) });
|
||||
var a2 = new PolylineAnnotation
|
||||
{
|
||||
InterpolationAlgorithm = InterpolationAlgorithms.CanonicalSpline,
|
||||
Text = "Smooth Polyline"
|
||||
};
|
||||
a2.Points.AddRange(new[] { new DataPoint(0, 15), new DataPoint(3, 23), new DataPoint(9, 30), new DataPoint(20, 12), new DataPoint(30, 10) });
|
||||
model.Annotations.Add(a1);
|
||||
model.Annotations.Add(a2);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Koch Surfaces")]
|
||||
public static PlotModel KochSurface()
|
||||
{
|
||||
DataPoint[] plane(DataPoint centre)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new DataPoint(centre.X - 1, centre.Y),
|
||||
new DataPoint(centre.X + 1, centre.Y),
|
||||
};
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "PolygonAnnotation", PlotType = PlotType.Cartesian };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -2, Maximum = 2 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -2, Maximum = 2 });
|
||||
|
||||
var a1 = new PolylineAnnotation { Text = "MSL = 4", MinimumSegmentLength = 4, LineStyle = LineStyle.Solid, TextPosition = new DataPoint(0, 1) };
|
||||
a1.Points.AddRange(PolygonAnnotationExamples.KochFractal(plane(new DataPoint(0, 1)), 8, true, false));
|
||||
model.Annotations.Add(a1);
|
||||
|
||||
var a2 = new PolylineAnnotation { Text = "MSL = 2", MinimumSegmentLength = 2, LineStyle = LineStyle.Solid, TextPosition = new DataPoint(0, 0) };
|
||||
a2.Points.AddRange(PolygonAnnotationExamples.KochFractal(plane(new DataPoint(0, 0)), 8, true, false));
|
||||
model.Annotations.Add(a2);
|
||||
|
||||
var a3 = new PolylineAnnotation { Text = "MSL = 1", MinimumSegmentLength = 1, LineStyle = LineStyle.Solid, TextPosition = new DataPoint(0, -1) };
|
||||
a3.Points.AddRange(PolygonAnnotationExamples.KochFractal(plane(new DataPoint(0, -1)), 8, true, false));
|
||||
model.Annotations.Add(a3);
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="RectangleAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("RectangleAnnotation"), Tags("Annotations")]
|
||||
public static class RectangleAnnotationExamples
|
||||
{
|
||||
[Example("RectangleAnnotation")]
|
||||
public static PlotModel RectangleAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "RectangleAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumX = 20, MaximumX = 70, MinimumY = 10, MaximumY = 40, TextRotation = 10, Text = "RectangleAnnotation", Fill = OxyColor.FromAColor(99, OxyColors.Blue), Stroke = OxyColors.Black, StrokeThickness = 2 });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RectangleAnnotations - vertical limit")]
|
||||
public static PlotModel RectangleAnnotationVerticalLimit()
|
||||
{
|
||||
var model = new PlotModel { Title = "RectangleAnnotations - vertical limit" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
model.Annotations.Add(new RectangleAnnotation { MaximumY = 89.5, Text = "Valid area", Fill = OxyColor.FromAColor(99, OxyColors.Black) });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RectangleAnnotation - horizontal bands")]
|
||||
public static PlotModel RectangleAnnotationHorizontals()
|
||||
{
|
||||
var model = new PlotModel { Title = "RectangleAnnotation - horizontal bands" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 10 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 87, Maximum = 97, MajorStep = 1, MinorStep = 1 });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumY = 89.5, MaximumY = 90.8, Text = "Invalid", Fill = OxyColor.FromAColor(99, OxyColors.Red) });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumY = 90.8, MaximumY = 92.1, Fill = OxyColor.FromAColor(99, OxyColors.Orange) });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumY = 92.1, MaximumY = 94.6, Fill = OxyColor.FromAColor(99, OxyColors.Yellow) });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumY = 94.6, MaximumY = 96, Text = "Ok", Fill = OxyColor.FromAColor(99, OxyColors.Green) });
|
||||
LineSeries series1;
|
||||
model.Series.Add(series1 = new LineSeries { Color = OxyColors.Black, StrokeThickness = 6.0, LineJoin = LineJoin.Round });
|
||||
series1.Points.Add(new DataPoint(0.5, 90.7));
|
||||
series1.Points.Add(new DataPoint(1.5, 91.2));
|
||||
series1.Points.Add(new DataPoint(2.5, 91));
|
||||
series1.Points.Add(new DataPoint(3.5, 89.5));
|
||||
series1.Points.Add(new DataPoint(4.5, 92.5));
|
||||
series1.Points.Add(new DataPoint(5.5, 93.1));
|
||||
series1.Points.Add(new DataPoint(6.5, 94.5));
|
||||
series1.Points.Add(new DataPoint(7.5, 95.5));
|
||||
series1.Points.Add(new DataPoint(8.5, 95.7));
|
||||
series1.Points.Add(new DataPoint(9.5, 96.0));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RectangleAnnotation - vertical bands")]
|
||||
public static PlotModel RectangleAnnotationVerticals()
|
||||
{
|
||||
var model = new PlotModel { Title = "RectangleAnnotation - vertical bands" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 10 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 87, Maximum = 97, MajorStep = 1, MinorStep = 1 });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumX = 2.5, MaximumX = 2.8, TextRotation = 90, Text = "Red", Fill = OxyColor.FromAColor(99, OxyColors.Red) });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumX = 2.8, MaximumX = 6.1, TextRotation = 90, Text = "Orange", Fill = OxyColor.FromAColor(99, OxyColors.Orange) });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumX = 6.1, MaximumX = 7.6, TextRotation = 90, Text = "Yellow", Fill = OxyColor.FromAColor(99, OxyColors.Yellow) });
|
||||
model.Annotations.Add(new RectangleAnnotation { MinimumX = 7.6, MaximumX = 9.7, TextRotation = 270, Text = "Green", Fill = OxyColor.FromAColor(99, OxyColors.Green) });
|
||||
LineSeries series1;
|
||||
model.Series.Add(series1 = new LineSeries { Color = OxyColors.Black, StrokeThickness = 6.0, LineJoin = LineJoin.Round });
|
||||
series1.Points.Add(new DataPoint(0.5, 90.7));
|
||||
series1.Points.Add(new DataPoint(1.5, 91.2));
|
||||
series1.Points.Add(new DataPoint(2.5, 91));
|
||||
series1.Points.Add(new DataPoint(3.5, 89.5));
|
||||
series1.Points.Add(new DataPoint(4.5, 92.5));
|
||||
series1.Points.Add(new DataPoint(5.5, 93.1));
|
||||
series1.Points.Add(new DataPoint(6.5, 94.5));
|
||||
series1.Points.Add(new DataPoint(7.5, 95.5));
|
||||
series1.Points.Add(new DataPoint(8.5, 95.7));
|
||||
series1.Points.Add(new DataPoint(9.5, 96.0));
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="TextAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("TextAnnotation"), Tags("Annotations")]
|
||||
public static class TextAnnotationExamples
|
||||
{
|
||||
[Example("TextAnnotation")]
|
||||
public static PlotModel TextAnnotations()
|
||||
{
|
||||
var model = new PlotModel { Title = "TextAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -15, Maximum = 25 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -5, Maximum = 18 });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(-6, 0), Text = "Text annotation 1" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(-7, 10), TextRotation = 80, Text = "Text annotation 2" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(2, 2), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Right, TextVerticalAlignment = VerticalAlignment.Top, Text = "Right/Top" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(2, 4), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Right, TextVerticalAlignment = VerticalAlignment.Middle, Text = "Right/Middle" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(2, 6), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Right, TextVerticalAlignment = VerticalAlignment.Bottom, Text = "Right/Bottom" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(10, 2), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Center, TextVerticalAlignment = VerticalAlignment.Top, Text = "Center/Top" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(10, 4), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Center, TextVerticalAlignment = VerticalAlignment.Middle, Text = "Center/Middle" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(10, 6), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Center, TextVerticalAlignment = VerticalAlignment.Bottom, Text = "Center/Bottom" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(18, 2), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Left, TextVerticalAlignment = VerticalAlignment.Top, Text = "Left/Top" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(18, 4), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Left, TextVerticalAlignment = VerticalAlignment.Middle, Text = "Left/Middle" });
|
||||
model.Annotations.Add(new TextAnnotation { TextPosition = new DataPoint(18, 6), TextRotation = 20, TextHorizontalAlignment = HorizontalAlignment.Left, TextVerticalAlignment = VerticalAlignment.Bottom, Text = "Left/Bottom" });
|
||||
|
||||
double d = 0.05;
|
||||
|
||||
Action<double, double> addPoint = (x, y) =>
|
||||
{
|
||||
var annotation = new PolygonAnnotation
|
||||
{
|
||||
Layer = AnnotationLayer.BelowAxes,
|
||||
};
|
||||
annotation.Points.AddRange(new[]
|
||||
{
|
||||
new DataPoint(x - d, y - d), new DataPoint(x + d, y - d), new DataPoint(x + d, y + d),
|
||||
new DataPoint(x - d, y + d), new DataPoint(x - d, y - d)
|
||||
});
|
||||
model.Annotations.Add(annotation);
|
||||
};
|
||||
|
||||
foreach (var a in model.Annotations.ToArray())
|
||||
{
|
||||
var ta = a as TextAnnotation;
|
||||
if (ta != null)
|
||||
{
|
||||
addPoint(ta.TextPosition.X, ta.TextPosition.Y);
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Rotations")]
|
||||
public static PlotModel Rotations()
|
||||
{
|
||||
var model = new PlotModel { Title = "TextAnnotation Rotations" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -5, Maximum = 45 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, StartPosition = 1, EndPosition = 0, Minimum = -1, Maximum = 8 });
|
||||
for (var i = 0; i < 360; i += 5)
|
||||
{
|
||||
model.Annotations.Add(new TextAnnotation
|
||||
{
|
||||
TextRotation = i,
|
||||
TextPosition = new DataPoint(i % 45, i / 45),
|
||||
Text = $"{i}°",
|
||||
TextVerticalAlignment = VerticalAlignment.Middle,
|
||||
TextHorizontalAlignment = HorizontalAlignment.Center
|
||||
});
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
407
Source/Examples/ExampleLibrary/Annotations/TileMapAnnotation.cs
Normal file
@@ -0,0 +1,407 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="TileMapAnnotation.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Provides an annotation that shows a tile based map.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
|
||||
/// <summary>
|
||||
/// Provides an annotation that shows a tile based map.
|
||||
/// </summary>
|
||||
/// <remarks>The longitude and latitude range of the map is defined by the range of the x and y axis, respectively.</remarks>
|
||||
public class TileMapAnnotation : Annotation
|
||||
{
|
||||
/// <summary>
|
||||
/// The image cache.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, OxyImage> images = new Dictionary<string, OxyImage>();
|
||||
|
||||
/// <summary>
|
||||
/// The download queue.
|
||||
/// </summary>
|
||||
private readonly Queue<string> queue = new Queue<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The current number of downloads
|
||||
/// </summary>
|
||||
private int numberOfDownloads;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TileMapAnnotation" /> class.
|
||||
/// </summary>
|
||||
public TileMapAnnotation()
|
||||
{
|
||||
this.TileSize = 256;
|
||||
this.MinZoomLevel = 0;
|
||||
this.MaxZoomLevel = 20;
|
||||
this.Opacity = 1.0;
|
||||
this.MaxNumberOfDownloads = 8;
|
||||
this.UserAgent = "OxyPlotExampleLibrary";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the max number of simultaneous downloads.
|
||||
/// </summary>
|
||||
/// <value>The max number of downloads.</value>
|
||||
public int MaxNumberOfDownloads { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URL.
|
||||
/// </summary>
|
||||
/// <value>The URL.</value>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the copyright notice.
|
||||
/// </summary>
|
||||
/// <value>The copyright notice.</value>
|
||||
public string CopyrightNotice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the tiles.
|
||||
/// </summary>
|
||||
/// <value>The size of the tiles.</value>
|
||||
public int TileSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the min zoom level.
|
||||
/// </summary>
|
||||
/// <value>The min zoom level.</value>
|
||||
public int MinZoomLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the max zoom level.
|
||||
/// </summary>
|
||||
/// <value>The max zoom level.</value>
|
||||
public int MaxZoomLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the opacity.
|
||||
/// </summary>
|
||||
/// <value>The opacity.</value>
|
||||
public double Opacity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user agent used for requests.
|
||||
/// </summary>
|
||||
public string UserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Renders the annotation on the specified context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The render context.</param>
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
var lon0 = this.XAxis.ActualMinimum;
|
||||
var lon1 = this.XAxis.ActualMaximum;
|
||||
var lat0 = this.YAxis.ActualMinimum;
|
||||
var lat1 = this.YAxis.ActualMaximum;
|
||||
|
||||
// the desired number of tiles horizontally
|
||||
double tilesx = this.PlotModel.Width / this.TileSize;
|
||||
|
||||
// calculate the desired zoom level
|
||||
var n = tilesx / (((lon1 + 180) / 360) - ((lon0 + 180) / 360));
|
||||
var zoom = (int)Math.Round(Math.Log(n) / Math.Log(2));
|
||||
if (zoom < this.MinZoomLevel)
|
||||
{
|
||||
zoom = this.MinZoomLevel;
|
||||
}
|
||||
|
||||
if (zoom > this.MaxZoomLevel)
|
||||
{
|
||||
zoom = this.MaxZoomLevel;
|
||||
}
|
||||
|
||||
// find tile coordinates for the corners
|
||||
double x0, y0;
|
||||
LatLonToTile(lat0, lon0, zoom, out x0, out y0);
|
||||
double x1, y1;
|
||||
LatLonToTile(lat1, lon1, zoom, out x1, out y1);
|
||||
|
||||
double xmax = Math.Max(x0, x1);
|
||||
double xmin = Math.Min(x0, x1);
|
||||
double ymax = Math.Max(y0, y1);
|
||||
double ymin = Math.Min(y0, y1);
|
||||
|
||||
var clippingRectangle = this.GetClippingRect();
|
||||
|
||||
// Add the tiles
|
||||
for (var x = (int)xmin; x < xmax; x++)
|
||||
{
|
||||
for (var y = (int)ymin; y < ymax; y++)
|
||||
{
|
||||
string uri = this.GetTileUri(x, y, zoom);
|
||||
var img = this.GetImage(uri, rc.RendersToScreen);
|
||||
|
||||
if (img == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// transform from tile coordinates to lat/lon
|
||||
double latitude0, latitude1, longitude0, longitude1;
|
||||
TileToLatLon(x, y, zoom, out latitude0, out longitude0);
|
||||
TileToLatLon(x + 1, y + 1, zoom, out latitude1, out longitude1);
|
||||
|
||||
// transform from lat/lon to screen coordinates
|
||||
var s00 = this.Transform(longitude0, latitude0);
|
||||
var s11 = this.Transform(longitude1, latitude1);
|
||||
|
||||
var r = OxyRect.Create(s00.X, s00.Y, s11.X, s11.Y);
|
||||
|
||||
// draw the image
|
||||
rc.DrawImage(img, r.Left, r.Top, r.Width, r.Height, this.Opacity, true);
|
||||
}
|
||||
}
|
||||
|
||||
// draw the copyright notice
|
||||
var p = new ScreenPoint(clippingRectangle.Right - 5, clippingRectangle.Bottom - 5);
|
||||
var textSize = rc.MeasureText(this.CopyrightNotice, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
|
||||
rc.DrawRectangle(
|
||||
new OxyRect(p.X - textSize.Width - 2, p.Y - textSize.Height - 2, textSize.Width + 4, textSize.Height + 4),
|
||||
OxyColor.FromAColor(200, OxyColors.White),
|
||||
OxyColors.Undefined,
|
||||
0,
|
||||
this.EdgeRenderingMode);
|
||||
|
||||
rc.DrawText(
|
||||
p,
|
||||
this.CopyrightNotice,
|
||||
OxyColors.Black,
|
||||
this.ActualFont,
|
||||
this.ActualFontSize,
|
||||
this.ActualFontWeight,
|
||||
0,
|
||||
HorizontalAlignment.Right,
|
||||
VerticalAlignment.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a position to a tile coordinate.
|
||||
/// </summary>
|
||||
/// <param name="latitude">The latitude.</param>
|
||||
/// <param name="longitude">The longitude.</param>
|
||||
/// <param name="zoom">The zoom.</param>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
private static void LatLonToTile(double latitude, double longitude, int zoom, out double x, out double y)
|
||||
{
|
||||
// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
||||
int n = 1 << zoom;
|
||||
double lat = latitude / 180 * Math.PI;
|
||||
x = (longitude + 180.0) / 360.0 * n;
|
||||
y = (1.0 - (Math.Log(Math.Tan(lat) + (1.0 / Math.Cos(lat))) / Math.PI)) / 2.0 * n;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a tile coordinate (x,y) to a position.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="zoom">The zoom.</param>
|
||||
/// <param name="latitude">The latitude.</param>
|
||||
/// <param name="longitude">The longitude.</param>
|
||||
private static void TileToLatLon(double x, double y, int zoom, out double latitude, out double longitude)
|
||||
{
|
||||
int n = 1 << zoom;
|
||||
longitude = (x / n * 360.0) - 180.0;
|
||||
double lat = Math.Atan(Math.Sinh(Math.PI * (1 - (2 * y / n))));
|
||||
latitude = lat * 180.0 / Math.PI;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image from the specified uri.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI.</param>
|
||||
/// <param name="asyncLoading">Get the image asynchronously if set to <c>true</c>. The plot model will be invalidated when the image has been downloaded.</param>
|
||||
/// <returns>The image.</returns>
|
||||
/// <remarks>This method gets the image from cache, or starts an async download.</remarks>
|
||||
private OxyImage GetImage(string uri, bool asyncLoading)
|
||||
{
|
||||
OxyImage img;
|
||||
if (this.images.TryGetValue(uri, out img))
|
||||
{
|
||||
return img;
|
||||
}
|
||||
|
||||
if (!asyncLoading)
|
||||
{
|
||||
return this.Download(uri);
|
||||
}
|
||||
|
||||
lock (this.queue)
|
||||
{
|
||||
// 'reserve' an image (otherwise multiple downloads of the same uri may happen)
|
||||
this.images[uri] = null;
|
||||
this.queue.Enqueue(uri);
|
||||
}
|
||||
|
||||
this.BeginDownload();
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads the image from the specified URI.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI.</param>
|
||||
/// <returns>The image</returns>
|
||||
private OxyImage Download(string uri)
|
||||
{
|
||||
OxyImage img = null;
|
||||
var mre = new ManualResetEvent(false);
|
||||
var request = (HttpWebRequest)WebRequest.Create(uri);
|
||||
request.Method = "GET";
|
||||
request.BeginGetResponse(
|
||||
r =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (request.HaveResponse)
|
||||
{
|
||||
var response = request.EndGetResponse(r);
|
||||
var stream = response.GetResponseStream();
|
||||
|
||||
var ms = new MemoryStream();
|
||||
stream.CopyTo(ms);
|
||||
var buffer = ms.ToArray();
|
||||
|
||||
img = new OxyImage(buffer);
|
||||
this.images[uri] = img;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var ie = e;
|
||||
while (ie != null)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ie.Message);
|
||||
ie = ie.InnerException;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
mre.Set();
|
||||
}
|
||||
},
|
||||
request);
|
||||
|
||||
mre.WaitOne();
|
||||
return img;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the next download in the queue.
|
||||
/// </summary>
|
||||
private void BeginDownload()
|
||||
{
|
||||
if (this.numberOfDownloads >= this.MaxNumberOfDownloads)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string uri = this.queue.Dequeue();
|
||||
var request = (HttpWebRequest)WebRequest.Create(uri);
|
||||
request.Method = "GET";
|
||||
|
||||
#if NETFRAMEWORK
|
||||
// unavailable in NET Standard 1.0
|
||||
request.UserAgent = this.UserAgent;
|
||||
#else
|
||||
// compiles but does not run under NET Framework
|
||||
request.Headers["User-Agent"] = this.UserAgent;
|
||||
#endif
|
||||
|
||||
Interlocked.Increment(ref this.numberOfDownloads);
|
||||
request.BeginGetResponse(
|
||||
r =>
|
||||
{
|
||||
Interlocked.Decrement(ref this.numberOfDownloads);
|
||||
try
|
||||
{
|
||||
if (request.HaveResponse)
|
||||
{
|
||||
var response = request.EndGetResponse(r);
|
||||
var stream = response.GetResponseStream();
|
||||
this.DownloadCompleted(uri, stream);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var ie = e;
|
||||
while (ie != null)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ie.Message);
|
||||
ie = ie.InnerException;
|
||||
}
|
||||
}
|
||||
},
|
||||
request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The download completed, set the image.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI.</param>
|
||||
/// <param name="result">The result.</param>
|
||||
private void DownloadCompleted(string uri, Stream result)
|
||||
{
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ms = new MemoryStream();
|
||||
result.CopyTo(ms);
|
||||
var buffer = ms.ToArray();
|
||||
|
||||
var img = new OxyImage(buffer);
|
||||
this.images[uri] = img;
|
||||
|
||||
lock (this.queue)
|
||||
{
|
||||
// Clear old items in the queue, new ones will be added when the plot is refreshed
|
||||
foreach (var queuedUri in this.queue)
|
||||
{
|
||||
// Remove the 'reserved' image
|
||||
this.images.Remove(queuedUri);
|
||||
}
|
||||
|
||||
this.queue.Clear();
|
||||
}
|
||||
|
||||
this.PlotModel.InvalidatePlot(false);
|
||||
if (this.queue.Count > 0)
|
||||
{
|
||||
this.BeginDownload();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tile URI.
|
||||
/// </summary>
|
||||
/// <param name="x">The tile x.</param>
|
||||
/// <param name="y">The tile y.</param>
|
||||
/// <param name="zoom">The zoom.</param>
|
||||
/// <returns>The uri.</returns>
|
||||
private string GetTileUri(int x, int y, int zoom)
|
||||
{
|
||||
string url = this.Url.Replace("{X}", x.ToString(CultureInfo.InvariantCulture));
|
||||
url = url.Replace("{Y}", y.ToString(CultureInfo.InvariantCulture));
|
||||
return url.Replace("{Z}", zoom.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="TileMapAnnotationExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("TileMapAnnotation"), Tags("Annotations")]
|
||||
public static class TileMapAnnotationExamples
|
||||
{
|
||||
[Example("TileMapAnnotation (openstreetmap.org)", true)]
|
||||
public static PlotModel TileMapAnnotation2()
|
||||
{
|
||||
// See policy document: https://operations.osmfoundation.org/policies/tiles/
|
||||
|
||||
var model = new PlotModel { Title = "TileMapAnnotation" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 10.4, Maximum = 10.6, Title = "Longitude" });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 59.88, Maximum = 59.96, Title = "Latitude" });
|
||||
|
||||
// Add the tile map annotation
|
||||
model.Annotations.Add(
|
||||
new TileMapAnnotation
|
||||
{
|
||||
Url = "http://tile.openstreetmap.org/{Z}/{X}/{Y}.png",
|
||||
CopyrightNotice = "OpenStreetMap",
|
||||
MaxNumberOfDownloads = 2,
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TileMapAnnotation (statkart.no)", true)]
|
||||
public static PlotModel TileMapAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "TileMapAnnotation" };
|
||||
|
||||
// TODO: scale ratio between the two axes should be fixed (or depending on latitude...)
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 10.4, Maximum = 10.6, Title = "Longitude" });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 59.88, Maximum = 59.96, Title = "Latitude" });
|
||||
|
||||
// Add the tile map annotation
|
||||
model.Annotations.Add(
|
||||
new TileMapAnnotation
|
||||
{
|
||||
Url = "http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=toporaster3&zoom={Z}&x={X}&y={Y}",
|
||||
CopyrightNotice = "Kartgrunnlag: Statens kartverk, Geovekst og kommuner.",
|
||||
MinZoomLevel = 5,
|
||||
MaxZoomLevel = 19
|
||||
});
|
||||
|
||||
model.Annotations.Add(new ArrowAnnotation
|
||||
{
|
||||
EndPoint = new DataPoint(10.563, 59.888),
|
||||
ArrowDirection = new ScreenVector(-40, -60),
|
||||
StrokeThickness = 3,
|
||||
FontSize = 20,
|
||||
FontWeight = FontWeights.Bold,
|
||||
TextColor = OxyColor.FromAColor(160, OxyColors.Magenta),
|
||||
Color = OxyColor.FromAColor(100, OxyColors.Magenta)
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks the model as documentation example to be exported by the ExampleGenerator program.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class DocumentationExampleAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename of the documentation file without extension. For sub folders, use '/' as path delimiter.</param>
|
||||
public DocumentationExampleAttribute(string filename)
|
||||
{
|
||||
this.Filename = filename;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filename.
|
||||
/// </summary>
|
||||
/// <value>The filename.</value>
|
||||
/// <remarks>
|
||||
/// For sub folders, use '/' as path delimiter.
|
||||
/// This is then replaced with the current platforms path separator later in the process.
|
||||
/// </remarks>
|
||||
public string Filename { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ExampleAttribute.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the title for an example.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ExampleAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExampleAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="title">The title.</param>
|
||||
/// <param name="excludeFromAutomatedTests">A value indiciating whether the example should be excluded from automated tests.</param>
|
||||
public ExampleAttribute(string title = null, bool excludeFromAutomatedTests = false)
|
||||
{
|
||||
this.Title = title;
|
||||
this.ExcludeFromAutomatedTests = excludeFromAutomatedTests;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the title.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The title.
|
||||
/// </value>
|
||||
public string Title { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indiciating whether this example should be excluded from automated tests.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the example should be excluded from automated tests, otherwise <c>false</c>.
|
||||
/// </value>
|
||||
public bool ExcludeFromAutomatedTests { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ExamplesAttribute.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the category for a class containing examples.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ExamplesAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExamplesAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="category">The category.</param>
|
||||
public ExamplesAttribute(string category = null)
|
||||
{
|
||||
this.Category = category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the category.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The category.
|
||||
/// </value>
|
||||
public string Category { get; private set; }
|
||||
}
|
||||
}
|
||||
34
Source/Examples/ExampleLibrary/Attributes/TagsAttribute.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="TagsAttribute.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies tags.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class TagsAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TagsAttribute" /> class.
|
||||
/// </summary>
|
||||
/// <param name="tags">The tags.</param>
|
||||
public TagsAttribute(params string[] tags)
|
||||
{
|
||||
this.Tags = tags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tags.
|
||||
/// </value>
|
||||
public string[] Tags { get; private set; }
|
||||
}
|
||||
}
|
||||
1951
Source/Examples/ExampleLibrary/Axes/AxisExamples.cs
Normal file
151
Source/Examples/ExampleLibrary/Axes/CartesianAxesExamples.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CartesianAxesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("Cartesian axes"), Tags("Axes")]
|
||||
public class CartesianAxesExamples
|
||||
{
|
||||
[Example("Trigonometric functions")]
|
||||
public static PlotModel FunctionSeries()
|
||||
{
|
||||
var pm = new PlotModel { Title = "Trigonometric functions", PlotType = PlotType.Cartesian };
|
||||
pm.Series.Add(new FunctionSeries(Math.Sin, -10, 10, 0.1, "sin(x)"));
|
||||
pm.Series.Add(new FunctionSeries(Math.Cos, -10, 10, 0.1, "cos(x)"));
|
||||
pm.Series.Add(new FunctionSeries(t => 5 * Math.Cos(t), t => 5 * Math.Sin(t), 0, 2 * Math.PI, 1000, "cos(t),sin(t)"));
|
||||
return pm;
|
||||
}
|
||||
|
||||
[Example("Clover")]
|
||||
public static PlotModel Clover()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Parametric function", PlotType = PlotType.Cartesian };
|
||||
plot.Series.Add(new FunctionSeries(t => 2 * Math.Cos(2 * t) * Math.Cos(t), t => 2 * Math.Cos(2 * t) * Math.Sin(t),
|
||||
0, Math.PI * 2, 1000, "2cos(2t)cos(t) , 2cos(2t)sin(t)"));
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("AbsoluteMinimum Y")]
|
||||
public static PlotModel AbsoluteYmin()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Y: AbsoluteMinimum = 0", PlotType = PlotType.Cartesian };
|
||||
var c = OxyColors.DarkBlue;
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "X-axis", MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Y-axis", AbsoluteMinimum = 0, Minimum = 0, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Series.Add(CreateTestSeries());
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("AbsoluteMinimum Y, manual plotmargins")]
|
||||
public static PlotModel AbsoluteYmin2()
|
||||
{
|
||||
var plot = new PlotModel
|
||||
{
|
||||
Title = "Y: AbsoluteMinimum = 0",
|
||||
Subtitle = "AutoAdjustPlotMargins = false",
|
||||
PlotType = PlotType.Cartesian,
|
||||
PlotMargins = new OxyThickness(60, 4, 4, 40)
|
||||
};
|
||||
var c = OxyColors.DarkBlue;
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "X-axis", MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Y-axis", AbsoluteMinimum = 0, Minimum = 0, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Series.Add(CreateTestSeries());
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("AbsoluteMinimum X/Y")]
|
||||
public static PlotModel AbsoluteYminXmin()
|
||||
{
|
||||
var plot = new PlotModel { Title = "X: AbsoluteMinimum = -10, Y: AbsoluteMinimum = 0", PlotType = PlotType.Cartesian };
|
||||
|
||||
var c = OxyColors.DarkBlue;
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "X-axis", AbsoluteMinimum = -10, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Y-axis", AbsoluteMinimum = 0, Minimum = 0, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Series.Add(CreateTestSeries());
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("AbsoluteMinimum/Maximum Y")]
|
||||
public static PlotModel AbsoluteYminYmax()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Y: AbsoluteMinimum = 0, AbsoluteMaximum = 2", PlotType = PlotType.Cartesian };
|
||||
|
||||
var c = OxyColors.DarkBlue;
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "X-axis", MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Y-axis", AbsoluteMinimum = 0, Minimum = 0, AbsoluteMaximum = 2, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Series.Add(CreateTestSeries());
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("AbsoluteMinimum Y, AbsoluteMinimum/Maximum X")]
|
||||
public static PlotModel AbsoluteYminXminXmax()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Y: AbsoluteMinimum = 0, X: AbsoluteMinimum = -10, AbsoluteMaximum = 10", PlotType = PlotType.Cartesian };
|
||||
|
||||
var c = OxyColors.DarkBlue;
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "X-axis", AbsoluteMinimum = -10, AbsoluteMaximum = 10, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Y-axis", AbsoluteMinimum = 0, Minimum = 0, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Series.Add(CreateTestSeries());
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("AbsoluteMinimum/Maximum X/Y")]
|
||||
public static PlotModel AbsoluteYminYmaxXminXmax()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Y: AbsoluteMinimum = 0, AbsoluteMaximum = 2, X: AbsoluteMinimum = -10, AbsoluteMaximum = 10", PlotType = PlotType.Cartesian };
|
||||
|
||||
var c = OxyColors.DarkBlue;
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "X-axis", AbsoluteMinimum = -10, AbsoluteMaximum = 10, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Y-axis", AbsoluteMinimum = 0, Minimum = 0, AbsoluteMaximum = 2, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.FromAColor(40, c), MinorGridlineColor = OxyColor.FromAColor(20, c) });
|
||||
plot.Series.Add(CreateTestSeries());
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
private static OxyPlot.Series.Series CreateTestSeries()
|
||||
{
|
||||
var absSerie = new LineSeries();
|
||||
|
||||
absSerie.Points.Add(new DataPoint(-8.0, 0.0));
|
||||
absSerie.Points.Add(new DataPoint(-7.5, 0.1));
|
||||
absSerie.Points.Add(new DataPoint(-7.0, 0.2));
|
||||
absSerie.Points.Add(new DataPoint(-6.0, 0.4));
|
||||
absSerie.Points.Add(new DataPoint(-5.0, 0.5));
|
||||
absSerie.Points.Add(new DataPoint(-4.0, 0.6));
|
||||
absSerie.Points.Add(new DataPoint(-3.0, 0.7));
|
||||
absSerie.Points.Add(new DataPoint(-2.0, 0.8));
|
||||
absSerie.Points.Add(new DataPoint(-1.0, 0.9));
|
||||
absSerie.Points.Add(new DataPoint(0.0, 1.0));
|
||||
absSerie.Points.Add(new DataPoint(1.0, 0.9));
|
||||
absSerie.Points.Add(new DataPoint(2.0, 0.8));
|
||||
absSerie.Points.Add(new DataPoint(3.0, 0.7));
|
||||
absSerie.Points.Add(new DataPoint(4.0, 0.6));
|
||||
absSerie.Points.Add(new DataPoint(5.0, 0.5));
|
||||
absSerie.Points.Add(new DataPoint(6.0, 0.4));
|
||||
absSerie.Points.Add(new DataPoint(7.0, 0.2));
|
||||
absSerie.Points.Add(new DataPoint(7.5, 0.1));
|
||||
absSerie.Points.Add(new DataPoint(8.0, 0.0));
|
||||
|
||||
absSerie.Points.Add(DataPoint.Undefined);
|
||||
|
||||
// Plot a square
|
||||
absSerie.Points.Add(new DataPoint(-0.5, 0.5));
|
||||
absSerie.Points.Add(new DataPoint(-0.5, 1.5));
|
||||
absSerie.Points.Add(new DataPoint(0.5, 1.5));
|
||||
absSerie.Points.Add(new DataPoint(0.5, 0.5));
|
||||
absSerie.Points.Add(new DataPoint(-0.5, 0.5));
|
||||
|
||||
return absSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Source/Examples/ExampleLibrary/Axes/CategoryAxisExamples.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CategoryAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("CategoryAxis"), Tags("Axes")]
|
||||
public static class CategoryAxisExamples
|
||||
{
|
||||
[Example("Standard")]
|
||||
public static PlotModel StandardCategoryAxis()
|
||||
{
|
||||
var plotModel1 = new PlotModel { Title = "Standard" };
|
||||
var catAxis = new CategoryAxis();
|
||||
catAxis.Labels.AddRange(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
|
||||
plotModel1.Axes.Add(catAxis);
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
plotModel1.Axes.Add(linearAxis);
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
[Example("ItemsSource - string[]")]
|
||||
public static PlotModel ItemsSourceStrings()
|
||||
{
|
||||
var model = new PlotModel { Title = "CategoryAxis with string[] as ItemsSource" };
|
||||
model.Axes.Add(new CategoryAxis
|
||||
{
|
||||
StringFormat = "Item {0}",
|
||||
ItemsSource = new[] { "A", "B", "C" }
|
||||
});
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
model.Axes.Add(linearAxis);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ItemsSource - int[]")]
|
||||
public static PlotModel ItemsSourceValues()
|
||||
{
|
||||
var model = new PlotModel { Title = "CategoryAxis with int[] as ItemsSource" };
|
||||
model.Axes.Add(new CategoryAxis
|
||||
{
|
||||
StringFormat = "Item {0}",
|
||||
ItemsSource = new[] { 10, 100, 123 }
|
||||
});
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
model.Axes.Add(linearAxis);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("MajorStep")]
|
||||
public static PlotModel MajorStepCategoryAxis()
|
||||
{
|
||||
var plotModel1 = new PlotModel { Title = "Major Step = 4, IsTickCentered = false" };
|
||||
var catAxis = new CategoryAxis { IsTickCentered = false, MajorStep = 4 };
|
||||
catAxis.Labels.AddRange(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
|
||||
plotModel1.Axes.Add(catAxis);
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
plotModel1.Axes.Add(linearAxis);
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
[Example("MajorStep, TickCentered")]
|
||||
public static PlotModel MajorStepCategoryTickCenteredAxis()
|
||||
{
|
||||
var plotModel1 = new PlotModel { Title = "Major Step = 4, IsTickCentered = true" };
|
||||
var catAxis = new CategoryAxis { IsTickCentered = true, MajorStep = 4 };
|
||||
catAxis.Labels.AddRange(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
|
||||
plotModel1.Axes.Add(catAxis);
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
plotModel1.Axes.Add(linearAxis);
|
||||
return plotModel1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CategoryColorAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("CategoryColorAxis"), Tags("Axes")]
|
||||
public class CategoryColorAxisExamples
|
||||
{
|
||||
[Example("CategoryColorAxis")]
|
||||
public static PlotModel StandardCategoryColorAxis()
|
||||
{
|
||||
var plotModel1 = new PlotModel { Title = "CategoryColorAxis" };
|
||||
var catAxis = new CategoryColorAxis { Key = "ccc", Palette = OxyPalettes.BlackWhiteRed(12) };
|
||||
catAxis.Labels.AddRange(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
|
||||
plotModel1.Axes.Add(catAxis);
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
var ss = new ScatterSeries { ColorAxisKey = catAxis.Key };
|
||||
ss.Points.Add(new ScatterPoint(0, 0) { Value = 0 });
|
||||
ss.Points.Add(new ScatterPoint(3, 0) { Value = 3 });
|
||||
plotModel1.Series.Add(ss);
|
||||
plotModel1.Axes.Add(linearAxis);
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
[Example("Centered ticks, MajorStep = 4")]
|
||||
public static PlotModel MajorStep4()
|
||||
{
|
||||
var plotModel1 = new PlotModel { Title = "Major Step = 4, IsTickCentered = true" };
|
||||
var catAxis = new CategoryColorAxis
|
||||
{
|
||||
Palette = OxyPalettes.BlackWhiteRed(3),
|
||||
IsTickCentered = true,
|
||||
MajorStep = 4
|
||||
};
|
||||
catAxis.Labels.AddRange(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" });
|
||||
plotModel1.Axes.Add(catAxis);
|
||||
var linearAxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
plotModel1.Axes.Add(linearAxis);
|
||||
return plotModel1;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Source/Examples/ExampleLibrary/Axes/CustomAxisExamples.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CustomAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("Custom axes"), Tags("Axes")]
|
||||
public static class CustomAxisExamples
|
||||
{
|
||||
public class ArrowAxis : LinearAxis
|
||||
{
|
||||
public override void Render(IRenderContext rc, int pass)
|
||||
{
|
||||
base.Render(rc, pass);
|
||||
var points = new List<ScreenPoint>();
|
||||
if (this.IsHorizontal())
|
||||
{
|
||||
var xmax = this.Transform(this.ActualMaximum);
|
||||
points.Add(new ScreenPoint(xmax + 4, this.PlotModel.PlotArea.Bottom - 4));
|
||||
points.Add(new ScreenPoint(xmax + 18, this.PlotModel.PlotArea.Bottom));
|
||||
points.Add(new ScreenPoint(xmax + 4, this.PlotModel.PlotArea.Bottom + 4));
|
||||
//// etc.
|
||||
}
|
||||
else
|
||||
{
|
||||
var ymax = this.Transform(this.ActualMaximum);
|
||||
points.Add(new ScreenPoint(this.PlotModel.PlotArea.Left - 4, ymax - 4));
|
||||
points.Add(new ScreenPoint(this.PlotModel.PlotArea.Left, ymax - 18));
|
||||
points.Add(new ScreenPoint(this.PlotModel.PlotArea.Left + 4, ymax - 4));
|
||||
//// etc.
|
||||
}
|
||||
|
||||
rc.DrawPolygon(points, OxyColors.Black, OxyColors.Undefined, 0, this.EdgeRenderingMode);
|
||||
}
|
||||
}
|
||||
|
||||
[Example("ArrowAxis")]
|
||||
public static PlotModel CustomArrowAxis()
|
||||
{
|
||||
var model = new PlotModel { PlotAreaBorderThickness = new OxyThickness(0), PlotMargins = new OxyThickness(60, 60, 60, 60) };
|
||||
model.Axes.Add(new ArrowAxis { Position = AxisPosition.Bottom, AxislineStyle = LineStyle.Solid });
|
||||
model.Axes.Add(new ArrowAxis { Position = AxisPosition.Left, AxislineStyle = LineStyle.Solid });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
248
Source/Examples/ExampleLibrary/Axes/DateTimeAxisExamples.cs
Normal file
@@ -0,0 +1,248 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DateTimeAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("DateTimeAxis"), Tags("Axes")]
|
||||
public static class DateTimeAxisExamples
|
||||
{
|
||||
public class DateValue
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public double Value { get; set; }
|
||||
}
|
||||
|
||||
[Example("Default StringFormat")]
|
||||
public static PlotModel DefaultValues()
|
||||
{
|
||||
return CreateExample(7, null);
|
||||
}
|
||||
|
||||
[Example("StringFormat 'MMM dd\\nyyyy'")]
|
||||
public static PlotModel StringFormat()
|
||||
{
|
||||
return CreateExample(7, "MMM dd\nyyyy");
|
||||
}
|
||||
|
||||
private static PlotModel CreateExample(int days, string stringFormat)
|
||||
{
|
||||
var m = new PlotModel();
|
||||
var startTime = new DateTime(2000, 1, 1);
|
||||
var min = DateTimeAxis.ToDouble(startTime);
|
||||
var max = min + days;
|
||||
m.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom, Minimum = min, Maximum = max, StringFormat = stringFormat });
|
||||
m.Axes.Add(new DateTimeAxis { Position = AxisPosition.Left, Minimum = min, Maximum = max, StringFormat = stringFormat });
|
||||
return m;
|
||||
}
|
||||
|
||||
// [Example("DateTime Minimum bug")]
|
||||
public static PlotModel Example1()
|
||||
{
|
||||
var tmp = new PlotModel { Title = "Test" };
|
||||
tmp.Axes.Add(new LinearAxis { Position = AxisPosition.Left, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Dot, TickStyle = TickStyle.Outside });
|
||||
var dt = new DateTime(2010, 1, 1);
|
||||
tmp.Axes.Add(new DateTimeAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
Minimum = DateTimeAxis.ToDouble(dt),
|
||||
Maximum = DateTimeAxis.ToDouble(dt.AddDays(1)),
|
||||
IntervalType = DateTimeIntervalType.Hours,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
Angle = 90,
|
||||
StringFormat = "HH:mm",
|
||||
MajorStep = 1.0 / 24 / 2, // 1/24 = 1 hour, 1/24/2 = 30 minutes
|
||||
IsZoomEnabled = true,
|
||||
MaximumPadding = 0,
|
||||
MinimumPadding = 0,
|
||||
TickStyle = TickStyle.None
|
||||
});
|
||||
|
||||
var ls = new LineSeries { Title = "Line1", DataFieldX = "X", DataFieldY = "Y" };
|
||||
var ii = new List<Item>();
|
||||
|
||||
for (int i = 0; i < 24; i++)
|
||||
ii.Add(new Item { X = dt.AddHours(i), Y = i * i });
|
||||
ls.ItemsSource = ii;
|
||||
tmp.Series.Add(ls);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
[Example("TimeZone adjustments")]
|
||||
public static PlotModel DaylightSavingsBreak()
|
||||
{
|
||||
var m = new PlotModel();
|
||||
|
||||
var xa = new DateTimeAxis { Position = AxisPosition.Bottom };
|
||||
// TimeZone not available in PCL...
|
||||
|
||||
m.Axes.Add(xa);
|
||||
m.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
var ls = new LineSeries { MarkerType = MarkerType.Circle };
|
||||
m.Series.Add(ls);
|
||||
|
||||
// set the origin of the curve to 2013-03-31 00:00:00 (UTC)
|
||||
var o = new DateTime(2013, 3, 31, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
// add points at 10min intervals
|
||||
// at 2am the clocks are turned forward 1 hour (W. Europe Standard Time)
|
||||
for (int i = 0; i < 400; i += 10)
|
||||
{
|
||||
var time = o.AddMinutes(i);
|
||||
ls.Points.Add(DateTimeAxis.CreateDataPoint(time, i));
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
public class Item
|
||||
{
|
||||
public DateTime X { get; set; }
|
||||
public double Y { get; set; }
|
||||
}
|
||||
|
||||
[Example("DateTime axis")]
|
||||
public static PlotModel DateTimeaxisPlotModel()
|
||||
{
|
||||
var start = new DateTime(2010, 01, 01);
|
||||
var end = new DateTime(2015, 01, 01);
|
||||
double increment = 3600 * 24 * 14;
|
||||
|
||||
// Create a random data collection
|
||||
var r = new Random(13);
|
||||
var data = new Collection<DateValue>();
|
||||
var date = start;
|
||||
while (date <= end)
|
||||
{
|
||||
data.Add(new DateValue { Date = date, Value = r.NextDouble() });
|
||||
date = date.AddSeconds(increment);
|
||||
}
|
||||
|
||||
var plotModel1 = new PlotModel { Title = "DateTime axis" };
|
||||
var dateTimeAxis1 = new DateTimeAxis
|
||||
{
|
||||
CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek,
|
||||
FirstDayOfWeek = DayOfWeek.Monday,
|
||||
Position = AxisPosition.Bottom
|
||||
};
|
||||
plotModel1.Axes.Add(dateTimeAxis1);
|
||||
var linearAxis1 = new LinearAxis();
|
||||
plotModel1.Axes.Add(linearAxis1);
|
||||
var lineSeries1 = new LineSeries
|
||||
{
|
||||
Color = OxyColor.FromArgb(255, 78, 154, 6),
|
||||
MarkerFill = OxyColor.FromArgb(255, 78, 154, 6),
|
||||
MarkerStroke = OxyColors.ForestGreen,
|
||||
MarkerType = MarkerType.Plus,
|
||||
StrokeThickness = 1,
|
||||
DataFieldX = "Date",
|
||||
DataFieldY = "Value",
|
||||
ItemsSource = data
|
||||
};
|
||||
plotModel1.Series.Add(lineSeries1);
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
public class SunItem
|
||||
{
|
||||
public DateTime Day { get; set; }
|
||||
public TimeSpan Sunrise { get; set; }
|
||||
public TimeSpan Sunset { get; set; }
|
||||
}
|
||||
|
||||
private static Collection<SunItem> CreateSunData(int year, double lat, double lon, Func<DateTime, DateTime> utcToLocalTime)
|
||||
{
|
||||
var data = new Collection<SunItem>();
|
||||
var day = new DateTime(year, 1, 1);
|
||||
|
||||
while (day.Year == year)
|
||||
{
|
||||
var sunrise = Sun.Calculate(day, lat, lon, true, utcToLocalTime);
|
||||
var sunset = Sun.Calculate(day, lat, lon, false, utcToLocalTime);
|
||||
data.Add(new SunItem { Day = day, Sunrise = sunrise - day, Sunset = sunset - day });
|
||||
day = day.AddDays(1);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static bool IsDaylightSaving(DateTime time)
|
||||
{
|
||||
// Daylight saving starts last sunday in March and ends last sunday in October
|
||||
// http://en.wikipedia.org/wiki/Daylight_saving_time
|
||||
var start = new DateTime(time.Year, 3, 31, 2, 0, 0);
|
||||
start = start.AddDays(-(int)start.DayOfWeek);
|
||||
var end = new DateTime(time.Year, 10, 31, 3, 0, 0);
|
||||
end = end.AddDays(-(int)end.DayOfWeek);
|
||||
return time >= start && time <= end;
|
||||
}
|
||||
|
||||
[Example("Sunrise and sunset in Oslo")]
|
||||
public static PlotModel SunriseandsunsetinOslo()
|
||||
{
|
||||
int year = DateTime.Now.Year;
|
||||
|
||||
// Convert UTC time to Western European Time (WET)
|
||||
Func<DateTime, DateTime> utcToLocalTime = utc => utc.AddHours(IsDaylightSaving(utc) ? 2 : 1);
|
||||
|
||||
var sunData = CreateSunData(year, 59.91, 10.75, utcToLocalTime);
|
||||
|
||||
var plotModel1 = new PlotModel { Title = "Sunrise and sunset in Oslo", Subtitle = "UTC time" };
|
||||
|
||||
var dateTimeAxis1 = new DateTimeAxis
|
||||
{
|
||||
CalendarWeekRule = CalendarWeekRule.FirstFourDayWeek,
|
||||
FirstDayOfWeek = DayOfWeek.Monday,
|
||||
IntervalType = DateTimeIntervalType.Months,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
Position = AxisPosition.Bottom,
|
||||
StringFormat = "MMM"
|
||||
};
|
||||
plotModel1.Axes.Add(dateTimeAxis1);
|
||||
var timeSpanAxis1 = new TimeSpanAxis { MajorGridlineStyle = LineStyle.Solid, Maximum = 86400, Minimum = 0, StringFormat = "h:mm" };
|
||||
plotModel1.Axes.Add(timeSpanAxis1);
|
||||
var areaSeries1 = new AreaSeries
|
||||
{
|
||||
ItemsSource = sunData,
|
||||
DataFieldX = "Day",
|
||||
DataFieldY = "Sunrise",
|
||||
DataFieldX2 = "Day",
|
||||
DataFieldY2 = "Sunset",
|
||||
Fill = OxyColor.FromArgb(128, 255, 255, 0),
|
||||
Color = OxyColors.Black
|
||||
};
|
||||
plotModel1.Series.Add(areaSeries1);
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
[Example("LabelFormatter")]
|
||||
public static PlotModel LabelFormatter()
|
||||
{
|
||||
var model = new PlotModel { Title = "Using LabelFormatter to format labels by day of week" };
|
||||
model.Axes.Add(new DateTimeAxis { LabelFormatter = x => DateTimeAxis.ToDateTime(x).DayOfWeek.ToString().Substring(0, 3) });
|
||||
var series = new LineSeries();
|
||||
model.Series.Add(series);
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
var time = new DateTime(2014, 9, 10).AddDays(i);
|
||||
double x = DateTimeAxis.ToDouble(time);
|
||||
double y = Math.Sin(i * i);
|
||||
series.Points.Add(new DataPoint(x, y));
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
141
Source/Examples/ExampleLibrary/Axes/LinearAxisExamples.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LinearAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("LinearAxis"), Tags("Axes")]
|
||||
public static class LinearAxisExamples
|
||||
{
|
||||
[Example("Default StringFormat ('g6')")]
|
||||
public static PlotModel StringFormat()
|
||||
{
|
||||
return CreateExample(1.2345678901234567890e5, 1.2345678901234567890e6, null);
|
||||
}
|
||||
|
||||
[Example("StringFormat = 'g2'")]
|
||||
public static PlotModel StringFormatG2()
|
||||
{
|
||||
return CreateExample(1.2345678901234567890e5, 1.2345678901234567890e6, "g2");
|
||||
}
|
||||
|
||||
[Example("StringFormat = 'g10'")]
|
||||
public static PlotModel StringFormatG10()
|
||||
{
|
||||
return CreateExample(1.2345678901234567890e5, 1.2345678901234567890e6, "g10");
|
||||
}
|
||||
|
||||
[Example("StringFormat = 'f2'")]
|
||||
public static PlotModel StringFormatF2()
|
||||
{
|
||||
return CreateExample(1.2345678901234567890e5, 1.2345678901234567890e6, "f2");
|
||||
}
|
||||
|
||||
private static PlotModel CreateExample(double min, double max, string stringFormat)
|
||||
{
|
||||
var m = new PlotModel();
|
||||
m.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = min, Maximum = max, StringFormat = stringFormat });
|
||||
m.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = min, Maximum = max, StringFormat = stringFormat });
|
||||
return m;
|
||||
}
|
||||
|
||||
[Example("TickStyle: None")]
|
||||
public static PlotModel TickStyleNone()
|
||||
{
|
||||
return CreateTickStyleModel(TickStyle.None);
|
||||
}
|
||||
|
||||
[Example("TickStyle: Crossing")]
|
||||
public static PlotModel TickStyleCrossing()
|
||||
{
|
||||
return CreateTickStyleModel(TickStyle.Crossing);
|
||||
}
|
||||
|
||||
[Example("TickStyle: Inside")]
|
||||
public static PlotModel TickStyleInside()
|
||||
{
|
||||
return CreateTickStyleModel(TickStyle.Inside);
|
||||
}
|
||||
|
||||
[Example("TickStyle: Outside")]
|
||||
public static PlotModel TickStyleOutside()
|
||||
{
|
||||
return CreateTickStyleModel(TickStyle.Outside);
|
||||
}
|
||||
|
||||
private static PlotModel CreateTickStyleModel(TickStyle tickStyle)
|
||||
{
|
||||
var model = new PlotModel { Title = "TickStyle: " + tickStyle };
|
||||
model.Axes.Add(new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
TickStyle = tickStyle,
|
||||
MajorGridlineStyle = LineStyle.None,
|
||||
MinorGridlineStyle = LineStyle.None,
|
||||
MaximumPadding = 0,
|
||||
MinimumPadding = 0
|
||||
});
|
||||
model.Axes.Add(new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
TickStyle = tickStyle,
|
||||
MajorGridlineStyle = LineStyle.None,
|
||||
MinorGridlineStyle = LineStyle.None,
|
||||
MaximumPadding = 0,
|
||||
MinimumPadding = 0
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Gridlines: None")]
|
||||
public static PlotModel GridlinesNone()
|
||||
{
|
||||
return CreateGridlinesModel("None", LineStyle.None, LineStyle.None);
|
||||
}
|
||||
|
||||
[Example("Gridlines: Horizontal")]
|
||||
public static PlotModel GridlinesHorizontal()
|
||||
{
|
||||
return CreateGridlinesModel("Horizontal", LineStyle.Solid, LineStyle.None);
|
||||
}
|
||||
|
||||
[Example("Gridlines: Vertical")]
|
||||
public static PlotModel GridlinesVertical()
|
||||
{
|
||||
return CreateGridlinesModel("Vertical", LineStyle.None, LineStyle.Solid);
|
||||
}
|
||||
|
||||
[Example("Gridlines: Both")]
|
||||
public static PlotModel GridlinesBoth()
|
||||
{
|
||||
return CreateGridlinesModel("Both", LineStyle.Solid, LineStyle.Solid);
|
||||
}
|
||||
|
||||
private static PlotModel CreateGridlinesModel(string title, LineStyle horizontal, LineStyle vertical)
|
||||
{
|
||||
var model = new PlotModel { Title = "Gridlines: " + title };
|
||||
model.Axes.Add(new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
MajorGridlineStyle = vertical,
|
||||
MinorGridlineStyle = vertical == LineStyle.Solid ? LineStyle.Dot : LineStyle.None,
|
||||
MaximumPadding = 0,
|
||||
MinimumPadding = 0
|
||||
});
|
||||
model.Axes.Add(new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
MajorGridlineStyle = horizontal,
|
||||
MinorGridlineStyle = horizontal == LineStyle.Solid ? LineStyle.Dot : LineStyle.None,
|
||||
MaximumPadding = 0,
|
||||
MinimumPadding = 0
|
||||
});
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
247
Source/Examples/ExampleLibrary/Axes/LinearColorAxisExamples.cs
Normal file
@@ -0,0 +1,247 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LinearColorAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
|
||||
[Examples("LinearColorAxis"), Tags("Axes")]
|
||||
public class LinearColorAxisExamples
|
||||
{
|
||||
[Example("Default palette")]
|
||||
public static PlotModel DefaultPalette()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(null, false);
|
||||
model.Axes.Clear();
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Jet (200 colors) palette")]
|
||||
public static PlotModel Jet200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(200), false);
|
||||
}
|
||||
|
||||
[Example("Jet (20 colors) palette")]
|
||||
public static PlotModel Jet20()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(20), false);
|
||||
}
|
||||
|
||||
[Example("Hue (400 colors) palette")]
|
||||
public static PlotModel Hue400()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Hue(400), false);
|
||||
}
|
||||
|
||||
[Example("Hue distinct (200 colors) palette")]
|
||||
public static PlotModel HueDistinct200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.HueDistinct(200), false);
|
||||
}
|
||||
|
||||
[Example("Hue distinct reversed (200 colors) palette")]
|
||||
public static PlotModel HueDistinctReverse200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.HueDistinct(200).Reverse(), false);
|
||||
}
|
||||
|
||||
[Example("Hot (200 colors) palette")]
|
||||
public static PlotModel Hot200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Hot(200), false);
|
||||
}
|
||||
|
||||
[Example("Hot (64 colors) palette")]
|
||||
public static PlotModel Hot64()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Hot64, false);
|
||||
}
|
||||
|
||||
[Example("Hot (30 colors) palette")]
|
||||
public static PlotModel Hot30()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Hot(30), false);
|
||||
}
|
||||
|
||||
[Example("Blue-white-red (200 colors) palette")]
|
||||
public static PlotModel BlueWhiteRed200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.BlueWhiteRed(200), false);
|
||||
}
|
||||
|
||||
[Example("Blue-white-red (40 colors) palette")]
|
||||
public static PlotModel BlueWhiteRed40()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.BlueWhiteRed(40), false);
|
||||
}
|
||||
|
||||
[Example("Black-white-red (500 colors) palette")]
|
||||
public static PlotModel BlackWhiteRed500()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.BlackWhiteRed(500), false);
|
||||
}
|
||||
|
||||
[Example("Black-white-red (3 colors) palette")]
|
||||
public static PlotModel BlackWhiteRed3()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.BlackWhiteRed(3), false);
|
||||
}
|
||||
|
||||
[Example("Cool (200 colors) palette")]
|
||||
public static PlotModel Cool200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Cool(200), false);
|
||||
}
|
||||
|
||||
[Example("Rainbow (200 colors) palette")]
|
||||
public static PlotModel Rainbow200()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Rainbow(200), false);
|
||||
}
|
||||
|
||||
[Example("Viridis palette")]
|
||||
public static PlotModel Viridis()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Viridis(), false);
|
||||
}
|
||||
|
||||
[Example("Plasma palette")]
|
||||
public static PlotModel Plasma()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Plasma(), false);
|
||||
}
|
||||
|
||||
[Example("Magma palette")]
|
||||
public static PlotModel Magma()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Magma(), false);
|
||||
}
|
||||
|
||||
[Example("Inferno palette")]
|
||||
public static PlotModel Inferno()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Inferno(), false);
|
||||
}
|
||||
|
||||
[Example("Cividis palette")]
|
||||
public static PlotModel Cividis()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Cividis(), false);
|
||||
}
|
||||
|
||||
[Example("Viridis (10 colors) palette")]
|
||||
public static PlotModel Viridis10()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Viridis(10), false);
|
||||
}
|
||||
|
||||
[Example("Rainbow (7 colors) palette")]
|
||||
public static PlotModel Rainbow7()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Rainbow(7), false);
|
||||
}
|
||||
|
||||
[Example("Vertical (6 colors)")]
|
||||
public static PlotModel Vertical_6()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(6), false);
|
||||
}
|
||||
|
||||
[Example("Vertical reverse (6 colors)")]
|
||||
public static PlotModel Vertical_Reverse_6()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(6), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.StartPosition = 1;
|
||||
colorAxis.EndPosition = 0;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Horizontal (6 colors)")]
|
||||
public static PlotModel Horizontal_6()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(6), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.Position = AxisPosition.Top;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Horizontal reverse (6 colors)")]
|
||||
public static PlotModel Horizontal_Reverse_6()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(6), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.Position = AxisPosition.Top;
|
||||
colorAxis.StartPosition = 1;
|
||||
colorAxis.EndPosition = 0;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RenderAsImage (horizontal)")]
|
||||
public static PlotModel RenderAsImage_Horizontal()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(1000), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.RenderAsImage = true;
|
||||
colorAxis.Position = AxisPosition.Top;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RenderAsImage (horizontal reversed)")]
|
||||
public static PlotModel RenderAsImage_Horizontal_Reversed()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(1000), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.RenderAsImage = true;
|
||||
colorAxis.Position = AxisPosition.Top;
|
||||
colorAxis.StartPosition = 1;
|
||||
colorAxis.EndPosition = 0;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RenderAsImage (vertical)")]
|
||||
public static PlotModel RenderAsImage_Vertical()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(1000), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.RenderAsImage = true;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RenderAsImage (vertical reversed)")]
|
||||
public static PlotModel RenderAsImage_Vertical_Reversed()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(1000), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.RenderAsImage = true;
|
||||
colorAxis.StartPosition = 1;
|
||||
colorAxis.EndPosition = 0;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Short vertical")]
|
||||
public static PlotModel Vertical_Short()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(600), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.StartPosition = 0.02;
|
||||
colorAxis.EndPosition = 0.5;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Position None")]
|
||||
public static PlotModel Position_None()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks(OxyPalettes.Jet(600), false);
|
||||
var colorAxis = (LinearColorAxis)model.Axes[0];
|
||||
colorAxis.Position = AxisPosition.None;
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
176
Source/Examples/ExampleLibrary/Axes/LogarithmicAxisExamples.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LogarithmicAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("LogarithmicAxis"), Tags("Axes")]
|
||||
public static class LogarithmicAxisExamples
|
||||
{
|
||||
[Example("LogarithmicAxis with default values")]
|
||||
public static PlotModel DefaultValues()
|
||||
{
|
||||
var m = new PlotModel();
|
||||
m.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Bottom });
|
||||
m.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Left});
|
||||
return m;
|
||||
}
|
||||
|
||||
[Example("Amdahl's Law")]
|
||||
public static PlotModel AmdahlsLaw()
|
||||
{
|
||||
var model = new PlotModel { Title = "Amdahl's law" };
|
||||
|
||||
Legend l = new Legend
|
||||
{
|
||||
LegendTitle = "Parallel portion"
|
||||
};
|
||||
model.Legends.Add(l);
|
||||
|
||||
// http://en.wikipedia.org/wiki/Amdahl's_law
|
||||
Func<double, int, double> maxSpeedup = (p, n) => 1.0 / ((1.0 - p) + (double)p / n);
|
||||
Func<double, LineSeries> createSpeedupCurve = p =>
|
||||
{
|
||||
// todo: tracker does not work when smoothing = true (too few points interpolated on the left end of the curve)
|
||||
var ls = new LineSeries { Title = p.ToString("P0") };
|
||||
for (int n = 1; n <= 65536; n *= 2) ls.Points.Add(new DataPoint(n, maxSpeedup(p, n)));
|
||||
return ls;
|
||||
};
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Bottom, Title = "Number of processors", Base = 2, MajorGridlineStyle = LineStyle.Solid, TickStyle = TickStyle.None });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 20, MinorStep = 2, MajorStep = 2, Title = "Speedup", StringFormat = "F2", MajorGridlineStyle = LineStyle.Solid, TickStyle = TickStyle.None });
|
||||
model.Series.Add(createSpeedupCurve(0.5));
|
||||
model.Series.Add(createSpeedupCurve(0.75));
|
||||
model.Series.Add(createSpeedupCurve(0.9));
|
||||
model.Series.Add(createSpeedupCurve(0.95));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Richter magnitudes")]
|
||||
public static PlotModel RichterMagnitudes()
|
||||
{
|
||||
// http://en.wikipedia.org/wiki/Richter_magnitude_scale
|
||||
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "The Richter magnitude scale",
|
||||
PlotMargins = new OxyThickness(80, 0, 80, 40),
|
||||
};
|
||||
|
||||
Legend l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Inside,
|
||||
LegendPosition = LegendPosition.TopCenter,
|
||||
LegendOrientation = LegendOrientation.Horizontal,
|
||||
LegendSymbolLength = 24
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "Richter magnitude scale", MajorGridlineStyle = LineStyle.None, TickStyle = TickStyle.None });
|
||||
|
||||
var frequencyCurve = new LineSeries
|
||||
{
|
||||
Title = "Frequency",
|
||||
Color = OxyColor.FromUInt32(0xff3c6c9e),
|
||||
StrokeThickness = 3,
|
||||
MarkerStroke = OxyColor.FromUInt32(0xff3c6c9e),
|
||||
MarkerFill = OxyColors.White,
|
||||
MarkerType = MarkerType.Circle,
|
||||
MarkerSize = 4,
|
||||
MarkerStrokeThickness = 3
|
||||
};
|
||||
|
||||
frequencyCurve.Points.Add(new DataPoint(1.5, 8000 * 365 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(2.5, 1000 * 365 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(3.5, 49000 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(4.5, 6200 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(5.5, 800 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(6.5, 120 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(7.5, 18 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(8.5, 1 * 100));
|
||||
frequencyCurve.Points.Add(new DataPoint(9.5, 1.0 / 20 * 100));
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Left, Title = "Frequency / 100 yr", UseSuperExponentialFormat = true, MajorGridlineStyle = LineStyle.None, TickStyle = TickStyle.Outside });
|
||||
model.Series.Add(frequencyCurve);
|
||||
|
||||
var energyCurve = new LineSeries
|
||||
{
|
||||
Title = "Energy",
|
||||
Color = OxyColor.FromUInt32(0xff9e6c3c),
|
||||
StrokeThickness = 3,
|
||||
MarkerStroke = OxyColor.FromUInt32(0xff9e6c3c),
|
||||
MarkerFill = OxyColors.White,
|
||||
MarkerType = MarkerType.Circle,
|
||||
MarkerSize = 4,
|
||||
MarkerStrokeThickness = 3
|
||||
};
|
||||
|
||||
energyCurve.Points.Add(new DataPoint(1.5, 11e6));
|
||||
energyCurve.Points.Add(new DataPoint(2.5, 360e6));
|
||||
energyCurve.Points.Add(new DataPoint(3.5, 11e9));
|
||||
energyCurve.Points.Add(new DataPoint(4.5, 360e9));
|
||||
energyCurve.Points.Add(new DataPoint(5.5, 11e12));
|
||||
energyCurve.Points.Add(new DataPoint(6.5, 360e12));
|
||||
energyCurve.Points.Add(new DataPoint(7.5, 11e15));
|
||||
energyCurve.Points.Add(new DataPoint(8.5, 360e15));
|
||||
energyCurve.Points.Add(new DataPoint(9.5, 11e18));
|
||||
energyCurve.YAxisKey = "energyAxis";
|
||||
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Right, Title = "Energy / J", Key = "energyAxis", UseSuperExponentialFormat = true, MajorGridlineStyle = LineStyle.None, TickStyle = TickStyle.Outside });
|
||||
model.Series.Add(energyCurve);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LogarithmicAxis with AbsoluteMaximum")]
|
||||
public static PlotModel AbsoluteMaximum()
|
||||
{
|
||||
var model = new PlotModel { Title = "AbsoluteMaximum = 1000" };
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Left, Minimum = 0.1, Maximum = 1000, AbsoluteMaximum = 1000 });
|
||||
model.Series.Add(new FunctionSeries(Math.Exp, 0, Math.Log(900), 100));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LogarithmicAxis with AxisChanged event handler")]
|
||||
public static PlotModel AxisChangedEventHAndler()
|
||||
{
|
||||
var model = new PlotModel { Title = "AxisChanged event handler" };
|
||||
var logAxis = new LogarithmicAxis { Position = AxisPosition.Left, Minimum = 0.1, Maximum = 1000 };
|
||||
int n = 0;
|
||||
logAxis.AxisChanged += (s, e) => { model.Subtitle = "Changed " + (n++) + " times. ActualMaximum=" + logAxis.ActualMaximum; };
|
||||
model.Axes.Add(logAxis);
|
||||
model.Series.Add(new FunctionSeries(Math.Exp, 0, Math.Log(900), 100));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Negative values")]
|
||||
public static PlotModel NegativeValues()
|
||||
{
|
||||
var model = new PlotModel { Title = "LogarithmicAxis", Subtitle = "LineSeries with negative values" };
|
||||
model.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Left });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Series.Add(new FunctionSeries(Math.Sin, 0, 40, 1000));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Tick calculation")]
|
||||
public static PlotModel TickCalculation()
|
||||
{
|
||||
var model = new PlotModel { Title = "Tick calculation for different bases" };
|
||||
model.Axes.Add(new LogarithmicAxis { Title = "Base 10", Position = AxisPosition.Left, Minimum = 20, Maximum = 20000, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid });
|
||||
model.Axes.Add(new LogarithmicAxis { Title = "Base 7", Position = AxisPosition.Bottom, Base = 7, Minimum = 2, Maximum = 10000, MajorGridlineStyle = LineStyle.Solid, MinorGridlineStyle = LineStyle.Solid });
|
||||
model.Axes.Add(new LogarithmicAxis { Title = "Base 5.5", Position = AxisPosition.Top, Base = 5.5, Minimum = 1, Maximum = 100 });
|
||||
model.Axes.Add(new LogarithmicAxis { Title = "Base 2", Position = AxisPosition.Right, Base = 2, Minimum = 1, Maximum = 1000000 });
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
338
Source/Examples/ExampleLibrary/Axes/PolarPlotExamples.cs
Normal file
@@ -0,0 +1,338 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PolarPlotExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Shows how to orient 0 degrees at the bottom and add E/W to indicate directions.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("Polar Plots"), Tags("Axes")]
|
||||
public static class PolarPlotExamples
|
||||
{
|
||||
[Example("Spiral")]
|
||||
public static PlotModel ArchimedeanSpiral()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Polar plot",
|
||||
Subtitle = "Archimedean spiral with equation r(θ) = θ for 0 < θ < 6π",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(0),
|
||||
};
|
||||
model.Axes.Add(
|
||||
new AngleAxis
|
||||
{
|
||||
MajorStep = Math.PI / 4,
|
||||
MinorStep = Math.PI / 16,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid,
|
||||
FormatAsFractions = true,
|
||||
FractionUnit = Math.PI,
|
||||
FractionUnitSymbol = "π",
|
||||
Minimum = 0,
|
||||
Maximum = 2 * Math.PI
|
||||
});
|
||||
model.Axes.Add(new MagnitudeAxis
|
||||
{
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid,
|
||||
});
|
||||
model.Series.Add(new FunctionSeries(t => t, t => t, 0, Math.PI * 6, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Spiral2")]
|
||||
public static PlotModel ArchimedeanSpiral2()
|
||||
{
|
||||
var model = ArchimedeanSpiral();
|
||||
model.Title += "(reversed angle axis)";
|
||||
var angleAxis = (AngleAxis)model.Axes[0];
|
||||
angleAxis.StartAngle = 360;
|
||||
angleAxis.EndAngle = 0;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Spiral with magnitude axis min and max")]
|
||||
public static PlotModel ArchimedeanSpiral3()
|
||||
{
|
||||
var model = ArchimedeanSpiral();
|
||||
model.Title += " (axis Minimum = 10 and Maximum = 20)";
|
||||
var magnitudeAxis = (MagnitudeAxis)model.Axes[1];
|
||||
magnitudeAxis.Minimum = 10;
|
||||
magnitudeAxis.Maximum = 20;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Angle axis with offset angle")]
|
||||
public static PlotModel OffsetAngles()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Offset angle axis",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(0),
|
||||
};
|
||||
|
||||
var angleAxis = new AngleAxis
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = Math.PI * 2,
|
||||
MajorStep = Math.PI / 4,
|
||||
MinorStep = Math.PI / 16,
|
||||
StringFormat = "0.00",
|
||||
StartAngle = 30,
|
||||
EndAngle = 390
|
||||
};
|
||||
model.Axes.Add(angleAxis);
|
||||
model.Axes.Add(new MagnitudeAxis());
|
||||
model.Series.Add(new FunctionSeries(t => t, t => t, 0, Math.PI * 6, 0.01));
|
||||
|
||||
// Subscribe to the mouse down event on the line series.
|
||||
model.MouseDown += (s, e) =>
|
||||
{
|
||||
var increment = 0d;
|
||||
|
||||
// Increment and decrement must be in degrees (corresponds to the StartAngle and EndAngle properties).
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
increment = 15;
|
||||
}
|
||||
|
||||
if (e.ChangedButton == OxyMouseButton.Right)
|
||||
{
|
||||
increment = -15;
|
||||
}
|
||||
|
||||
if (Math.Abs(increment) > double.Epsilon)
|
||||
{
|
||||
angleAxis.StartAngle += increment;
|
||||
angleAxis.EndAngle += increment;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Semi-circle")]
|
||||
public static PlotModel SemiCircle()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Semi-circle polar plot",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(0),
|
||||
};
|
||||
model.Axes.Add(
|
||||
new AngleAxis
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 180,
|
||||
MajorStep = 45,
|
||||
MinorStep = 9,
|
||||
StartAngle = 0,
|
||||
EndAngle = 180,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Axes.Add(new MagnitudeAxis
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 1,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Series.Add(new FunctionSeries(x => Math.Sin(x / 180 * Math.PI), t => t, 0, 180, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Semi-circle offset angle axis range")]
|
||||
public static PlotModel SemiCircleOffsetAngleAxisRange()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Semi-circle polar plot",
|
||||
Subtitle = "Angle axis range offset to -180 - 180",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(0),
|
||||
};
|
||||
model.Axes.Add(
|
||||
new AngleAxis
|
||||
{
|
||||
Minimum = -180,
|
||||
Maximum = 180,
|
||||
MajorStep = 45,
|
||||
MinorStep = 9,
|
||||
StartAngle = 0,
|
||||
EndAngle = 360,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Axes.Add(new MagnitudeAxis
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 1,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Series.Add(new FunctionSeries(x => Math.Sin(x / 180 * Math.PI), t => t, 0, 180, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows how to orient 0 degrees at the bottom and add E/W to indicate directions.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Example("East/west directions")]
|
||||
public static PlotModel EastWestDirections()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "East/west directions",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(0),
|
||||
};
|
||||
model.Axes.Add(
|
||||
new AngleAxis
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 360,
|
||||
MajorStep = 30,
|
||||
MinorStep = 30,
|
||||
StartAngle = -90,
|
||||
EndAngle = 270,
|
||||
LabelFormatter = angle =>
|
||||
{
|
||||
if (angle > 0 && angle < 180)
|
||||
{
|
||||
return angle + "E";
|
||||
}
|
||||
|
||||
if (angle > 180)
|
||||
{
|
||||
return (360 - angle) + "W";
|
||||
}
|
||||
|
||||
return angle.ToString();
|
||||
},
|
||||
MajorGridlineStyle = LineStyle.Dot,
|
||||
MinorGridlineStyle = LineStyle.None
|
||||
});
|
||||
model.Axes.Add(new MagnitudeAxis
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 1,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Series.Add(new FunctionSeries(x => Math.Sin(x / 180 * Math.PI), t => t, 0, 180, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Semi-circle full plot area")]
|
||||
public static PlotModel SemiCircleFullPlotArea()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Semi-circle polar plot filling the plot area",
|
||||
Subtitle = "The center can be move using the right mouse button",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(1),
|
||||
};
|
||||
model.Axes.Add(
|
||||
new AngleAxisFullPlotArea
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 180,
|
||||
MajorStep = 45,
|
||||
MinorStep = 9,
|
||||
StartAngle = 0,
|
||||
EndAngle = 180,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Axes.Add(new MagnitudeAxisFullPlotArea
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 1,
|
||||
MidshiftH = 0,
|
||||
MidshiftV = 0.9d,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
model.Series.Add(new FunctionSeries(x => Math.Sin(x / 180 * Math.PI), t => t, 0, 180, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Spiral full plot area")]
|
||||
public static PlotModel ArchimedeanSpiralFullPlotArea()
|
||||
{
|
||||
var model = CreateFullPlotAreaPlotModel();
|
||||
model.Series.Add(new FunctionSeries(t => t, t => t, 0, Math.PI * 6, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Spiral full plot area with negative minimum")]
|
||||
public static PlotModel SpiralWithNegativeMinium()
|
||||
{
|
||||
var model = CreateFullPlotAreaPlotModel();
|
||||
model.Title += " with a negative minimum";
|
||||
model.Series.Add(new FunctionSeries(t => t, t => t, -Math.PI * 6, Math.PI * 6, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Spiral full plot area with positive minimum")]
|
||||
public static PlotModel SpiralWithPositiveMinium()
|
||||
{
|
||||
var model = CreateFullPlotAreaPlotModel();
|
||||
model.Title += " with a positive minimum";
|
||||
model.Series.Add(new FunctionSeries(t => t, t => t, Math.PI * 6, Math.PI * 12, 0.01));
|
||||
return model;
|
||||
}
|
||||
|
||||
private static PlotModel CreateFullPlotAreaPlotModel()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Polar plot filling the plot area",
|
||||
Subtitle = "The center can be move using the right mouse button",
|
||||
PlotType = PlotType.Polar,
|
||||
PlotAreaBorderThickness = new OxyThickness(1),
|
||||
};
|
||||
|
||||
model.Axes.Add(
|
||||
new AngleAxisFullPlotArea
|
||||
{
|
||||
MajorStep = Math.PI / 4,
|
||||
MinorStep = Math.PI / 16,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid,
|
||||
FormatAsFractions = true,
|
||||
FractionUnit = Math.PI,
|
||||
FractionUnitSymbol = "π",
|
||||
Minimum = 0,
|
||||
Maximum = 2 * Math.PI
|
||||
});
|
||||
|
||||
model.Axes.Add(new MagnitudeAxisFullPlotArea
|
||||
{
|
||||
MidshiftH = -0.1d,
|
||||
MidshiftV = -0.25d,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
MinorGridlineStyle = LineStyle.Solid
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="RangeColorAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("RangeColorAxis"), Tags("Axes")]
|
||||
public class RangeColorAxisExamples
|
||||
{
|
||||
[Example("ScatterSeries with Reversed RangeColorAxis (Horizontal)")]
|
||||
public static PlotModel ReversedHorizontalRangeColorAxis()
|
||||
{
|
||||
return RangeColorAxis(AxisPosition.Top, true);
|
||||
}
|
||||
|
||||
[Example("ScatterSeries with Reversed RangeColorAxis (Vertical)")]
|
||||
public static PlotModel ReversedVerticalRangeColorAxis()
|
||||
{
|
||||
return RangeColorAxis(AxisPosition.Right, true);
|
||||
}
|
||||
|
||||
[Example("ScatterSeries with RangeColorAxis (Horizontal)")]
|
||||
public static PlotModel HorizontalRangeColorAxis()
|
||||
{
|
||||
return RangeColorAxis(AxisPosition.Top, false);
|
||||
}
|
||||
|
||||
[Example("ScatterSeries with RangeColorAxis (Vertical)")]
|
||||
public static PlotModel VerticalRangeColorAxis()
|
||||
{
|
||||
return RangeColorAxis(AxisPosition.Right, false);
|
||||
}
|
||||
|
||||
private static PlotModel RangeColorAxis(AxisPosition position, bool reverseAxis)
|
||||
{
|
||||
int n = 1000;
|
||||
|
||||
string modelTitle = reverseAxis
|
||||
? string.Format("ScatterSeries and Reversed RangeColorAxis (n={0})", n)
|
||||
: string.Format("ScatterSeries and RangeColorAxis (n={0})", n);
|
||||
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = modelTitle,
|
||||
Background = OxyColors.LightGray
|
||||
};
|
||||
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var rca = new RangeColorAxis { Position = position, Maximum = 2, Minimum = -2 };
|
||||
rca.AddRange(0, 0.5, OxyColors.Blue);
|
||||
rca.AddRange(-0.2, -0.1, OxyColors.Red);
|
||||
|
||||
if (reverseAxis)
|
||||
{
|
||||
rca.StartPosition = 1;
|
||||
rca.EndPosition = 0;
|
||||
}
|
||||
|
||||
model.Axes.Add(rca);
|
||||
|
||||
var s1 = new ScatterSeries { MarkerType = MarkerType.Square, MarkerSize = 6, };
|
||||
|
||||
var random = new Random(13);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
double x = (random.NextDouble() * 2.2) - 1.1;
|
||||
s1.Points.Add(new ScatterPoint(x, random.NextDouble()) { Value = x });
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Source/Examples/ExampleLibrary/Axes/TimeSpanAxisExamples.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="TimeSpanAxisExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("TimeSpanAxis"), Tags("Axes")]
|
||||
public static class TimeSpanAxisExamples
|
||||
{
|
||||
public class TimeValue
|
||||
{
|
||||
public TimeSpan Time { get; set; }
|
||||
public double Value { get; set; }
|
||||
}
|
||||
|
||||
[Example("Default StringFormat")]
|
||||
public static PlotModel TimeSpanaxisPlotModelDefault()
|
||||
{
|
||||
return TimeSpanaxisPlotModel(null);
|
||||
}
|
||||
|
||||
[Example("StringFormat = 'h:mm'")]
|
||||
public static PlotModel TimeSpanaxisPlotModel1()
|
||||
{
|
||||
return TimeSpanaxisPlotModel("h:mm");
|
||||
}
|
||||
|
||||
private static PlotModel TimeSpanaxisPlotModel(string stringFormat)
|
||||
{
|
||||
var start = new TimeSpan(0, 0, 0, 0);
|
||||
var end = new TimeSpan(0, 24, 0, 0);
|
||||
double increment = 3600;
|
||||
|
||||
// Create a random data collection
|
||||
var r = new Random(7);
|
||||
var data = new Collection<TimeValue>();
|
||||
var current = start;
|
||||
while (current <= end)
|
||||
{
|
||||
data.Add(new TimeValue { Time = current, Value = r.NextDouble() });
|
||||
current = current.Add(new TimeSpan(0, 0, (int)increment));
|
||||
}
|
||||
|
||||
var plotModel1 = new PlotModel { Title = "TimeSpan axis" };
|
||||
var timeSpanAxis1 = new TimeSpanAxis { Position = AxisPosition.Bottom, StringFormat = stringFormat };
|
||||
plotModel1.Axes.Add(timeSpanAxis1);
|
||||
var linearAxis1 = new LinearAxis { Position = AxisPosition.Left };
|
||||
plotModel1.Axes.Add(linearAxis1);
|
||||
var lineSeries1 = new LineSeries
|
||||
{
|
||||
Color = OxyColor.FromArgb(255, 78, 154, 6),
|
||||
MarkerFill = OxyColor.FromArgb(255, 78, 154, 6),
|
||||
MarkerStroke = OxyColors.ForestGreen,
|
||||
MarkerType = MarkerType.Plus,
|
||||
StrokeThickness = 1,
|
||||
DataFieldX = "Time",
|
||||
DataFieldY = "Value",
|
||||
ItemsSource = data
|
||||
};
|
||||
plotModel1.Series.Add(lineSeries1);
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="CustomSeriesExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("Custom series"), Tags("Series")]
|
||||
public static class CustomSeriesExamples
|
||||
{
|
||||
[Example("ErrorSeries")]
|
||||
public static PlotModel ErrorSeries()
|
||||
{
|
||||
int n = 20;
|
||||
|
||||
var model = new PlotModel { Title = "ErrorSeries" };
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPosition = LegendPosition.BottomRight
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
var s1 = new ErrorSeries { Title = "Measurements" };
|
||||
var random = new Random(31);
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
x += 2 + (random.NextDouble() * 10);
|
||||
y += 1 + random.NextDouble();
|
||||
double xe = 1 + (random.NextDouble() * 2);
|
||||
double ye = 1 + (random.NextDouble() * 2);
|
||||
s1.Points.Add(new ErrorItem(x, y, xe, ye));
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSegmentSeries")]
|
||||
public static PlotModel LineSegmentSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSegmentSeries" };
|
||||
|
||||
var lss1 = new LineSegmentSeries { Title = "The first series" };
|
||||
|
||||
// First segment
|
||||
lss1.Points.Add(new DataPoint(0, 3));
|
||||
lss1.Points.Add(new DataPoint(2, 3.2));
|
||||
|
||||
// Second segment
|
||||
lss1.Points.Add(new DataPoint(2, 2.7));
|
||||
lss1.Points.Add(new DataPoint(7, 2.9));
|
||||
|
||||
model.Series.Add(lss1);
|
||||
|
||||
var lss2 = new LineSegmentSeries { Title = "The second series" };
|
||||
|
||||
// First segment
|
||||
lss2.Points.Add(new DataPoint(1, -3));
|
||||
lss2.Points.Add(new DataPoint(2, 10));
|
||||
|
||||
// Second segment
|
||||
lss2.Points.Add(new DataPoint(0, 4.8));
|
||||
lss2.Points.Add(new DataPoint(7, 2.3));
|
||||
|
||||
// A very short segment
|
||||
lss2.Points.Add(new DataPoint(6, 4));
|
||||
lss2.Points.Add(new DataPoint(6, 4 + 1e-8));
|
||||
|
||||
model.Series.Add(lss2);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("FlagSeries")]
|
||||
public static PlotModel FlagSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "FlagSeries" };
|
||||
|
||||
var s1 = new FlagSeries { Title = "Incidents", Color = OxyColors.Red };
|
||||
s1.Values.Add(2);
|
||||
s1.Values.Add(3);
|
||||
s1.Values.Add(5);
|
||||
s1.Values.Add(7);
|
||||
s1.Values.Add(11);
|
||||
s1.Values.Add(13);
|
||||
s1.Values.Add(17);
|
||||
s1.Values.Add(19);
|
||||
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("MatrixSeries - diagonal matrix")]
|
||||
public static PlotModel DiagonalMatrix()
|
||||
{
|
||||
var model = new PlotModel();
|
||||
|
||||
var matrix = new double[3, 3];
|
||||
matrix[0, 0] = 1;
|
||||
matrix[1, 1] = 2;
|
||||
matrix[2, 2] = 3;
|
||||
|
||||
// Reverse the vertical axis
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, StartPosition = 1, EndPosition = 0 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Series.Add(new MatrixSeries { Matrix = matrix, ShowDiagonal = true });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap")]
|
||||
public static PlotModel PolarHeatMap()
|
||||
{
|
||||
var model = new PlotModel { Title = "Polar heat map", PlotMargins = new OxyThickness(40, 80, 40, 40), PlotType = PlotType.Polar, PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
|
||||
var matrix = new double[2, 2];
|
||||
matrix[0, 0] = 0;
|
||||
matrix[0, 1] = 2;
|
||||
matrix[1, 0] = 1.5;
|
||||
matrix[1, 1] = 0.2;
|
||||
|
||||
model.Axes.Add(new AngleAxis { StartAngle = 0, EndAngle = 360, Minimum = 0, Maximum = 360, MajorStep = 30, MinorStep = 15 });
|
||||
model.Axes.Add(new MagnitudeAxis { Minimum = 0, Maximum = 100, MajorStep = 25, MinorStep = 5 });
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right, Palette = OxyPalettes.Rainbow(500), HighColor = OxyColors.Gray, LowColor = OxyColors.Black });
|
||||
model.Series.Add(new PolarHeatMapSeries { Data = matrix, Angle0 = 30, Angle1 = 150, Magnitude0 = 0, Magnitude1 = 80, Interpolate = false });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap Reversed Angle Axis")]
|
||||
public static PlotModel PolarHeatMapReversedAngleAxis()
|
||||
{
|
||||
var model = new PlotModel { Title = "Polar heat map", PlotMargins = new OxyThickness(40, 80, 40, 40), PlotType = PlotType.Polar, PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
|
||||
var matrix = new double[2, 2];
|
||||
matrix[0, 0] = 0;
|
||||
matrix[0, 1] = 2;
|
||||
matrix[1, 0] = 1.5;
|
||||
matrix[1, 1] = 0.2;
|
||||
|
||||
model.Axes.Add(new AngleAxis { StartAngle = 360, EndAngle = 0, Minimum = 0, Maximum = 360, MajorStep = 30, MinorStep = 15 });
|
||||
model.Axes.Add(new MagnitudeAxis { Minimum = 0, Maximum = 100, MajorStep = 25, MinorStep = 5 });
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right, Palette = OxyPalettes.Rainbow(500), HighColor = OxyColors.Gray, LowColor = OxyColors.Black });
|
||||
model.Series.Add(new PolarHeatMapSeries { Data = matrix, Angle0 = 30, Angle1 = 150, Magnitude0 = 0, Magnitude1 = 80, Interpolate = false });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap Rotated CounterClockwise 90")]
|
||||
public static PlotModel PolarHeatMapRotatedCounterClockwise90()
|
||||
{
|
||||
var model = new PlotModel { Title = "Polar heat map", PlotMargins = new OxyThickness(40, 80, 40, 40), PlotType = PlotType.Polar, PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
|
||||
var matrix = new double[2, 2];
|
||||
matrix[0, 0] = 0;
|
||||
matrix[0, 1] = 2;
|
||||
matrix[1, 0] = 1.5;
|
||||
matrix[1, 1] = 0.2;
|
||||
|
||||
model.Axes.Add(new AngleAxis { StartAngle = 90, EndAngle = 90+360, Minimum = 0, Maximum = 360, MajorStep = 30, MinorStep = 15 });
|
||||
model.Axes.Add(new MagnitudeAxis { Minimum = 0, Maximum = 100, MajorStep = 25, MinorStep = 5 });
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right, Palette = OxyPalettes.Rainbow(500), HighColor = OxyColors.Gray, LowColor = OxyColors.Black });
|
||||
model.Series.Add(new PolarHeatMapSeries { Data = matrix, Angle0 = 30, Angle1 = 150, Magnitude0 = 0, Magnitude1 = 80, Interpolate = false });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap Rotated CounterClockwise on PI degrees")]
|
||||
public static PlotModel PolarHeatMapRotatedCounterClockwisePi()
|
||||
{
|
||||
var model = new PlotModel { Title = "Polar heat map", PlotMargins = new OxyThickness(40, 80, 40, 40), PlotType = PlotType.Polar, PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
|
||||
var matrix = new double[2, 2];
|
||||
matrix[0, 0] = 0;
|
||||
matrix[0, 1] = 2;
|
||||
matrix[1, 0] = 1.5;
|
||||
matrix[1, 1] = 0.2;
|
||||
|
||||
model.Axes.Add(new AngleAxis { StartAngle = Math.PI, EndAngle = Math.PI + 360, Minimum = 0, Maximum = 360, MajorStep = 30, MinorStep = 15 });
|
||||
model.Axes.Add(new MagnitudeAxis { Minimum = 0, Maximum = 100, MajorStep = 25, MinorStep = 5 });
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right, Palette = OxyPalettes.Rainbow(500), HighColor = OxyColors.Gray, LowColor = OxyColors.Black });
|
||||
model.Series.Add(new PolarHeatMapSeries { Data = matrix, Angle0 = 30, Angle1 = 150, Magnitude0 = 0, Magnitude1 = 80, Interpolate = false });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap (interpolated)")]
|
||||
public static PlotModel PolarHeatMapInterpolated()
|
||||
{
|
||||
var model = PolarHeatMap();
|
||||
model.Title = "Polar heat map (interpolated)";
|
||||
((PolarHeatMapSeries)model.Series[0]).Interpolate = true;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap fixed size image")]
|
||||
public static PlotModel PolarHeatMapFixed()
|
||||
{
|
||||
var model = PolarHeatMap();
|
||||
model.Title = "Polar heat map with fixed size image";
|
||||
((PolarHeatMapSeries)model.Series[0]).ImageSize = 800;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap on linear axes")]
|
||||
public static PlotModel PolarHeatMapLinearAxes()
|
||||
{
|
||||
var model = new PlotModel { Title = "Polar heat map on linear axes" };
|
||||
|
||||
var matrix = new double[2, 2];
|
||||
matrix[0, 0] = 0;
|
||||
matrix[0, 1] = 2;
|
||||
matrix[1, 0] = 1.5;
|
||||
matrix[1, 1] = 0.2;
|
||||
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -100, Maximum = 100 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 100 });
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right, Palette = OxyPalettes.Rainbow(500), HighColor = OxyColors.Gray, LowColor = OxyColors.Black });
|
||||
model.Series.Add(new PolarHeatMapSeries { Data = matrix, Angle0 = 30, Angle1 = 150, Magnitude0 = 0, Magnitude1 = 80, Interpolate = true });
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap linear axes, fixed size image (256x256)")]
|
||||
public static PlotModel PolarHeatMapLinearAxesFixed256()
|
||||
{
|
||||
var model = PolarHeatMapLinearAxes();
|
||||
model.Title = "Polar heat map on linear axes & fixed size image (256x256)";
|
||||
((PolarHeatMapSeries)model.Series[0]).ImageSize = 256;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolarHeatMap linear axes, fixed size image (1000x1000)")]
|
||||
public static PlotModel PolarHeatMapLinearAxesFixed1000()
|
||||
{
|
||||
var model = PolarHeatMapLinearAxes();
|
||||
model.Title = "Polar heat map on linear axes & fixed size image (1000x1000)";
|
||||
((PolarHeatMapSeries)model.Series[0]).ImageSize = 1000;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Design structure matrix (DSM)")]
|
||||
public static PlotModel DesignStructureMatrix()
|
||||
{
|
||||
// See also http://en.wikipedia.org/wiki/Design_structure_matrix
|
||||
var data = new double[7, 7];
|
||||
|
||||
// indexing: data[column,row]
|
||||
data[1, 0] = 1;
|
||||
data[5, 0] = 1;
|
||||
data[3, 1] = 1;
|
||||
data[0, 2] = 1;
|
||||
data[6, 2] = 1;
|
||||
data[4, 3] = 1;
|
||||
data[1, 4] = 1;
|
||||
data[5, 4] = 1;
|
||||
data[2, 5] = 1;
|
||||
data[0, 6] = 1;
|
||||
data[4, 6] = 1;
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
data[i, i] = -1;
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "Design structure matrix (DSM)" };
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.None, Palette = new OxyPalette(OxyColors.White, OxyColors.LightGreen), LowColor = OxyColors.Black, Minimum = 0, IsAxisVisible = false });
|
||||
var topAxis = new CategoryAxis
|
||||
{
|
||||
Position = AxisPosition.Top
|
||||
};
|
||||
topAxis.Labels.AddRange(new[] { "A", "B", "C", "D", "E", "F", "G" });
|
||||
model.Axes.Add(topAxis);
|
||||
var leftAxis = new CategoryAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
StartPosition = 1,
|
||||
EndPosition = 0
|
||||
};
|
||||
leftAxis.Labels.AddRange(new[] { "Element A", "Element B", "Element C", "Element D", "Element E", "Element F", "Element G" });
|
||||
model.Axes.Add(leftAxis);
|
||||
|
||||
var hms = new DesignStructureMatrixSeries
|
||||
{
|
||||
Data = data,
|
||||
Interpolate = false,
|
||||
LabelFormatString = "#",
|
||||
LabelFontSize = 0.25,
|
||||
X0 = 0,
|
||||
X1 = data.GetLength(0) - 1,
|
||||
Y0 = 0,
|
||||
Y1 = data.GetLength(1) - 1,
|
||||
};
|
||||
|
||||
model.Series.Add(hms);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
public class DesignStructureMatrixSeries : HeatMapSeries
|
||||
{
|
||||
protected override string GetLabel(double v, int i, int j)
|
||||
{
|
||||
if (i == j)
|
||||
{
|
||||
return ((CategoryAxis)this.XAxis).Labels[i];
|
||||
}
|
||||
|
||||
return base.GetLabel(v, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Source/Examples/ExampleLibrary/CustomSeries/ErrorItem.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ErrorItem.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Represents an error item.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an error item.
|
||||
/// </summary>
|
||||
public class ErrorItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ErrorItem" /> class.
|
||||
/// </summary>
|
||||
public ErrorItem()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ErrorItem" /> class.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="xerror">The xerror.</param>
|
||||
/// <param name="yerror">The yerror.</param>
|
||||
public ErrorItem(double x, double y, double xerror, double yerror)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.XError = xerror;
|
||||
this.YError = yerror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X.
|
||||
/// </summary>
|
||||
public double X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y.
|
||||
/// </summary>
|
||||
public double Y { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X error.
|
||||
/// </summary>
|
||||
public double XError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y error.
|
||||
/// </summary>
|
||||
public double YError { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns c# code that generates this instance.
|
||||
/// </summary>
|
||||
/// <returns>C# code.</returns>
|
||||
public string ToCode()
|
||||
{
|
||||
return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1},{2},{3}", this.X, this.Y, this.XError, this.YError);
|
||||
}
|
||||
}
|
||||
}
|
||||
163
Source/Examples/ExampleLibrary/CustomSeries/ErrorSeries.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ErrorSeries.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Represents an error series.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Series;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an error series.
|
||||
/// </summary>
|
||||
public class ErrorSeries : XYAxisSeries
|
||||
{
|
||||
/// <summary>
|
||||
/// The list of error items.
|
||||
/// </summary>
|
||||
private readonly List<ErrorItem> points = new List<ErrorItem>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ErrorSeries" /> class.
|
||||
/// </summary>
|
||||
public ErrorSeries()
|
||||
{
|
||||
this.Color = OxyColors.Black;
|
||||
this.StrokeThickness = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color.
|
||||
/// </summary>
|
||||
/// <value>The color.</value>
|
||||
public OxyColor Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of points.
|
||||
/// </summary>
|
||||
/// <value>A list of <see cref="ErrorItem" />.</value>
|
||||
public List<ErrorItem> Points
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.points;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the stroke thickness.
|
||||
/// </summary>
|
||||
/// <value>The stroke thickness.</value>
|
||||
public double StrokeThickness { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Renders the series on the specified render context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
var points = this.Points;
|
||||
if (points.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.VerifyAxes();
|
||||
|
||||
int n = points.Count;
|
||||
|
||||
// Transform all points to screen coordinates
|
||||
var segments = new List<ScreenPoint>(n * 6);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var sp = XAxis.Transform(points[i].X, points[i].Y, YAxis);
|
||||
var ei = points[i];
|
||||
double errorx = ei != null ? ei.XError * XAxis.Scale : 0;
|
||||
double errory = ei != null ? ei.YError * Math.Abs(YAxis.Scale) : 0;
|
||||
double d = 4;
|
||||
|
||||
if (errorx > 0)
|
||||
{
|
||||
var p0 = new ScreenPoint(sp.X - (errorx * 0.5), sp.Y);
|
||||
var p1 = new ScreenPoint(sp.X + (errorx * 0.5), sp.Y);
|
||||
segments.Add(p0);
|
||||
segments.Add(p1);
|
||||
segments.Add(new ScreenPoint(p0.X, p0.Y - d));
|
||||
segments.Add(new ScreenPoint(p0.X, p0.Y + d));
|
||||
segments.Add(new ScreenPoint(p1.X, p1.Y - d));
|
||||
segments.Add(new ScreenPoint(p1.X, p1.Y + d));
|
||||
}
|
||||
|
||||
if (errory > 0)
|
||||
{
|
||||
var p0 = new ScreenPoint(sp.X, sp.Y - (errory * 0.5));
|
||||
var p1 = new ScreenPoint(sp.X, sp.Y + (errory * 0.5));
|
||||
segments.Add(p0);
|
||||
segments.Add(p1);
|
||||
segments.Add(new ScreenPoint(p0.X - d, p0.Y));
|
||||
segments.Add(new ScreenPoint(p0.X + d, p0.Y));
|
||||
segments.Add(new ScreenPoint(p1.X - d, p1.Y));
|
||||
segments.Add(new ScreenPoint(p1.X + d, p1.Y));
|
||||
}
|
||||
}
|
||||
|
||||
// clip the line segments with the clipping rectangle
|
||||
for (int i = 0; i + 1 < segments.Count; i += 2)
|
||||
{
|
||||
rc.DrawReducedLine(
|
||||
new[] { segments[i], segments[i + 1] },
|
||||
0,
|
||||
this.GetSelectableColor(this.Color),
|
||||
this.StrokeThickness,
|
||||
this.EdgeRenderingMode,
|
||||
null,
|
||||
LineJoin.Bevel);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the legend symbol on the specified rendering context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
/// <param name="legendBox">The legend rectangle.</param>
|
||||
public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
|
||||
{
|
||||
double xmid = (legendBox.Left + legendBox.Right) * 0.5;
|
||||
double ymid = (legendBox.Top + legendBox.Bottom) * 0.5;
|
||||
var pts = new[]
|
||||
{
|
||||
new ScreenPoint(legendBox.Left, ymid),
|
||||
new ScreenPoint(legendBox.Right, ymid),
|
||||
new ScreenPoint(legendBox.Left, ymid - 2),
|
||||
new ScreenPoint(legendBox.Left, ymid + 3),
|
||||
new ScreenPoint(legendBox.Right, ymid - 2),
|
||||
new ScreenPoint(legendBox.Right, ymid + 3),
|
||||
|
||||
new ScreenPoint(xmid, legendBox.Top),
|
||||
new ScreenPoint(xmid, legendBox.Bottom),
|
||||
new ScreenPoint(xmid - 2, legendBox.Top),
|
||||
new ScreenPoint(xmid + 3, legendBox.Top),
|
||||
new ScreenPoint(xmid - 2, legendBox.Bottom),
|
||||
new ScreenPoint(xmid + 3, legendBox.Bottom)
|
||||
};
|
||||
rc.DrawLineSegments(pts, this.GetSelectableColor(this.Color), this.StrokeThickness, this.EdgeRenderingMode, null, LineJoin.Miter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the maximum and minimum values of the series.
|
||||
/// </summary>
|
||||
protected override void UpdateMaxMin()
|
||||
{
|
||||
base.UpdateMaxMin();
|
||||
this.InternalUpdateMaxMin(this.points, p => p.X - p.XError, p => p.X + p.XError, p => p.Y - p.YError, p => p.Y + p.YError);
|
||||
}
|
||||
}
|
||||
}
|
||||
236
Source/Examples/ExampleLibrary/CustomSeries/FlagSeries.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="FlagSeries.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Renders a 'flag' above the x-axis at the specified positions (in the Values list).
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
/// <summary>
|
||||
/// Renders a 'flag' above the x-axis at the specified positions (in the Values list).
|
||||
/// </summary>
|
||||
public class FlagSeries : ItemsSeries
|
||||
{
|
||||
/// <summary>
|
||||
/// The symbol position (y coordinate).
|
||||
/// </summary>
|
||||
private double symbolPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The symbol text size.
|
||||
/// </summary>
|
||||
private OxySize symbolSize;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FlagSeries" /> class.
|
||||
/// </summary>
|
||||
public FlagSeries()
|
||||
{
|
||||
this.Values = new List<double>();
|
||||
this.Color = OxyColors.Black;
|
||||
this.FontSize = 10;
|
||||
this.Symbol = ((char)0xEA).ToString();
|
||||
this.Font = "Wingdings 2";
|
||||
this.TrackerFormatString = "{0}: {1}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the symbols.
|
||||
/// </summary>
|
||||
/// <value>The color.</value>
|
||||
public OxyColor Color { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum value.
|
||||
/// </summary>
|
||||
/// <value>The maximum value.</value>
|
||||
public double MaximumX { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum value.
|
||||
/// </summary>
|
||||
/// <value>The minimum value.</value>
|
||||
public double MinimumX { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the symbol to draw at each value.
|
||||
/// </summary>
|
||||
/// <value>The symbol.</value>
|
||||
public string Symbol { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values.
|
||||
/// </summary>
|
||||
/// <value>The values.</value>
|
||||
public List<double> Values { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the x-axis.
|
||||
/// </summary>
|
||||
/// <value>The x-axis.</value>
|
||||
public Axis XAxis { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-axis key.
|
||||
/// </summary>
|
||||
/// <value>The x-axis key.</value>
|
||||
public string XAxisKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the point on the series that is nearest the specified point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point.</param>
|
||||
/// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
|
||||
/// <returns>A TrackerHitResult for the current hit.</returns>
|
||||
public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
|
||||
{
|
||||
foreach (var v in this.Values)
|
||||
{
|
||||
if (double.IsNaN(v) || v < this.XAxis.ActualMinimum || v > this.XAxis.ActualMaximum)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double x = this.XAxis.Transform(v);
|
||||
var r = new OxyRect(x - (this.symbolSize.Width / 2), this.symbolPosition - this.symbolSize.Height, this.symbolSize.Width, this.symbolSize.Height);
|
||||
if (r.Contains(point))
|
||||
{
|
||||
return new TrackerHitResult
|
||||
{
|
||||
Series = this,
|
||||
DataPoint = new DataPoint(v, double.NaN),
|
||||
Position = new ScreenPoint(x, this.symbolPosition - this.symbolSize.Height),
|
||||
Text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, null, this.Title, v)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the series on the specified render context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
if (this.XAxis == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.symbolPosition = this.PlotModel.PlotArea.Bottom;
|
||||
this.symbolSize = rc.MeasureText(this.Symbol, this.ActualFont, this.ActualFontSize);
|
||||
foreach (var v in this.Values)
|
||||
{
|
||||
if (double.IsNaN(v) || v < this.XAxis.ClipMinimum || v > this.XAxis.ClipMaximum)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double x = this.XAxis.Transform(v);
|
||||
rc.DrawText(
|
||||
new ScreenPoint(x, this.symbolPosition),
|
||||
this.Symbol,
|
||||
this.Color,
|
||||
this.ActualFont,
|
||||
this.ActualFontSize,
|
||||
this.ActualFontWeight,
|
||||
0,
|
||||
HorizontalAlignment.Center,
|
||||
VerticalAlignment.Bottom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the legend symbol on the specified render context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
/// <param name="legendBox">The legend rectangle.</param>
|
||||
public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
|
||||
{
|
||||
rc.DrawText(
|
||||
legendBox.Center,
|
||||
this.Symbol,
|
||||
this.Color,
|
||||
this.ActualFont,
|
||||
this.ActualFontSize,
|
||||
this.ActualFontWeight,
|
||||
0,
|
||||
HorizontalAlignment.Center,
|
||||
VerticalAlignment.Middle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if this data series requires X/Y axes. (e.g. Pie series do not require axes)
|
||||
/// </summary>
|
||||
/// <returns>True if no axes are required.</returns>
|
||||
protected override bool AreAxesRequired()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the axes of the series is defined.
|
||||
/// </summary>
|
||||
protected override void EnsureAxes()
|
||||
{
|
||||
this.XAxis = this.XAxisKey != null ?
|
||||
this.PlotModel.GetAxis(this.XAxisKey) :
|
||||
this.PlotModel.DefaultXAxis;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the data series is using the specified axis.
|
||||
/// </summary>
|
||||
/// <param name="axis">An axis which should be checked if used</param>
|
||||
/// <returns>True if the axis is in use.</returns>
|
||||
protected override bool IsUsing(Axis axis)
|
||||
{
|
||||
return axis == this.XAxis;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets default values (colors, line style etc) from the plot model.
|
||||
/// </summary>
|
||||
protected override void SetDefaultValues()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the axis maximum and minimum values.
|
||||
/// </summary>
|
||||
protected override void UpdateAxisMaxMin()
|
||||
{
|
||||
this.XAxis.Include(this.MinimumX);
|
||||
this.XAxis.Include(this.MaximumX);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the data from the ItemsSource.
|
||||
/// </summary>
|
||||
protected override void UpdateData()
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the maximum and minimum values of the series.
|
||||
/// </summary>
|
||||
protected override void UpdateMaxMin()
|
||||
{
|
||||
this.MinimumX = this.Values.Min();
|
||||
this.MaximumX = this.Values.Max();
|
||||
}
|
||||
}
|
||||
}
|
||||
165
Source/Examples/ExampleLibrary/CustomSeries/LineSegmentSeries.cs
Normal file
@@ -0,0 +1,165 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LineSegmentSeries.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Represents a line series where the points collection define line segments.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OxyPlot;
|
||||
using OxyPlot.Series;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a line series where the points collection define line segments.
|
||||
/// </summary>
|
||||
public class LineSegmentSeries : LineSeries
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LineSegmentSeries" /> class.
|
||||
/// </summary>
|
||||
public LineSegmentSeries()
|
||||
{
|
||||
this.ShowVerticals = true;
|
||||
this.Epsilon = 1e-8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to show vertical lines where there is no gap in x-coordinate.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if verticals should be shown; otherwise, <c>false</c>.</value>
|
||||
public bool ShowVerticals { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate gap tolerance.
|
||||
/// </summary>
|
||||
/// <value>The epsilon value.</value>
|
||||
public double Epsilon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Renders the series on the specified rendering context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
if (Points.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Points.Count % 2 != 0)
|
||||
{
|
||||
throw new InvalidOperationException("The number of points should be even.");
|
||||
}
|
||||
|
||||
if (this.XAxis == null || this.YAxis == null)
|
||||
{
|
||||
throw new InvalidOperationException("Axis has not been defined.");
|
||||
}
|
||||
|
||||
var screenPoints = Points.Select(this.Transform).ToList();
|
||||
var verticalLines = new List<ScreenPoint>();
|
||||
|
||||
for (int i = 0; i < screenPoints.Count; i += 2)
|
||||
{
|
||||
if (screenPoints[i].DistanceToSquared(screenPoints[i + 1]) < this.StrokeThickness)
|
||||
{
|
||||
screenPoints[i] = new ScreenPoint(screenPoints[i].X - (this.StrokeThickness * 0.5), screenPoints[i].Y);
|
||||
screenPoints[i + 1] = new ScreenPoint(screenPoints[i].X + (this.StrokeThickness * 0.5), screenPoints[i].Y);
|
||||
}
|
||||
|
||||
if (this.ShowVerticals && i > 0 && Math.Abs(screenPoints[i - 1].X - screenPoints[i].X) < this.Epsilon)
|
||||
{
|
||||
verticalLines.Add(screenPoints[i - 1]);
|
||||
verticalLines.Add(screenPoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.StrokeThickness > 0)
|
||||
{
|
||||
if (this.LineStyle != LineStyle.None)
|
||||
{
|
||||
rc.DrawLineSegments(screenPoints, this.ActualColor, this.StrokeThickness, this.EdgeRenderingMode, this.LineStyle.GetDashArray(), this.LineJoin);
|
||||
}
|
||||
|
||||
rc.DrawLineSegments(verticalLines, this.ActualColor, this.StrokeThickness / 3, this.EdgeRenderingMode, LineStyle.Dash.GetDashArray(), this.LineJoin);
|
||||
}
|
||||
|
||||
rc.DrawMarkers(screenPoints, this.MarkerType, null, this.MarkerSize, this.MarkerFill, this.MarkerStroke, this.MarkerStrokeThickness, this.EdgeRenderingMode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the point on the series that is nearest the specified point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point.</param>
|
||||
/// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
|
||||
/// <returns>A TrackerHitResult for the current hit.</returns>
|
||||
public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
|
||||
{
|
||||
var points = this.Points;
|
||||
|
||||
if (points == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var spn = default(ScreenPoint);
|
||||
var dpn = default(DataPoint);
|
||||
double index = -1;
|
||||
|
||||
double minimumDistance = double.MaxValue;
|
||||
|
||||
for (int i = 0; i + 1 < points.Count; i += 2)
|
||||
{
|
||||
var p1 = points[i];
|
||||
var p2 = points[i + 1];
|
||||
if (!this.IsValidPoint(p1) || !this.IsValidPoint(p2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var sp1 = this.Transform(p1);
|
||||
var sp2 = this.Transform(p2);
|
||||
|
||||
// Find the nearest point on the line segment.
|
||||
var spl = ScreenPointHelper.FindPointOnLine(point, sp1, sp2);
|
||||
|
||||
if (ScreenPoint.IsUndefined(spl))
|
||||
{
|
||||
// P1 && P2 coincident
|
||||
continue;
|
||||
}
|
||||
|
||||
double l2 = (point - spl).LengthSquared;
|
||||
|
||||
if (l2 < minimumDistance)
|
||||
{
|
||||
double u = (spl - sp1).Length / (sp2 - sp1).Length;
|
||||
dpn = new DataPoint(p1.X + (u * (p2.X - p1.X)), p1.Y + (u * (p2.Y - p1.Y)));
|
||||
spn = spl;
|
||||
minimumDistance = l2;
|
||||
index = i + u;
|
||||
}
|
||||
}
|
||||
|
||||
if (minimumDistance < double.MaxValue)
|
||||
{
|
||||
return new TrackerHitResult
|
||||
{
|
||||
Series = this,
|
||||
DataPoint = dpn,
|
||||
Position = spn,
|
||||
Item = this.GetItem((int)index),
|
||||
Index = index
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
236
Source/Examples/ExampleLibrary/CustomSeries/MatrixSeries.cs
Normal file
@@ -0,0 +1,236 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="MatrixSeries.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Provides a series that visualizes the structure of a matrix.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Series;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a series that visualizes the structure of a matrix.
|
||||
/// </summary>
|
||||
public class MatrixSeries : XYAxisSeries
|
||||
{
|
||||
/// <summary>
|
||||
/// The image
|
||||
/// </summary>
|
||||
private OxyImage image;
|
||||
|
||||
/// <summary>
|
||||
/// The matrix
|
||||
/// </summary>
|
||||
private double[,] matrix;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatrixSeries" /> class.
|
||||
/// </summary>
|
||||
public MatrixSeries()
|
||||
{
|
||||
this.GridInterval = 1;
|
||||
this.ShowDiagonal = false;
|
||||
this.MinimumGridLineDistance = 4;
|
||||
this.GridColor = OxyColors.LightGray;
|
||||
this.BorderColor = OxyColors.Gray;
|
||||
this.NotZeroColor = OxyColors.Black;
|
||||
this.ZeroTolerance = 0;
|
||||
this.TrackerFormatString = "{0}\r\n[{1},{2}] = {3}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the matrix.
|
||||
/// </summary>
|
||||
public double[,] Matrix
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.matrix;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.image = null;
|
||||
this.matrix = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interval between the grid lines (the grid is hidden if value is 0).
|
||||
/// </summary>
|
||||
public int GridInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to show the diagonal.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if the diagonal should be shown; otherwise, <c>false</c>.</value>
|
||||
public bool ShowDiagonal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum grid line distance.
|
||||
/// </summary>
|
||||
public double MinimumGridLineDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the grid.
|
||||
/// </summary>
|
||||
/// <value>The color of the grid.</value>
|
||||
public OxyColor GridColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the border around the matrix.
|
||||
/// </summary>
|
||||
/// <value>The color of the border.</value>
|
||||
public OxyColor BorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the not zero elements of the matrix.
|
||||
/// </summary>
|
||||
public OxyColor NotZeroColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the zero tolerance (inclusive).
|
||||
/// </summary>
|
||||
/// <value>The zero tolerance.</value>
|
||||
public double ZeroTolerance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the point on the series that is nearest the specified point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point.</param>
|
||||
/// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
|
||||
/// <returns>A TrackerHitResult for the current hit.</returns>
|
||||
public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
|
||||
{
|
||||
var dp = this.InverseTransform(point);
|
||||
int i = (int)dp.Y;
|
||||
int j = (int)dp.X;
|
||||
|
||||
if (i >= 0 && i < this.matrix.GetLength(0) && j >= 0 && j < this.matrix.GetLength(1))
|
||||
{
|
||||
var value = this.matrix[i, j];
|
||||
return new TrackerHitResult
|
||||
{
|
||||
Series = this,
|
||||
DataPoint = dp,
|
||||
Position = point,
|
||||
Item = null,
|
||||
Index = -1,
|
||||
Text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, null, this.Title, i, j, value)
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the series on the specified render context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
if (this.Matrix == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int m = this.Matrix.GetLength(0);
|
||||
int n = this.Matrix.GetLength(1);
|
||||
var p0 = this.Transform(0, 0);
|
||||
var p1 = this.Transform(n, m);
|
||||
|
||||
// note matrix index [i,j] maps to image index [j,i]
|
||||
if (this.image == null)
|
||||
{
|
||||
var pixels = new OxyColor[n, m];
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
for (int j = 0; j < n; j++)
|
||||
{
|
||||
pixels[j, i] = Math.Abs(this.Matrix[i, j]) <= this.ZeroTolerance ? OxyColors.Transparent : this.NotZeroColor;
|
||||
}
|
||||
}
|
||||
|
||||
this.image = OxyImage.Create(pixels, ImageFormat.Png);
|
||||
}
|
||||
|
||||
var x0 = Math.Min(p0.X, p1.X);
|
||||
var y0 = Math.Min(p0.Y, p1.Y);
|
||||
var w = Math.Abs(p0.X - p1.X);
|
||||
var h = Math.Abs(p0.Y - p1.Y);
|
||||
rc.DrawImage(this.image, x0, y0, w, h, 1, false);
|
||||
|
||||
var points = new List<ScreenPoint>();
|
||||
if (this.GridInterval > 0)
|
||||
{
|
||||
var p2 = this.Transform(this.GridInterval, this.GridInterval);
|
||||
if (Math.Abs(p2.Y - p0.Y) > this.MinimumGridLineDistance)
|
||||
{
|
||||
for (int i = 1; i < n; i += this.GridInterval)
|
||||
{
|
||||
points.Add(this.Transform(0, i));
|
||||
points.Add(this.Transform(n, i));
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.Abs(p2.X - p0.X) > this.MinimumGridLineDistance)
|
||||
{
|
||||
for (int j = 1; j < m; j += this.GridInterval)
|
||||
{
|
||||
points.Add(this.Transform(j, 0));
|
||||
points.Add(this.Transform(j, m));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.ShowDiagonal)
|
||||
{
|
||||
points.Add(this.Transform(0, 0));
|
||||
points.Add(this.Transform(n, m));
|
||||
}
|
||||
|
||||
rc.DrawLineSegments(points, this.GridColor, 1, this.EdgeRenderingMode, null, LineJoin.Miter);
|
||||
|
||||
if (this.BorderColor.IsVisible())
|
||||
{
|
||||
var borderPoints = new[]
|
||||
{
|
||||
this.Transform(0, 0),
|
||||
this.Transform(m, 0),
|
||||
this.Transform(0, n),
|
||||
this.Transform(m, n),
|
||||
this.Transform(0, 0),
|
||||
this.Transform(0, n),
|
||||
this.Transform(m, 0),
|
||||
this.Transform(m, n)
|
||||
};
|
||||
|
||||
rc.DrawLineSegments(borderPoints, this.BorderColor, 1, this.EdgeRenderingMode, null, LineJoin.Miter);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the maximum and minimum values of the series.
|
||||
/// </summary>
|
||||
protected override void UpdateMaxMin()
|
||||
{
|
||||
base.UpdateMaxMin();
|
||||
if (this.Matrix == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.MinX = 0;
|
||||
this.MaxX = this.Matrix.GetLength(1);
|
||||
this.MinY = 0;
|
||||
this.MaxY = this.Matrix.GetLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PolarHeatMapSeries.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Implements a polar heat map series.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace OxyPlot.Series
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot.Axes;
|
||||
|
||||
/// <summary>
|
||||
/// Implements a polar heat map series.
|
||||
/// </summary>
|
||||
public class PolarHeatMapSeries : XYAxisSeries
|
||||
{
|
||||
/// <summary>
|
||||
/// The image
|
||||
/// </summary>
|
||||
private OxyImage image;
|
||||
|
||||
/// <summary>
|
||||
/// The pixels
|
||||
/// </summary>
|
||||
private OxyColor[,] pixels;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PolarHeatMapSeries" /> class.
|
||||
/// </summary>
|
||||
public PolarHeatMapSeries()
|
||||
{
|
||||
this.Interpolate = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the image - if set to 0, the image will be generated at every update.
|
||||
/// </summary>
|
||||
/// <value>The size of the image.</value>
|
||||
public int ImageSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of the left column mid point.
|
||||
/// </summary>
|
||||
public double Angle0 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of the right column mid point.
|
||||
/// </summary>
|
||||
public double Angle1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of the top row mid point.
|
||||
/// </summary>
|
||||
public double Magnitude0 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of the bottom row mid point.
|
||||
/// </summary>
|
||||
public double Magnitude1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data array.
|
||||
/// </summary>
|
||||
/// <remarks>Note that the indices of the data array refer to [x,y].</remarks>
|
||||
public double[,] Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to interpolate when rendering.
|
||||
/// </summary>
|
||||
/// <remarks>This property is not supported on all platforms.</remarks>
|
||||
public bool Interpolate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum value of the dataset.
|
||||
/// </summary>
|
||||
public double MinValue { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum value of the dataset.
|
||||
/// </summary>
|
||||
public double MaxValue { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color axis.
|
||||
/// </summary>
|
||||
/// <value>The color axis.</value>
|
||||
public IColorAxis ColorAxis { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the color axis key.
|
||||
/// </summary>
|
||||
/// <value>The color axis key.</value>
|
||||
public string ColorAxisKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Renders the series on the specified render context.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rendering context.</param>
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
if (this.Data == null)
|
||||
{
|
||||
this.image = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.ImageSize > 0)
|
||||
{
|
||||
this.RenderFixed(rc, this.PlotModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.RenderDynamic(rc, this.PlotModel);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders by an image sized from the available plot area.
|
||||
/// </summary>
|
||||
/// <param name="rc">The rc.</param>
|
||||
/// <param name="model">The model.</param>
|
||||
public void RenderDynamic(IRenderContext rc, PlotModel model)
|
||||
{
|
||||
int m = this.Data.GetLength(0);
|
||||
int n = this.Data.GetLength(1);
|
||||
|
||||
// get the available plot area
|
||||
var dest = model.PlotArea;
|
||||
int width = (int)dest.Width;
|
||||
int height = (int)dest.Height;
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.pixels == null || this.pixels.GetLength(0) != height || this.pixels.GetLength(1) != width)
|
||||
{
|
||||
this.pixels = new OxyColor[width, height];
|
||||
}
|
||||
|
||||
var p = this.pixels;
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
// transform from screen to magnitude/angle
|
||||
var sp = new ScreenPoint(dest.Left + x, dest.Top + y);
|
||||
var xy = this.InverseTransform(sp);
|
||||
double angle;
|
||||
double magnitude;
|
||||
if (this.PlotModel.PlotType != PlotType.Polar)
|
||||
{
|
||||
angle = Math.Atan2(xy.Y, xy.X) / Math.PI * 180;
|
||||
magnitude = Math.Sqrt((xy.X * xy.X) + (xy.Y * xy.Y));
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = xy.Y / Math.PI * 180;
|
||||
magnitude = xy.X;
|
||||
while (angle < 0)
|
||||
{
|
||||
angle += 360;
|
||||
}
|
||||
while (angle > 360)
|
||||
{
|
||||
angle -= 360;
|
||||
}
|
||||
}
|
||||
|
||||
// transform to indices in the Data array
|
||||
var ii = (angle - this.Angle0) / (this.Angle1 - this.Angle0) * m;
|
||||
var jj = (magnitude - this.Magnitude0) / (this.Magnitude1 - this.Magnitude0) * n;
|
||||
if (ii >= 0 && ii < m && jj >= 0 && jj < n)
|
||||
{
|
||||
// get the (interpolated) value
|
||||
var value = this.GetValue(ii, jj);
|
||||
|
||||
// use the color axis to get the color
|
||||
p[x, y] = OxyColor.FromAColor(160, this.ColorAxis.GetColor(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
// outside the range of the Data array
|
||||
p[x, y] = OxyColors.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the PNG image
|
||||
this.image = OxyImage.Create(p, ImageFormat.Png);
|
||||
|
||||
// Render the image
|
||||
rc.DrawImage(this.image, dest.Left, dest.Top, dest.Width, dest.Height, 1, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the image next time the series is rendered.
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
this.image = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders by scaling a fixed image.
|
||||
/// </summary>
|
||||
/// <param name="rc">The render context.</param>
|
||||
/// <param name="model">The model.</param>
|
||||
public void RenderFixed(IRenderContext rc, PlotModel model)
|
||||
{
|
||||
if (image == null)
|
||||
{
|
||||
int m = this.Data.GetLength(0);
|
||||
int n = this.Data.GetLength(1);
|
||||
|
||||
int width = this.ImageSize;
|
||||
int height = this.ImageSize;
|
||||
if (this.pixels == null || this.pixels.GetLength(0) != height || this.pixels.GetLength(1) != width)
|
||||
{
|
||||
this.pixels = new OxyColor[width, height];
|
||||
}
|
||||
|
||||
var p = this.pixels;
|
||||
for (int yi = 0; yi < height; yi++)
|
||||
{
|
||||
for (int xi = 0; xi < width; xi++)
|
||||
{
|
||||
double x = (xi - width * 0.5) / (width * 0.5) * this.Magnitude1;
|
||||
double y = -(yi - height * 0.5) / (height * 0.5) * this.Magnitude1;
|
||||
|
||||
double angle = Math.Atan2(y, x) / Math.PI * 180;
|
||||
double magnitude = Math.Sqrt(x * x + y * y);
|
||||
|
||||
while (angle < 0)
|
||||
{
|
||||
angle += 360;
|
||||
}
|
||||
while (angle > 360)
|
||||
{
|
||||
angle -= 360;
|
||||
}
|
||||
|
||||
// transform to indices in the Data array
|
||||
var ii = (angle - this.Angle0) / (this.Angle1 - this.Angle0) * m;
|
||||
var jj = (magnitude - this.Magnitude0) / (this.Magnitude1 - this.Magnitude0) * n;
|
||||
if (ii >= 0 && ii < m && jj >= 0 && jj < n)
|
||||
{
|
||||
// get the (interpolated) value
|
||||
var value = this.GetValue(ii, jj);
|
||||
|
||||
// use the color axis to get the color
|
||||
p[xi, yi] = OxyColor.FromAColor(160, this.ColorAxis.GetColor(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
// outside the range of the Data array
|
||||
p[xi, yi] = OxyColors.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the PNG image
|
||||
this.image = OxyImage.Create(p, ImageFormat.Png);
|
||||
}
|
||||
|
||||
OxyRect dest;
|
||||
if (this.PlotModel.PlotType != PlotType.Polar)
|
||||
{
|
||||
var topleft = this.Transform(-this.Magnitude1, this.Magnitude1);
|
||||
var bottomright = this.Transform(this.Magnitude1, -this.Magnitude1);
|
||||
dest = new OxyRect(topleft.X, topleft.Y, bottomright.X - topleft.X, bottomright.Y - topleft.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
var top = this.Transform(this.Magnitude1, 90);
|
||||
var bottom = this.Transform(this.Magnitude1, 270);
|
||||
var left = this.Transform(this.Magnitude1, 180);
|
||||
var right = this.Transform(this.Magnitude1, 0);
|
||||
dest = new OxyRect(left.X, top.Y, right.X - left.X, bottom.Y - top.Y);
|
||||
}
|
||||
|
||||
// Render the image
|
||||
rc.DrawImage(this.image, dest.Left, dest.Top, dest.Width, dest.Height, 1, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value at the specified data indices.
|
||||
/// </summary>
|
||||
/// <param name="ii">The first index in the Data array.</param>
|
||||
/// <param name="jj">The second index in the Data array.</param>
|
||||
/// <returns>The value.</returns>
|
||||
protected virtual double GetValue(double ii, double jj)
|
||||
{
|
||||
if (!this.Interpolate)
|
||||
{
|
||||
var i = (int)Math.Floor(ii);
|
||||
var j = (int)Math.Floor(jj);
|
||||
return this.Data[i, j];
|
||||
}
|
||||
|
||||
ii -= 0.5;
|
||||
jj -= 0.5;
|
||||
|
||||
// bi-linear interpolation http://en.wikipedia.org/wiki/Bilinear_interpolation
|
||||
var r = (int)Math.Floor(ii);
|
||||
var c = (int)Math.Floor(jj);
|
||||
|
||||
int r0 = r > 0 ? r : 0;
|
||||
int r1 = r + 1 < this.Data.GetLength(0) ? r + 1 : r;
|
||||
int c0 = c > 0 ? c : 0;
|
||||
int c1 = c + 1 < this.Data.GetLength(1) ? c + 1 : c;
|
||||
|
||||
double v00 = this.Data[r0, c0];
|
||||
double v01 = this.Data[r0, c1];
|
||||
double v10 = this.Data[r1, c0];
|
||||
double v11 = this.Data[r1, c1];
|
||||
|
||||
double di = ii - r;
|
||||
double dj = jj - c;
|
||||
|
||||
double v0 = (v00 * (1 - dj)) + (v01 * dj);
|
||||
double v1 = (v10 * (1 - dj)) + (v11 * dj);
|
||||
|
||||
return (v0 * (1 - di)) + (v1 * di);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the point on the series that is nearest the specified point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point.</param>
|
||||
/// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
|
||||
/// <returns>A TrackerHitResult for the current hit.</returns>
|
||||
public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the axes of the series is defined.
|
||||
/// </summary>
|
||||
protected override void EnsureAxes()
|
||||
{
|
||||
base.EnsureAxes();
|
||||
|
||||
this.ColorAxis = this.ColorAxisKey != null ?
|
||||
this.PlotModel.GetAxis(this.ColorAxisKey) as IColorAxis :
|
||||
this.PlotModel.DefaultColorAxis as IColorAxis;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the maximum and minimum values of the series.
|
||||
/// </summary>
|
||||
protected override void UpdateMaxMin()
|
||||
{
|
||||
base.UpdateMaxMin();
|
||||
|
||||
this.MinValue = this.GetData().Min();
|
||||
this.MaxValue = this.GetData().Max();
|
||||
|
||||
//this.XAxis.Include(this.MinX);
|
||||
//this.XAxis.Include(this.MaxX);
|
||||
|
||||
//this.YAxis.Include(this.MinY);
|
||||
//this.YAxis.Include(this.MaxY);
|
||||
|
||||
var colorAxis = this.ColorAxis as Axis;
|
||||
if (colorAxis != null)
|
||||
{
|
||||
colorAxis.Include(this.MinValue);
|
||||
colorAxis.Include(this.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data as a sequence (LINQ-friendly).
|
||||
/// </summary>
|
||||
/// <returns>The sequence of data.</returns>
|
||||
protected IEnumerable<double> GetData()
|
||||
{
|
||||
int m = this.Data.GetLength(0);
|
||||
int n = this.Data.GetLength(1);
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
for (int j = 0; j < n; j++)
|
||||
{
|
||||
yield return this.Data[i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
371
Source/Examples/ExampleLibrary/Discussions/DiscussionExamples.cs
Normal file
@@ -0,0 +1,371 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="DiscussionExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("Z0 Discussions")]
|
||||
public class DiscussionExamples
|
||||
{
|
||||
[Example("#445576: Invisible contour series")]
|
||||
public static PlotModel InvisibleContourSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "Invisible contour series" };
|
||||
var cs = new ContourSeries
|
||||
{
|
||||
IsVisible = false,
|
||||
ColumnCoordinates = ArrayBuilder.CreateVector(-1, 1, 0.05),
|
||||
RowCoordinates = ArrayBuilder.CreateVector(-1, 1, 0.05)
|
||||
};
|
||||
cs.Data = ArrayBuilder.Evaluate((x, y) => x + y, cs.ColumnCoordinates, cs.RowCoordinates);
|
||||
model.Series.Add(cs);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#461507: StairStepSeries NullReferenceException")]
|
||||
public static PlotModel StairStepSeries_NullReferenceException()
|
||||
{
|
||||
var plotModel1 = new PlotModel { Title = "StairStepSeries NullReferenceException" };
|
||||
plotModel1.Series.Add(new StairStepSeries());
|
||||
return plotModel1;
|
||||
}
|
||||
|
||||
[Example("#501409: Heatmap interpolation color")]
|
||||
public static PlotModel HeatMapSeriesInterpolationColor()
|
||||
{
|
||||
var data = new double[2, 3];
|
||||
data[0, 0] = 10;
|
||||
data[0, 1] = 0;
|
||||
data[0, 2] = -10;
|
||||
|
||||
var model = new PlotModel { Title = "HeatMapSeries" };
|
||||
model.Axes.Add(new LinearColorAxis { Position = AxisPosition.Right, Palette = new OxyPalette(OxyColors.Red, OxyColors.Green, OxyColors.Blue) });
|
||||
|
||||
var hms = new HeatMapSeries
|
||||
{
|
||||
CoordinateDefinition = HeatMapCoordinateDefinition.Center,
|
||||
X0 = 0,
|
||||
X1 = 3,
|
||||
Y0 = 0,
|
||||
Y1 = 2,
|
||||
Data = data,
|
||||
Interpolate = false,
|
||||
LabelFontSize = 0.2
|
||||
};
|
||||
model.Series.Add(hms);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#522598: Peaks 400x400")]
|
||||
public static PlotModel Peaks400()
|
||||
{
|
||||
return HeatMapSeriesExamples.CreatePeaks(null, true, 400);
|
||||
}
|
||||
|
||||
[Example("#474875: Updating HeatMapSeries 1")]
|
||||
public static PlotModel UpdatingHeatMapSeries1()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks();
|
||||
model.Title = "Updating HeatMapSeries";
|
||||
model.Subtitle = "Click the heat map to change the Maximum of the color axis.";
|
||||
var lca = (LinearColorAxis)model.Axes[0];
|
||||
var hms = (HeatMapSeries)model.Series[0];
|
||||
hms.MouseDown += (s, e) =>
|
||||
{
|
||||
lca.Maximum = Double.IsNaN(lca.Maximum) ? 10 : Double.NaN;
|
||||
model.InvalidatePlot(true);
|
||||
};
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#474875: Updating HeatMapSeries 2")]
|
||||
public static PlotModel UpdatingHeatMapSeries()
|
||||
{
|
||||
var model = HeatMapSeriesExamples.CreatePeaks();
|
||||
model.Title = "Updating HeatMapSeries";
|
||||
model.Subtitle = "Click the heat map to change the Maximum of the color axis and invoke the Invalidate method on the HeatMapSeries.";
|
||||
var lca = (LinearColorAxis)model.Axes[0];
|
||||
var hms = (HeatMapSeries)model.Series[0];
|
||||
hms.MouseDown += (s, e) =>
|
||||
{
|
||||
lca.Maximum = Double.IsNaN(lca.Maximum) ? 10 : Double.NaN;
|
||||
hms.Invalidate();
|
||||
model.InvalidatePlot(true);
|
||||
};
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#539104: Reduced color saturation")]
|
||||
public static PlotModel ReducedColorSaturation()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Reduced color saturation",
|
||||
};
|
||||
|
||||
model.Axes.Add(new CategoryAxis { Position = AxisPosition.Bottom });
|
||||
|
||||
// modify the saturation of the default colors
|
||||
model.DefaultColors = model.DefaultColors.Select(c => c.ChangeSaturation(0.5)).ToList();
|
||||
|
||||
var r = new Random(37);
|
||||
for (var i = 0; i < model.DefaultColors.Count; i++)
|
||||
{
|
||||
var columnSeries = new BarSeries();
|
||||
columnSeries.Items.Add(new BarItem(50 + r.Next(50)));
|
||||
columnSeries.Items.Add(new BarItem(40 + r.Next(50)));
|
||||
model.Series.Add(columnSeries);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#539104: Medium intensity colors")]
|
||||
public static PlotModel MediumIntensityColors()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Medium intensity colors",
|
||||
};
|
||||
|
||||
model.Axes.Add(new CategoryAxis { Position = AxisPosition.Bottom });
|
||||
|
||||
// See http://www.perceptualedge.com/articles/visual_business_intelligence/rules_for_using_color.pdf
|
||||
model.DefaultColors = new[]
|
||||
{
|
||||
OxyColor.FromRgb(114, 114, 114),
|
||||
OxyColor.FromRgb(241, 89, 95),
|
||||
OxyColor.FromRgb(121, 195, 106),
|
||||
OxyColor.FromRgb(89, 154, 211),
|
||||
OxyColor.FromRgb(249, 166, 90),
|
||||
OxyColor.FromRgb(158, 102, 171),
|
||||
OxyColor.FromRgb(205, 112, 88),
|
||||
OxyColor.FromRgb(215, 127, 179)
|
||||
};
|
||||
|
||||
var r = new Random(37);
|
||||
for (var i = 0; i < model.DefaultColors.Count; i++)
|
||||
{
|
||||
var columnSeries = new BarSeries();
|
||||
columnSeries.Items.Add(new BarItem(50 + r.Next(50)));
|
||||
columnSeries.Items.Add(new BarItem(40 + r.Next(50)));
|
||||
model.Series.Add(columnSeries);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#539104: Brewer colors (4)")]
|
||||
public static PlotModel BrewerColors4()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Brewer colors (Accent scheme)",
|
||||
};
|
||||
|
||||
model.Axes.Add(new CategoryAxis { Position = AxisPosition.Bottom });
|
||||
|
||||
// See http://colorbrewer2.org/?type=qualitative&scheme=Accent&n=4
|
||||
model.DefaultColors = new[]
|
||||
{
|
||||
OxyColor.FromRgb(127, 201, 127),
|
||||
OxyColor.FromRgb(190, 174, 212),
|
||||
OxyColor.FromRgb(253, 192, 134),
|
||||
OxyColor.FromRgb(255, 255, 153)
|
||||
};
|
||||
|
||||
var r = new Random(37);
|
||||
for (var i = 0; i < model.DefaultColors.Count; i++)
|
||||
{
|
||||
var columnSeries = new BarSeries();
|
||||
columnSeries.Items.Add(new BarItem(50 + r.Next(50)));
|
||||
columnSeries.Items.Add(new BarItem(40 + r.Next(50)));
|
||||
model.Series.Add(columnSeries);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#539104: Brewer colors (6)")]
|
||||
public static PlotModel BrewerColors6()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Brewer colors (Paired scheme)",
|
||||
};
|
||||
|
||||
model.Axes.Add(new CategoryAxis { Position = AxisPosition.Bottom });
|
||||
|
||||
// See http://colorbrewer2.org/?type=qualitative&scheme=Paired&n=6
|
||||
model.DefaultColors = new[]
|
||||
{
|
||||
OxyColor.FromRgb(166, 206, 227),
|
||||
OxyColor.FromRgb(31, 120, 180),
|
||||
OxyColor.FromRgb(178, 223, 138),
|
||||
OxyColor.FromRgb(51, 160, 44),
|
||||
OxyColor.FromRgb(251, 154, 153),
|
||||
OxyColor.FromRgb(227, 26, 28)
|
||||
};
|
||||
|
||||
var r = new Random(37);
|
||||
for (var i = 0; i < model.DefaultColors.Count; i++)
|
||||
{
|
||||
var columnSeries = new BarSeries();
|
||||
columnSeries.Items.Add(new BarItem(50 + r.Next(50)));
|
||||
columnSeries.Items.Add(new BarItem(40 + r.Next(50)));
|
||||
model.Series.Add(columnSeries);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#542701: Same color of LineSeries and axis title & labels")]
|
||||
public static PlotModel SameColorOfLineSeriesAndAxisTitleAndLabels()
|
||||
{
|
||||
var model = new PlotModel { Title = "Same color of LineSeries and axis title & labels" };
|
||||
var color = OxyColors.IndianRed;
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "Axis 1", TitleColor = color, TextColor = color });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Series.Add(new LineSeries { Title = "LineSeries 1", Color = color, ItemsSource = new[] { new DataPoint(0, 0), new DataPoint(10, 3), new DataPoint(20, 2) } });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("#549839: Polar plot with custom arrow series")]
|
||||
public static PlotModel PolarPlotWithArrows()
|
||||
{
|
||||
var model = new PlotModel { Title = "Custom arrow series", PlotType = PlotType.Polar, PlotAreaBorderColor = OxyColors.Undefined };
|
||||
model.Axes.Add(new AngleAxis { Minimum = 0, Maximum = 360, MajorStep = 30, MinorStep = 30, MajorGridlineStyle = LineStyle.Dash });
|
||||
model.Axes.Add(new MagnitudeAxis { Minimum = 0, Maximum = 5, MajorStep = 1, MinorStep = 1, Angle = 90, MajorGridlineStyle = LineStyle.Dash });
|
||||
model.Series.Add(new ArrowSeries549839 { EndPoint = new DataPoint(1, 40) });
|
||||
model.Series.Add(new ArrowSeries549839 { EndPoint = new DataPoint(2, 75) });
|
||||
model.Series.Add(new ArrowSeries549839 { EndPoint = new DataPoint(3, 110) });
|
||||
model.Series.Add(new ArrowSeries549839 { EndPoint = new DataPoint(4, 140) });
|
||||
model.Series.Add(new ArrowSeries549839 { EndPoint = new DataPoint(5, 180) });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("MarkerType = Circle problem")]
|
||||
public static PlotModel MarkerTypeCircleProblem()
|
||||
{
|
||||
var plotModel = new PlotModel { PlotType = PlotType.Cartesian, PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
|
||||
var l = new Legend
|
||||
{
|
||||
LegendSymbolLength = 30
|
||||
};
|
||||
|
||||
var xaxis = new DateTimeAxis
|
||||
{
|
||||
Position = AxisPosition.Bottom,
|
||||
TickStyle = TickStyle.None,
|
||||
AxislineStyle = LineStyle.Solid,
|
||||
AxislineColor = OxyColor.FromRgb(153, 153, 153),
|
||||
StringFormat = CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(1) + "d HH",
|
||||
IntervalType = DateTimeIntervalType.Hours
|
||||
};
|
||||
|
||||
var yaxis = new LinearAxis
|
||||
{
|
||||
Position = AxisPosition.Left,
|
||||
Minimum = 0.001f,
|
||||
Maximum = 3,
|
||||
MajorGridlineStyle = LineStyle.Solid,
|
||||
TickStyle = TickStyle.None,
|
||||
IntervalLength = 50
|
||||
};
|
||||
|
||||
plotModel.Axes.Add(xaxis);
|
||||
plotModel.Axes.Add(yaxis);
|
||||
|
||||
var series1 = new LineSeries
|
||||
{
|
||||
Color = OxyColor.FromRgb(44, 169, 173),
|
||||
StrokeThickness = 1,
|
||||
MarkerType = MarkerType.Circle,
|
||||
MarkerStroke = OxyColors.Blue,
|
||||
MarkerFill = OxyColors.SkyBlue,
|
||||
// MarkerStrokeThickness = 5,
|
||||
MarkerSize = 2,
|
||||
DataFieldX = "Date",
|
||||
DataFieldY = "Value",
|
||||
TrackerFormatString = "Date: {2:d HH}
Value: {4}"
|
||||
};
|
||||
|
||||
series1.Points.Add(new DataPoint(0.1, 0.7));
|
||||
series1.Points.Add(new DataPoint(0.6, 0.9));
|
||||
series1.Points.Add(new DataPoint(1.0, 0.85));
|
||||
series1.Points.Add(new DataPoint(1.4, 0.95));
|
||||
series1.Points.Add(new DataPoint(1.8, 1.2));
|
||||
series1.Points.Add(new DataPoint(2.2, 1.7));
|
||||
series1.Points.Add(new DataPoint(2.6, 1.7));
|
||||
series1.Points.Add(new DataPoint(3.0, 0.7));
|
||||
|
||||
plotModel.Series.Add(series1);
|
||||
|
||||
return plotModel;
|
||||
}
|
||||
|
||||
private class ArrowSeries549839 : XYAxisSeries
|
||||
{
|
||||
private OxyColor defaultColor;
|
||||
|
||||
public ArrowSeries549839()
|
||||
{
|
||||
this.Color = OxyColors.Automatic;
|
||||
this.StrokeThickness = 2;
|
||||
}
|
||||
|
||||
public DataPoint StartPoint { get; set; }
|
||||
|
||||
public DataPoint EndPoint { get; set; }
|
||||
|
||||
public OxyColor Color { get; set; }
|
||||
|
||||
public double StrokeThickness { get; set; }
|
||||
|
||||
protected override void SetDefaultValues()
|
||||
{
|
||||
if (this.Color.IsAutomatic())
|
||||
{
|
||||
this.defaultColor = this.PlotModel.GetDefaultColor();
|
||||
}
|
||||
}
|
||||
|
||||
public OxyColor ActualColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Color.GetActualColor(this.defaultColor);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Render(IRenderContext rc)
|
||||
{
|
||||
// transform to screen coordinates
|
||||
var p0 = this.Transform(this.StartPoint);
|
||||
var p1 = this.Transform(this.EndPoint);
|
||||
|
||||
var direction = p1 - p0;
|
||||
var normal = new ScreenVector(direction.Y, -direction.X);
|
||||
|
||||
// the end points of the arrow head, scaled by length of arrow
|
||||
var p2 = p1 - (direction * 0.2) + (normal * 0.1);
|
||||
var p3 = p1 - (direction * 0.2) - (normal * 0.1);
|
||||
|
||||
// draw the line segments
|
||||
rc.DrawLineSegments(new[] { p0, p1, p1, p2, p1, p3 }, this.ActualColor, this.StrokeThickness, this.EdgeRenderingMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Source/Examples/ExampleLibrary/Example.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="Example.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an example.
|
||||
/// </summary>
|
||||
public class Example
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Example"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <param name="controller">The controller.</param>
|
||||
public Example(PlotModel model, IPlotController controller = null)
|
||||
{
|
||||
this.Model = model;
|
||||
this.Controller = controller;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the controller.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The controller.
|
||||
/// </value>
|
||||
public IPlotController Controller { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the model.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The model.
|
||||
/// </value>
|
||||
public PlotModel Model { get; private set; }
|
||||
}
|
||||
}
|
||||
27
Source/Examples/ExampleLibrary/ExampleFlags.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ExampleFlags.cs" company="OxyPlot">
|
||||
// Copyright (c) 2020 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Properties of an example.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ExampleFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// Transpose the axes, so that horizontal axes become vertical and vice versa.
|
||||
/// </summary>
|
||||
Transpose = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Reverse the axes, so that their start and end positions are mirrored within the plot area.
|
||||
/// </summary>
|
||||
Reverse = 2,
|
||||
}
|
||||
}
|
||||
313
Source/Examples/ExampleLibrary/ExampleInfo.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ExampleInfo.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using ExampleLibrary.Utilities;
|
||||
|
||||
using OxyPlot;
|
||||
|
||||
/// <summary>
|
||||
/// Provides information about an example.
|
||||
/// </summary>
|
||||
public class ExampleInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The method to invoke.
|
||||
/// </summary>
|
||||
private readonly MethodInfo method;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance was already initialized.
|
||||
/// </summary>
|
||||
private bool initialized;
|
||||
|
||||
/// <summary>
|
||||
/// The un-modified example.
|
||||
/// </summary>
|
||||
private Example Example;
|
||||
|
||||
/// <summary>
|
||||
/// The examples for this example info.
|
||||
/// </summary>
|
||||
private Dictionary<ExampleFlags, Example> examples;
|
||||
|
||||
/// <summary>
|
||||
/// The options supported by this example.
|
||||
/// </summary>
|
||||
private ExampleFlags exampleSupport;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExampleInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="category">The category.</param>
|
||||
/// <param name="title">The title.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <param name="method">The method.</param>
|
||||
/// <param name="excludeFromAutomatedTests">A value indiciating whether the example should be excluded from automated tests.</param>
|
||||
public ExampleInfo(string category, string title, string[] tags, MethodInfo method, bool excludeFromAutomatedTests)
|
||||
{
|
||||
this.Category = category;
|
||||
this.Title = title;
|
||||
this.Tags = tags;
|
||||
this.method = method;
|
||||
this.ExcludeFromAutomatedTests = excludeFromAutomatedTests;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the category.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The category.
|
||||
/// </value>
|
||||
public string Category { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the code.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The code.
|
||||
/// </value>
|
||||
public string Code => this.PlotModel?.ToCode();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plot model is reversible.
|
||||
/// </summary>
|
||||
public bool IsReversible
|
||||
{
|
||||
get
|
||||
{
|
||||
this.EnsureInitialized();
|
||||
return exampleSupport.HasFlag(ExampleFlags.Reverse);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plot model is transposable.
|
||||
/// </summary>
|
||||
public bool IsTransposable
|
||||
{
|
||||
get
|
||||
{
|
||||
this.EnsureInitialized();
|
||||
return exampleSupport.HasFlag(ExampleFlags.Transpose);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the code for the example with the given flags.
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags for the example.</param>
|
||||
/// <returns>Code that produces the example.</returns>
|
||||
/// <remarks>Ignores unsupported flags.</remarks>
|
||||
public string GetCode(ExampleFlags flags)
|
||||
{
|
||||
return this.GetModel(flags)?.ToCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="PlotModel"/> for the example with the given flags.
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags for the example.</param>
|
||||
/// <returns>The <see cref="PlotModel"/>.</returns>
|
||||
/// <remarks>Ignores unsupported flags.</remarks>
|
||||
public PlotModel GetModel(ExampleFlags flags)
|
||||
{
|
||||
return this.GetExample(flags).Model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPlotController"/> for the example with the given flags.
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags for the example.</param>
|
||||
/// <returns>The <see cref="IPlotController"/>.</returns>
|
||||
/// <remarks>Ignores unsupported flags.</remarks>
|
||||
public IPlotController GetController(ExampleFlags flags)
|
||||
{
|
||||
return this.GetExample(flags).Controller;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Example"/> with the given flags.
|
||||
/// </summary>
|
||||
/// <param name="flags">The flags for the example.</param>
|
||||
/// <returns>The <see cref="Example"/>.</returns>
|
||||
/// <remarks>Ignores unsupported flags.</remarks>
|
||||
private Example GetExample(ExampleFlags flags)
|
||||
{
|
||||
this.EnsureInitialized();
|
||||
|
||||
// ignore flags we don't support
|
||||
flags = FilterFlags(flags);
|
||||
|
||||
if (!examples.TryGetValue(flags, out var example))
|
||||
{
|
||||
example = GetDefaultExample();
|
||||
|
||||
if (flags.HasFlag(ExampleFlags.Transpose))
|
||||
{
|
||||
example.Model.Transpose();
|
||||
}
|
||||
|
||||
if (flags.HasFlag(ExampleFlags.Reverse))
|
||||
{
|
||||
example.Model.ReverseAllAxes();
|
||||
}
|
||||
|
||||
examples[flags] = example;
|
||||
}
|
||||
|
||||
return example;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plot controller for the default example.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The plot controller.
|
||||
/// </value>
|
||||
public IPlotController PlotController
|
||||
{
|
||||
get
|
||||
{
|
||||
this.EnsureInitialized();
|
||||
return this.Example.Controller;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plot model for the default example.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The plot model.
|
||||
/// </value>
|
||||
public PlotModel PlotModel
|
||||
{
|
||||
get
|
||||
{
|
||||
this.EnsureInitialized();
|
||||
return this.Example.Model;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tags.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The tags.
|
||||
/// </value>
|
||||
public string[] Tags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indiciating whether this example should be excluded from automated tests.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if the example should be excluded from automated tests, otherwise <c>false</c>.
|
||||
/// </value>
|
||||
public bool ExcludeFromAutomatedTests { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the title.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The title.
|
||||
/// </value>
|
||||
public string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Title;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares <see cref="ExampleFlags"/> from the given parameters.
|
||||
/// </summary>
|
||||
/// <param name="transpose">Whether to set the <see cref="ExampleFlags.Transpose"/> flag.</param>
|
||||
/// <param name="reverse">Whether to set the <see cref="ExampleFlags.Reverse"/> flag.</param>
|
||||
/// <returns>The <see cref="ExampleFlags"/>.</returns>
|
||||
public static ExampleFlags PrepareFlags(bool transpose, bool reverse)
|
||||
{
|
||||
var flags = (ExampleFlags)0;
|
||||
|
||||
if (transpose)
|
||||
{
|
||||
flags |= ExampleFlags.Transpose;
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
flags |= ExampleFlags.Reverse;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this instance if it is not already initialized.
|
||||
/// </summary>
|
||||
private void EnsureInitialized()
|
||||
{
|
||||
if (this.initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
this.examples = new Dictionary<ExampleFlags, Example>();
|
||||
|
||||
this.Example = GetDefaultExample();
|
||||
|
||||
this.exampleSupport = PrepareFlags(this.Example.Model?.IsTransposable() == true, this.Example.Model?.IsReversible() == true);
|
||||
|
||||
// remember the 'default' model: loads the transposed/reversed ones as we need them
|
||||
this.examples.Add(PrepareFlags(false, false), this.Example);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new instance of the default example.
|
||||
/// </summary>
|
||||
/// <returns>An <see cref="Example"/>.</returns>
|
||||
private Example GetDefaultExample()
|
||||
{
|
||||
var result = this.method.Invoke(null, null);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
return new Example(null, null);
|
||||
}
|
||||
if (result is PlotModel plotModel)
|
||||
{
|
||||
return new Example(plotModel, null);
|
||||
}
|
||||
else if (result is Example example)
|
||||
{
|
||||
return example;
|
||||
}
|
||||
|
||||
throw new Exception($"Unsupport type returned by example method for example {Category} > {Title}: {result.GetType().FullName}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters unsupported flags from the given flags.
|
||||
/// </summary>
|
||||
/// <param name="flags">The original set of flags.</param>
|
||||
/// <returns>The filtered flags.</returns>
|
||||
private ExampleFlags FilterFlags(ExampleFlags flags)
|
||||
{
|
||||
return flags & exampleSupport;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Source/Examples/ExampleLibrary/ExampleLibrary.csproj
Normal file
@@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;net462;net6.0;net7.0</TargetFrameworks>
|
||||
<PackageId>OxyPlot.ExampleLibrary</PackageId>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Description>Example models for OxyPlot.</Description>
|
||||
<PackageTags>plotting plot charting chart</PackageTags>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\DodgyContourData.tsv" />
|
||||
<None Remove="Resources\X.txt" />
|
||||
<None Remove="Resources\Y.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Bergensbanen.csv" />
|
||||
<EmbeddedResource Include="Resources\DodgyContourData.tsv" />
|
||||
<EmbeddedResource Include="Resources\OxyPlot.png" />
|
||||
<EmbeddedResource Include="Resources\west0479.mtx" />
|
||||
<EmbeddedResource Include="Resources\WorldPopulation.xml" />
|
||||
<EmbeddedResource Include="Resources\X.txt" />
|
||||
<EmbeddedResource Include="Resources\Y.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Net.Requests" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XmlSerializer" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OxyPlot\OxyPlot.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
BIN
Source/Examples/ExampleLibrary/ExampleLibrary.snk
Normal file
104
Source/Examples/ExampleLibrary/Examples.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="Examples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all examples in the assembly.
|
||||
/// </summary>
|
||||
public static class Examples
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets all examples in the specified category.
|
||||
/// </summary>
|
||||
/// <param name="categoryType">The type of the category.</param>
|
||||
public static IEnumerable<ExampleInfo> GetCategory(Type categoryType)
|
||||
{
|
||||
var typeInfo = categoryType.GetTypeInfo();
|
||||
var examplesAttribute = typeInfo.GetCustomAttributes<ExamplesAttribute>().FirstOrDefault();
|
||||
var examplesTags = typeInfo.GetCustomAttributes<TagsAttribute>().FirstOrDefault() ?? new TagsAttribute();
|
||||
|
||||
var types = new List<Type>();
|
||||
var baseType = typeInfo;
|
||||
while (baseType != null)
|
||||
{
|
||||
types.Add(baseType.AsType());
|
||||
baseType = baseType.BaseType?.GetTypeInfo();
|
||||
}
|
||||
|
||||
foreach (var t in types)
|
||||
{
|
||||
foreach (var method in t.GetRuntimeMethods())
|
||||
{
|
||||
var exampleAttribute = method.GetCustomAttributes<ExampleAttribute>().FirstOrDefault();
|
||||
if (exampleAttribute != null)
|
||||
{
|
||||
var exampleTags = method.GetCustomAttributes<TagsAttribute>().FirstOrDefault() ?? new TagsAttribute();
|
||||
var tags = new List<string>(examplesTags.Tags);
|
||||
tags.AddRange(exampleTags.Tags);
|
||||
yield return
|
||||
new ExampleInfo(
|
||||
examplesAttribute.Category,
|
||||
exampleAttribute.Title,
|
||||
tags.ToArray(),
|
||||
method,
|
||||
exampleAttribute.ExcludeFromAutomatedTests);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all examples.
|
||||
/// </summary>
|
||||
public static IEnumerable<ExampleInfo> GetList()
|
||||
{
|
||||
foreach (var type in typeof(Examples).GetTypeInfo().Assembly.DefinedTypes)
|
||||
{
|
||||
if (!type.GetCustomAttributes<ExamplesAttribute>().Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var example in GetCategory(type.AsType()))
|
||||
{
|
||||
yield return example;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all examples suitable for automated test.
|
||||
/// </summary>
|
||||
public static IEnumerable<ExampleInfo> GetListForAutomatedTest()
|
||||
{
|
||||
return GetList().Where(ex => !ex.ExcludeFromAutomatedTests);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first example of each category suitable for automated test.
|
||||
/// </summary>
|
||||
public static IEnumerable<ExampleInfo> GetFirstExampleOfEachCategoryForAutomatedTest()
|
||||
{
|
||||
return GetListForAutomatedTest()
|
||||
.GroupBy(example => example.Category)
|
||||
.Select(group => group.First());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the 'rendering capabilities' examples suitable for automated test.
|
||||
/// </summary>
|
||||
public static IEnumerable<ExampleInfo> GetRenderingCapabilitiesForAutomatedTest()
|
||||
{
|
||||
return GetCategory(typeof(RenderingCapabilities)).Where(ex => !ex.ExcludeFromAutomatedTests);
|
||||
}
|
||||
}
|
||||
}
|
||||
151
Source/Examples/ExampleLibrary/Examples/FilteringExamples.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="FilteringExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("Filtering data points")]
|
||||
public static class FilteringExamples
|
||||
{
|
||||
[Example("Filtering NaN points")]
|
||||
public static PlotModel FilteringInvalidPoints()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Filtering NaN points" };
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var ls1 = new LineSeries();
|
||||
ls1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
ls1.Points.Add(new DataPoint(1, 0));
|
||||
ls1.Points.Add(new DataPoint(2, 10));
|
||||
ls1.Points.Add(new DataPoint(double.NaN, 20));
|
||||
ls1.Points.Add(new DataPoint(3, 10));
|
||||
ls1.Points.Add(new DataPoint(4, 0));
|
||||
ls1.Points.Add(new DataPoint(4.5, double.NaN));
|
||||
ls1.Points.Add(new DataPoint(5, 0));
|
||||
ls1.Points.Add(new DataPoint(7, 7));
|
||||
ls1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
ls1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
ls1.Points.Add(new DataPoint(7, 0));
|
||||
ls1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
plot.Series.Add(ls1);
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("Filtering NaN points with AreaSeries")]
|
||||
public static PlotModel FilteringInvalidPointsAreaSeries()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Filtering NaN points in an AreaSeries" };
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var as1 = new AreaSeries();
|
||||
as1.Points.Add(new DataPoint(1, 0));
|
||||
as1.Points.Add(new DataPoint(2, 10));
|
||||
as1.Points.Add(new DataPoint(3, 10));
|
||||
as1.Points.Add(new DataPoint(4, 0));
|
||||
as1.Points.Add(new DataPoint(5, 0));
|
||||
as1.Points.Add(new DataPoint(6, 7));
|
||||
as1.Points.Add(new DataPoint(7, 7));
|
||||
as1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
as1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
as1.Points.Add(new DataPoint(8, 0));
|
||||
as1.Points.Add(new DataPoint(9, 0));
|
||||
as1.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
|
||||
as1.Points2.Add(new DataPoint(1, 10));
|
||||
as1.Points2.Add(new DataPoint(2, 110));
|
||||
as1.Points2.Add(new DataPoint(3, 110));
|
||||
as1.Points2.Add(new DataPoint(4, 10));
|
||||
as1.Points2.Add(new DataPoint(5, 10));
|
||||
as1.Points2.Add(new DataPoint(6, 17));
|
||||
as1.Points2.Add(new DataPoint(7, 17));
|
||||
as1.Points2.Add(new DataPoint(double.NaN, double.NaN));
|
||||
as1.Points2.Add(new DataPoint(double.NaN, double.NaN));
|
||||
as1.Points2.Add(new DataPoint(8, 10));
|
||||
as1.Points2.Add(new DataPoint(9, 10));
|
||||
as1.Points2.Add(new DataPoint(double.NaN, double.NaN));
|
||||
|
||||
plot.Series.Add(as1);
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
|
||||
[Example("Filtering undefined points")]
|
||||
public static PlotModel FilteringUndefinedPoints()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Filtering undefined points" };
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var ls1 = new LineSeries();
|
||||
ls1.Points.Add(DataPoint.Undefined);
|
||||
ls1.Points.Add(new DataPoint(1, 0));
|
||||
ls1.Points.Add(new DataPoint(2, 10));
|
||||
ls1.Points.Add(DataPoint.Undefined);
|
||||
ls1.Points.Add(new DataPoint(3, 10));
|
||||
ls1.Points.Add(new DataPoint(4, 0));
|
||||
ls1.Points.Add(DataPoint.Undefined);
|
||||
ls1.Points.Add(new DataPoint(5, 0));
|
||||
ls1.Points.Add(new DataPoint(7, 7));
|
||||
ls1.Points.Add(DataPoint.Undefined);
|
||||
ls1.Points.Add(DataPoint.Undefined);
|
||||
ls1.Points.Add(new DataPoint(7, 0));
|
||||
ls1.Points.Add(DataPoint.Undefined);
|
||||
plot.Series.Add(ls1);
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("Filtering invalid points (log axis)")]
|
||||
public static PlotModel FilteringInvalidPointsLog()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Filtering invalid points on logarithmic axes" };
|
||||
plot.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Bottom });
|
||||
plot.Axes.Add(new LogarithmicAxis { Position = AxisPosition.Left });
|
||||
|
||||
var ls = new LineSeries();
|
||||
ls.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
ls.Points.Add(new DataPoint(1, 1));
|
||||
ls.Points.Add(new DataPoint(10, 10));
|
||||
ls.Points.Add(new DataPoint(0, 20));
|
||||
ls.Points.Add(new DataPoint(100, 2));
|
||||
ls.Points.Add(new DataPoint(1000, 12));
|
||||
ls.Points.Add(new DataPoint(4.5, 0));
|
||||
ls.Points.Add(new DataPoint(10000, 4));
|
||||
ls.Points.Add(new DataPoint(100000, 14));
|
||||
ls.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
ls.Points.Add(new DataPoint(1000000, 5));
|
||||
ls.Points.Add(new DataPoint(double.NaN, double.NaN));
|
||||
plot.Series.Add(ls);
|
||||
return plot;
|
||||
}
|
||||
|
||||
[Example("Filtering points outside (-1,1)")]
|
||||
public static PlotModel FilteringPointsOutsideRange()
|
||||
{
|
||||
var plot = new PlotModel { Title = "Filtering points outside (-1,1)" };
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, FilterMinValue = -1, FilterMaxValue = 1 });
|
||||
plot.Axes.Add(new LinearAxis { Position = AxisPosition.Left, FilterMinValue = -1, FilterMaxValue = 1 });
|
||||
|
||||
var ls = new LineSeries();
|
||||
for (double i = 0; i < 200; i += 0.01)
|
||||
{
|
||||
ls.Points.Add(new DataPoint(0.01 * i * Math.Sin(i), 0.01 * i * Math.Cos(i)));
|
||||
}
|
||||
|
||||
plot.Series.Add(ls);
|
||||
return plot;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Source/Examples/ExampleLibrary/Examples/ItemsSourceExamples.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="ItemsSourceExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Evaluates a chaotic function.
|
||||
// </summary>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("ItemsSource")]
|
||||
public class ItemsSourceExamples
|
||||
{
|
||||
private static int n = 100000;
|
||||
[Example("List<DataPoint>")]
|
||||
public static PlotModel UsingIDataPoint()
|
||||
{
|
||||
var points = new List<DataPoint>(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var x = (double)i / (n - 1);
|
||||
points.Add(new DataPoint(x, y(x)));
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "Using IDataPoint" };
|
||||
model.Series.Add(new LineSeries { ItemsSource = points });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Items implementing IDataPointProvider")]
|
||||
public static PlotModel UsingIDataPointProvider()
|
||||
{
|
||||
var points = new List<PointType1>(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var x = (double)i / (n - 1);
|
||||
points.Add(new PointType1(x, y(x)));
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "Items implementing IDataPointProvider" };
|
||||
model.Series.Add(new LineSeries { ItemsSource = points });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Mapping property")]
|
||||
public static PlotModel UsingMappingProperty()
|
||||
{
|
||||
var points = new List<PointType2>(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var x = (double)i / (n - 1);
|
||||
points.Add(new PointType2(x, y(x)));
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "Using Mapping property" };
|
||||
model.Series.Add(
|
||||
new LineSeries
|
||||
{
|
||||
ItemsSource = points,
|
||||
Mapping = item => new DataPoint(((PointType2)item).Abscissa, ((PointType2)item).Ordinate)
|
||||
});
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Using reflection (slow)")]
|
||||
public static PlotModel UsingReflection()
|
||||
{
|
||||
var points = new List<PointType2>(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var x = (double)i / (n - 1);
|
||||
points.Add(new PointType2(x, y(x)));
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "Using reflection (slow)" };
|
||||
model.Series.Add(new LineSeries { ItemsSource = points, DataFieldX = "Abscissa", DataFieldY = "Ordinate" });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Using reflection with path (slow)")]
|
||||
public static PlotModel UsingReflectionPath()
|
||||
{
|
||||
var points = new List<ItemType3>(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var x = (double)i / (n - 1);
|
||||
points.Add(new ItemType3(x, y(x)));
|
||||
}
|
||||
|
||||
var model = new PlotModel { Title = "Using reflection with path (slow)" };
|
||||
model.Series.Add(new LineSeries { ItemsSource = points, DataFieldX = "Point.X", DataFieldY = "Point.Y" });
|
||||
return model;
|
||||
}
|
||||
|
||||
private class PointType1 : IDataPointProvider, ICodeGenerating
|
||||
{
|
||||
public PointType1(double abscissa, double ordinate)
|
||||
{
|
||||
this.Abscissa = abscissa;
|
||||
this.Ordinate = ordinate;
|
||||
}
|
||||
|
||||
public double Abscissa { get; private set; }
|
||||
|
||||
public double Ordinate { get; private set; }
|
||||
|
||||
public DataPoint GetDataPoint()
|
||||
{
|
||||
return new DataPoint(Abscissa, Ordinate);
|
||||
}
|
||||
|
||||
public string ToCode()
|
||||
{
|
||||
return CodeGenerator.FormatConstructor(this.GetType(), "{0},{1}", this.Abscissa, this.Ordinate);
|
||||
}
|
||||
}
|
||||
|
||||
private class PointType2
|
||||
{
|
||||
public PointType2(double abscissa, double ordinate)
|
||||
{
|
||||
this.Abscissa = abscissa;
|
||||
this.Ordinate = ordinate;
|
||||
}
|
||||
|
||||
public double Abscissa { get; private set; }
|
||||
|
||||
public double Ordinate { get; private set; }
|
||||
}
|
||||
|
||||
private class ItemType3
|
||||
{
|
||||
public ItemType3(double x, double y)
|
||||
{
|
||||
this.Point = new ScreenPoint(x, y);
|
||||
}
|
||||
|
||||
public ScreenPoint Point { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates a chaotic function.
|
||||
/// </summary>
|
||||
/// <param name="x">The x value.</param>
|
||||
/// <returns>A y value.</returns>
|
||||
private static double y(double x)
|
||||
{
|
||||
// http://computing.dcu.ie/~humphrys/Notes/Neural/chaos.html
|
||||
return Math.Sin(3 / x) * Math.Sin(5 / (1 - x));
|
||||
}
|
||||
}
|
||||
}
|
||||
496
Source/Examples/ExampleLibrary/Examples/LegendExamples.cs
Normal file
@@ -0,0 +1,496 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="LegendExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("Legends")]
|
||||
public static class LegendExamples
|
||||
{
|
||||
[Example("Legend at right top inside")]
|
||||
public static PlotModel LegendRightTopInside()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Inside,
|
||||
LegendPosition = LegendPosition.RightTop,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend at right top outside")]
|
||||
public static PlotModel LegendRightTopOutside()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.RightTop,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend at BottomLeft outside horizontal")]
|
||||
public static PlotModel LegendBottomLeftHorizontal()
|
||||
{
|
||||
var model = CreateModel(4);
|
||||
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.BottomLeft,
|
||||
LegendOrientation = LegendOrientation.Horizontal,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend at TopLeft outside vertical")]
|
||||
public static PlotModel LegendTopLeftVertical()
|
||||
{
|
||||
var model = CreateModel(4);
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.TopLeft,
|
||||
LegendOrientation = LegendOrientation.Vertical,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend at default position")]
|
||||
public static PlotModel LegendDefault()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend();
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LegendItemSpacing (only for horizontal orientation)")]
|
||||
public static PlotModel LegendItemSpacing()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendItemSpacing = 100,
|
||||
LegendPosition = LegendPosition.BottomLeft,
|
||||
LegendOrientation = LegendOrientation.Horizontal,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LegendLineSpacing (vertical legend orientation)")]
|
||||
public static PlotModel LegendLineSpacingVertical()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendLineSpacing = 30,
|
||||
LegendPosition = LegendPosition.TopLeft,
|
||||
LegendOrientation = LegendOrientation.Vertical,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LegendLineSpacing (horizontal legend orientation)")]
|
||||
public static PlotModel LegendLineSpacingHorizontal()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendLineSpacing = 30,
|
||||
LegendPosition = LegendPosition.TopLeft,
|
||||
LegendOrientation = LegendOrientation.Horizontal,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LegendColumnSpacing (only for vertical orientation)")]
|
||||
public static PlotModel LegendColumnSpacing()
|
||||
{
|
||||
var model = CreateModel(60);
|
||||
var l = new Legend
|
||||
{
|
||||
LegendColumnSpacing = 100,
|
||||
LegendPosition = LegendPosition.TopRight,
|
||||
LegendOrientation = LegendOrientation.Vertical,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Hidden Legend")]
|
||||
public static PlotModel LegendHidden()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
model.Legends.Add(l);
|
||||
|
||||
model.IsLegendVisible = false;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Grayscale colors")]
|
||||
public static PlotModel LegendGrayscale()
|
||||
{
|
||||
var model = CreateModel();
|
||||
model.DefaultColors = new List<OxyColor> { OxyColors.Black, OxyColors.Gray };
|
||||
var l = new Legend
|
||||
{
|
||||
LegendSymbolLength = 32,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Clipped legends")]
|
||||
public static PlotModel ClippedLegends()
|
||||
{
|
||||
var model = CreateModel(1);
|
||||
model.Series[0].Title = "1234567890 abcdefghijklmnopqrstuvwxyzæøå ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ 1234567890 abcdefghijklmnopqrstuvwxyzæøå ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ";
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Inside,
|
||||
LegendPosition = LegendPosition.RightTop,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Clipped legends RightTop outside with MaxWidth")]
|
||||
public static PlotModel ClippedLegendsOutside()
|
||||
{
|
||||
var model = ClippedLegends();
|
||||
model.Legends[0].LegendPlacement = LegendPlacement.Outside;
|
||||
model.Legends[0].LegendPosition = LegendPosition.RightTop;
|
||||
model.Legends[0].LegendMaxWidth = 200;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Clipped legends TopRight outside")]
|
||||
public static PlotModel ClippedLegendsRight()
|
||||
{
|
||||
var model = ClippedLegends();
|
||||
model.Legends[0].LegendPlacement = LegendPlacement.Outside;
|
||||
model.Legends[0].LegendPosition = LegendPosition.TopRight;
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LegendMaxHeight (vertical legend orientation)")]
|
||||
public static PlotModel LegendBottomCenterOutsideWithMaxHeight()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.BottomCenter,
|
||||
LegendOrientation = LegendOrientation.Vertical,
|
||||
LegendMaxHeight = 75.0,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend with DefaultFontSize")]
|
||||
public static PlotModel LegendDefaultFontSize()
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend
|
||||
{
|
||||
LegendFontSize = double.NaN,
|
||||
LegendTitle = "Title in DefaultFontSize",
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
model.DefaultFontSize = 20;
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend with grouped Series Horizontal")]
|
||||
public static PlotModel SingleLegendWithSeriesGroupsHorizontal()
|
||||
{
|
||||
var model = CreateModel(21);
|
||||
for (int i = 0; i < 7; i++)
|
||||
model.Series[i].SeriesGroupName = "group 1";
|
||||
for (int i = 7; i < 14; i++)
|
||||
model.Series[i].SeriesGroupName = "group 2";
|
||||
for (int i = 14; i < 21; i++)
|
||||
model.Series[i].SeriesGroupName = "group 3";
|
||||
|
||||
var l = new Legend
|
||||
{
|
||||
LegendFontSize = double.NaN,
|
||||
LegendTitle = "Legend with groups of Series",
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
GroupNameFont="Segoe UI Black",
|
||||
LegendPosition = LegendPosition.TopLeft,
|
||||
LegendOrientation = LegendOrientation.Horizontal
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend with grouped Series")]
|
||||
public static PlotModel SingleLegendWithSeriesGroups()
|
||||
{
|
||||
var model = CreateModel(21);
|
||||
for (int i = 0; i < 7; i++)
|
||||
model.Series[i].SeriesGroupName = "group 1";
|
||||
for (int i = 7; i < 14; i++)
|
||||
model.Series[i].SeriesGroupName = "group 2";
|
||||
for (int i = 14; i < 21; i++)
|
||||
model.Series[i].SeriesGroupName = "group 3";
|
||||
|
||||
var l = new Legend
|
||||
{
|
||||
LegendFontSize = double.NaN,
|
||||
LegendTitle = "Legend with groups of Series",
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend with grouped Series and MaxHeight")]
|
||||
public static PlotModel SingleLegendWithSeriesGroupsMaxHeight()
|
||||
{
|
||||
var model = CreateModel(21);
|
||||
for (int i = 0; i < 7; i++)
|
||||
model.Series[i].SeriesGroupName = "group 1";
|
||||
for (int i = 7; i < 14; i++)
|
||||
model.Series[i].SeriesGroupName = "group 2";
|
||||
for (int i = 14; i < 21; i++)
|
||||
model.Series[i].SeriesGroupName = "group 3";
|
||||
|
||||
var l = new Legend
|
||||
{
|
||||
LegendFontSize = double.NaN,
|
||||
LegendTitle = "Legend with groups of Series",
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
LegendMaxHeight = 275.0
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Multiple Legends with grouped Series")]
|
||||
public static PlotModel MultipleLegendsWithSeriesGroups()
|
||||
{
|
||||
var model = CreateModel(21);
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
model.Series[i].SeriesGroupName = "group 1";
|
||||
model.Series[i].LegendKey = "Legend 1";
|
||||
}
|
||||
for (int i = 7; i < 14; i++)
|
||||
{
|
||||
model.Series[i].SeriesGroupName = "group 2";
|
||||
model.Series[i].LegendKey = "Legend 1";
|
||||
}
|
||||
for (int i = 14; i < 21; i++)
|
||||
{
|
||||
model.Series[i].SeriesGroupName = "group 3";
|
||||
model.Series[i].LegendKey = "Legend 2";
|
||||
}
|
||||
|
||||
var l1 = new Legend
|
||||
{
|
||||
Key="Legend 1",
|
||||
LegendFontSize = double.NaN,
|
||||
LegendTitle = "Legend 1 Series",
|
||||
LegendPlacement = LegendPlacement.Inside,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
var l2 = new Legend
|
||||
{
|
||||
Key = "Legend 2",
|
||||
LegendFontSize = double.NaN,
|
||||
LegendTitle = "Legend 2 Series",
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendBackground = OxyColor.FromAColor(200, OxyColors.White),
|
||||
LegendBorder = OxyColors.Black,
|
||||
};
|
||||
|
||||
model.Legends.Add(l1);
|
||||
model.Legends.Add(l2);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Full width legend")]
|
||||
public static PlotModel LegendFullWidth()
|
||||
{
|
||||
var model = CreateModel(21);
|
||||
|
||||
var l1 = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.TopCenter,
|
||||
LegendOrientation = LegendOrientation.Horizontal,
|
||||
AllowUseFullExtent = true,
|
||||
};
|
||||
|
||||
var l2 = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.BottomCenter,
|
||||
LegendOrientation = LegendOrientation.Horizontal,
|
||||
AllowUseFullExtent = true,
|
||||
};
|
||||
|
||||
model.PlotMargins = new OxyThickness(50);
|
||||
|
||||
model.Legends.Add(l1);
|
||||
model.Legends.Add(l2);
|
||||
|
||||
model.InvalidatePlot(true);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Full height legend")]
|
||||
public static PlotModel LegendFullHeight()
|
||||
{
|
||||
var model = CreateModel(21);
|
||||
|
||||
var l1 = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.LeftTop,
|
||||
LegendOrientation = LegendOrientation.Vertical,
|
||||
AllowUseFullExtent = true,
|
||||
};
|
||||
|
||||
var l2 = new Legend
|
||||
{
|
||||
LegendPlacement = LegendPlacement.Outside,
|
||||
LegendPosition = LegendPosition.RightTop,
|
||||
LegendOrientation = LegendOrientation.Vertical,
|
||||
AllowUseFullExtent = true,
|
||||
};
|
||||
|
||||
model.Legends.Add(l1);
|
||||
model.Legends.Add(l2);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Legend showing invisible series")]
|
||||
public static PlotModel LegendShowingInivisbleSeries()
|
||||
{
|
||||
return CreateModelWithInivisbleSeries(true);
|
||||
}
|
||||
|
||||
[Example("Legend not showing invisible series")]
|
||||
public static PlotModel LegendNotShowingInivisbleSeries()
|
||||
{
|
||||
return CreateModelWithInivisbleSeries(false);
|
||||
}
|
||||
|
||||
private static PlotModel CreateModelWithInivisbleSeries(bool showInvisibleSeries)
|
||||
{
|
||||
var model = CreateModel();
|
||||
var l = new Legend()
|
||||
{
|
||||
ShowInvisibleSeries = showInvisibleSeries,
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
for (int i = 0; i < model.Series.Count; i += 2)
|
||||
{
|
||||
model.Series[i].IsVisible = false;
|
||||
}
|
||||
|
||||
model.InvalidatePlot(false);
|
||||
return model;
|
||||
}
|
||||
|
||||
private static PlotModel CreateModel(int n = 20)
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries" };
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
var s = new LineSeries { Title = "Series " + i };
|
||||
model.Series.Add(s);
|
||||
for (double x = 0; x < 2 * Math.PI; x += 0.1)
|
||||
{
|
||||
s.Points.Add(new DataPoint(x, (Math.Sin(x * i) / i) + i));
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
661
Source/Examples/ExampleLibrary/Examples/MouseEventExamples.cs
Normal file
@@ -0,0 +1,661 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="MouseEventExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("Mouse Events")]
|
||||
public class MouseEventExamples
|
||||
{
|
||||
[Example("PlotModel mouse events")]
|
||||
public static PlotModel MouseEvents()
|
||||
{
|
||||
var model = new PlotModel { Title = "Mouse events", Subtitle = "Left click and drag" };
|
||||
var yaxis = new LinearAxis { Position = AxisPosition.Left, Minimum = -1, Maximum = 1 };
|
||||
var xaxis = new LinearAxis { Position = AxisPosition.Bottom, Minimum = -1, Maximum = 1 };
|
||||
model.Axes.Add(yaxis);
|
||||
model.Axes.Add(xaxis);
|
||||
|
||||
LineSeries s1 = null;
|
||||
|
||||
// Subscribe to the mouse down event on the line series
|
||||
model.MouseDown += (s, e) =>
|
||||
{
|
||||
// only handle the left mouse button (right button can still be used to pan)
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
// Add a line series
|
||||
s1 = new LineSeries
|
||||
{
|
||||
Title = "LineSeries" + (model.Series.Count + 1),
|
||||
MarkerType = MarkerType.None,
|
||||
StrokeThickness = 2
|
||||
};
|
||||
s1.Points.Add(xaxis.InverseTransform(e.Position.X, e.Position.Y, yaxis));
|
||||
model.Series.Add(s1);
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
model.MouseMove += (s, e) =>
|
||||
{
|
||||
if (s1 != null)
|
||||
{
|
||||
s1.Points.Add(xaxis.InverseTransform(e.Position.X, e.Position.Y, yaxis));
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
model.MouseUp += (s, e) =>
|
||||
{
|
||||
if (s1 != null)
|
||||
{
|
||||
s1 = null;
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("MouseDown event and HitTestResult")]
|
||||
public static PlotModel MouseDownEventHitTestResult()
|
||||
{
|
||||
var model = new PlotModel { Title = "MouseDown HitTestResult", Subtitle = "Reports the index of the nearest point." };
|
||||
|
||||
var s1 = new LineSeries();
|
||||
s1.Points.Add(new DataPoint(0, 10));
|
||||
s1.Points.Add(new DataPoint(10, 40));
|
||||
s1.Points.Add(new DataPoint(40, 20));
|
||||
s1.Points.Add(new DataPoint(60, 30));
|
||||
model.Series.Add(s1);
|
||||
s1.MouseDown += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "Index of nearest point in LineSeries: " + Math.Round(e.HitTestResult.Index);
|
||||
model.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
var s2 = new ScatterSeries();
|
||||
s2.Points.Add(new ScatterPoint(0, 15));
|
||||
s2.Points.Add(new ScatterPoint(10, 45));
|
||||
s2.Points.Add(new ScatterPoint(40, 25));
|
||||
s2.Points.Add(new ScatterPoint(60, 35));
|
||||
model.Series.Add(s2);
|
||||
s2.MouseDown += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "Index of nearest point in ScatterSeries: " + (int)e.HitTestResult.Index;
|
||||
model.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries and PlotModel MouseDown event")]
|
||||
public static PlotModel MouseDownEvent()
|
||||
{
|
||||
var model = new PlotModel { Title = "MouseDown", Subtitle = "Left click to edit or add points." };
|
||||
var l = new Legend
|
||||
{
|
||||
LegendSymbolLength = 40
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
// Add a line series
|
||||
var s1 = new LineSeries
|
||||
{
|
||||
Title = "LineSeries1",
|
||||
Color = OxyColors.SkyBlue,
|
||||
MarkerType = MarkerType.Circle,
|
||||
MarkerSize = 6,
|
||||
MarkerStroke = OxyColors.White,
|
||||
MarkerFill = OxyColors.SkyBlue,
|
||||
MarkerStrokeThickness = 1.5
|
||||
};
|
||||
s1.Points.Add(new DataPoint(0, 10));
|
||||
s1.Points.Add(new DataPoint(10, 40));
|
||||
s1.Points.Add(new DataPoint(40, 20));
|
||||
s1.Points.Add(new DataPoint(60, 30));
|
||||
model.Series.Add(s1);
|
||||
|
||||
int indexOfPointToMove = -1;
|
||||
|
||||
// Subscribe to the mouse down event on the line series
|
||||
s1.MouseDown += (s, e) =>
|
||||
{
|
||||
// only handle the left mouse button (right button can still be used to pan)
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
int indexOfNearestPoint = (int)Math.Round(e.HitTestResult.Index);
|
||||
var nearestPoint = s1.Transform(s1.Points[indexOfNearestPoint]);
|
||||
|
||||
// Check if we are near a point
|
||||
if ((nearestPoint - e.Position).Length < 10)
|
||||
{
|
||||
// Start editing this point
|
||||
indexOfPointToMove = indexOfNearestPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise create a point on the current line segment
|
||||
int i = (int)e.HitTestResult.Index + 1;
|
||||
s1.Points.Insert(i, s1.InverseTransform(e.Position));
|
||||
indexOfPointToMove = i;
|
||||
}
|
||||
|
||||
// Change the linestyle while editing
|
||||
s1.LineStyle = LineStyle.DashDot;
|
||||
|
||||
// Remember to refresh/invalidate of the plot
|
||||
model.InvalidatePlot(false);
|
||||
|
||||
// Set the event arguments to handled - no other handlers will be called.
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
s1.MouseMove += (s, e) =>
|
||||
{
|
||||
if (indexOfPointToMove >= 0)
|
||||
{
|
||||
// Move the point being edited.
|
||||
s1.Points[indexOfPointToMove] = s1.InverseTransform(e.Position);
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
s1.MouseUp += (s, e) =>
|
||||
{
|
||||
// Stop editing
|
||||
indexOfPointToMove = -1;
|
||||
s1.LineStyle = LineStyle.Solid;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
model.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
// Add a point to the line series.
|
||||
s1.Points.Add(s1.InverseTransform(e.Position));
|
||||
indexOfPointToMove = s1.Points.Count - 1;
|
||||
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Add arrow annotations")]
|
||||
public static PlotModel AddAnnotations()
|
||||
{
|
||||
var model = new PlotModel { Title = "Add arrow annotations", Subtitle = "Press and drag the left mouse button" };
|
||||
var xaxis = new LinearAxis { Position = AxisPosition.Bottom };
|
||||
var yaxis = new LinearAxis { Position = AxisPosition.Left };
|
||||
model.Axes.Add(xaxis);
|
||||
model.Axes.Add(yaxis);
|
||||
model.Series.Add(new FunctionSeries(x => Math.Sin(x / 4) * Math.Acos(Math.Sin(x)), 0, Math.PI * 8, 2000, "sin(x/4)*acos(sin(x))"));
|
||||
|
||||
ArrowAnnotation tmp = null;
|
||||
|
||||
// Add handlers to the PlotModel's mouse events
|
||||
model.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
// Create a new arrow annotation
|
||||
tmp = new ArrowAnnotation();
|
||||
tmp.StartPoint = tmp.EndPoint = xaxis.InverseTransform(e.Position.X, e.Position.Y, yaxis);
|
||||
model.Annotations.Add(tmp);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Handle mouse movements (note: this is only called when the mousedown event was handled)
|
||||
model.MouseMove += (s, e) =>
|
||||
{
|
||||
if (tmp != null)
|
||||
{
|
||||
// Modify the end point
|
||||
tmp.EndPoint = xaxis.InverseTransform(e.Position.X, e.Position.Y, yaxis);
|
||||
tmp.Text = string.Format("Y = {0:0.###}", tmp.EndPoint.Y);
|
||||
|
||||
// Redraw the plot
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
model.MouseUp += (s, e) =>
|
||||
{
|
||||
if (tmp != null)
|
||||
{
|
||||
tmp = null;
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineAnnotation")]
|
||||
public static PlotModel LineAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineAnnotation", Subtitle = "Click and drag the annotation line." };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 80 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
var la = new LineAnnotation { Type = LineAnnotationType.Vertical, X = 4 };
|
||||
la.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton != OxyMouseButton.Left)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
la.StrokeThickness *= 5;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
// Handle mouse movements (note: this is only called when the mousedown event was handled)
|
||||
la.MouseMove += (s, e) =>
|
||||
{
|
||||
la.X = la.InverseTransform(e.Position).X;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
la.MouseUp += (s, e) =>
|
||||
{
|
||||
la.StrokeThickness /= 5;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
model.Annotations.Add(la);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ArrowAnnotation")]
|
||||
public static PlotModel ArrowAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "ArrowAnnotation", Subtitle = "Click and drag the arrow." };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -40, Maximum = 60 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
|
||||
var arrow = new ArrowAnnotation { StartPoint = new DataPoint(8, 4), EndPoint = new DataPoint(0, 0), Text = "Move me!" };
|
||||
|
||||
var lastPoint = DataPoint.Undefined;
|
||||
bool moveStartPoint = false;
|
||||
bool moveEndPoint = false;
|
||||
var originalColor = OxyColors.White;
|
||||
|
||||
// Handle left mouse clicks
|
||||
arrow.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton != OxyMouseButton.Left)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lastPoint = arrow.InverseTransform(e.Position);
|
||||
moveStartPoint = e.HitTestResult.Index != 2;
|
||||
moveEndPoint = e.HitTestResult.Index != 1;
|
||||
originalColor = arrow.Color;
|
||||
arrow.Color = OxyColors.Red;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
// Handle mouse movements (note: this is only called when the mousedown event was handled)
|
||||
arrow.MouseMove += (s, e) =>
|
||||
{
|
||||
var thisPoint = arrow.InverseTransform(e.Position);
|
||||
double dx = thisPoint.X - lastPoint.X;
|
||||
double dy = thisPoint.Y - lastPoint.Y;
|
||||
if (moveStartPoint)
|
||||
{
|
||||
arrow.StartPoint = new DataPoint(arrow.StartPoint.X + dx, arrow.StartPoint.Y + dy);
|
||||
}
|
||||
|
||||
if (moveEndPoint)
|
||||
{
|
||||
arrow.EndPoint = new DataPoint(arrow.EndPoint.X + dx, arrow.EndPoint.Y + dy);
|
||||
}
|
||||
|
||||
lastPoint = thisPoint;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
// Handle mouse up (note: this is only called when the mousedown event was handled)
|
||||
arrow.MouseUp += (s, e) =>
|
||||
{
|
||||
arrow.Color = originalColor;
|
||||
};
|
||||
model.Annotations.Add(arrow);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PolygonAnnotation")]
|
||||
public static PlotModel PolygonAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "PolygonAnnotation", Subtitle = "Click the polygon" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -20, Maximum = 20 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 20 });
|
||||
var pa = new PolygonAnnotation
|
||||
{
|
||||
Text = "Polygon 1"
|
||||
};
|
||||
pa.Points.AddRange(new[]
|
||||
{
|
||||
new DataPoint(4, -2), new DataPoint(8, -4), new DataPoint(17, 7), new DataPoint(5, 8),
|
||||
new DataPoint(2, 5)
|
||||
});
|
||||
|
||||
// Handle left mouse clicks
|
||||
int hitCount = 1;
|
||||
pa.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton != OxyMouseButton.Left)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pa.Text = "Hit # " + hitCount++;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
model.Annotations.Add(pa);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TextAnnotation")]
|
||||
public static PlotModel TextAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "TextAnnotation", Subtitle = "Click the text" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 20 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
var ta = new TextAnnotation
|
||||
{
|
||||
TextPosition = new DataPoint(4, -2),
|
||||
Text = "Click here"
|
||||
};
|
||||
|
||||
// Handle left mouse clicks
|
||||
ta.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton != OxyMouseButton.Left)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ta.Background = ta.Background.IsUndefined() ? OxyColors.LightGreen : OxyColors.Undefined;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
model.Annotations.Add(ta);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ImageAnnotation")]
|
||||
public static PlotModel ImageAnnotation()
|
||||
{
|
||||
var model = new PlotModel { Title = "ImageAnnotation", Subtitle = "Click the image" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = -20, Maximum = 20 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = -10, Maximum = 10 });
|
||||
|
||||
OxyImage image;
|
||||
var assembly = typeof(MouseEventExamples).GetTypeInfo().Assembly;
|
||||
using (var stream = assembly.GetManifestResourceStream("ExampleLibrary.Resources.OxyPlot.png"))
|
||||
{
|
||||
image = new OxyImage(stream);
|
||||
}
|
||||
|
||||
var ia = new ImageAnnotation { ImageSource = image, X = new PlotLength(4, PlotLengthUnit.Data), Y = new PlotLength(2, PlotLengthUnit.Data), HorizontalAlignment = HorizontalAlignment.Right };
|
||||
model.Annotations.Add(ia);
|
||||
|
||||
// Handle left mouse clicks
|
||||
ia.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton != OxyMouseButton.Left)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ia.HorizontalAlignment = ia.HorizontalAlignment == HorizontalAlignment.Right ? HorizontalAlignment.Left : HorizontalAlignment.Right;
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Add Series")]
|
||||
public static PlotModel AddSeriesByMouseDownEvent()
|
||||
{
|
||||
var model = new PlotModel { Title = "MouseDown", Subtitle = "Left click to add series." };
|
||||
var l = new Legend
|
||||
{
|
||||
LegendSymbolLength = 40
|
||||
};
|
||||
|
||||
model.Legends.Add(l);
|
||||
|
||||
model.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
double a = model.Series.Count + 1;
|
||||
model.Series.Add(new FunctionSeries(x => Math.Sin(a * x), 0, 10, 1000));
|
||||
model.InvalidatePlot(true);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Select range")]
|
||||
public static PlotModel SelectRange()
|
||||
{
|
||||
var model = new PlotModel { Title = "Select range", Subtitle = "Left click and drag to select a range." };
|
||||
model.Series.Add(new FunctionSeries(Math.Cos, 0, 40, 0.1));
|
||||
|
||||
var range = new RectangleAnnotation { Fill = OxyColor.FromAColor(120, OxyColors.SkyBlue), MinimumX = 0, MaximumX = 0 };
|
||||
model.Annotations.Add(range);
|
||||
|
||||
double startx = double.NaN;
|
||||
|
||||
model.MouseDown += (s, e) =>
|
||||
{
|
||||
if (e.ChangedButton == OxyMouseButton.Left)
|
||||
{
|
||||
startx = range.InverseTransform(e.Position).X;
|
||||
range.MinimumX = startx;
|
||||
range.MaximumX = startx;
|
||||
model.InvalidatePlot(true);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
model.MouseMove += (s, e) =>
|
||||
{
|
||||
if (!double.IsNaN(startx))
|
||||
{
|
||||
var x = range.InverseTransform(e.Position).X;
|
||||
range.MinimumX = Math.Min(x, startx);
|
||||
range.MaximumX = Math.Max(x, startx);
|
||||
range.Text = string.Format("∫ cos(x) dx = {0:0.00}", Math.Sin(range.MaximumX) - Math.Sin(range.MinimumX));
|
||||
model.Subtitle = string.Format("Integrating from {0:0.00} to {1:0.00}", range.MinimumX, range.MaximumX);
|
||||
model.InvalidatePlot(true);
|
||||
e.Handled = true;
|
||||
}
|
||||
};
|
||||
|
||||
model.MouseUp += (s, e) =>
|
||||
{
|
||||
startx = double.NaN;
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Hover")]
|
||||
public static PlotModel Hover()
|
||||
{
|
||||
var model = new PlotModel { Title = "Hover" };
|
||||
LineSeries series = null;
|
||||
|
||||
model.MouseEnter += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "The mouse entered";
|
||||
series = new LineSeries();
|
||||
model.Series.Add(series);
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
model.MouseMove += (s, e) =>
|
||||
{
|
||||
if (series != null && series.XAxis != null)
|
||||
{
|
||||
series.Points.Add(series.InverseTransform(e.Position));
|
||||
model.InvalidatePlot(false);
|
||||
}
|
||||
};
|
||||
|
||||
model.MouseLeave += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "The mouse left";
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Touch")]
|
||||
public static PlotModel Touch()
|
||||
{
|
||||
var model = new PlotModel { Title = "Touch" };
|
||||
var series = new LineSeries();
|
||||
model.Series.Add(series);
|
||||
|
||||
model.TouchStarted += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "The touch gesture started";
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
model.TouchDelta += (s, e) =>
|
||||
{
|
||||
series.Points.Add(series.InverseTransform(e.Position));
|
||||
model.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
model.TouchCompleted += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "The touch gesture completed";
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Touch on a LineSeries")]
|
||||
public static PlotModel TouchSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "Touch on a LineSeries" };
|
||||
var series = new LineSeries();
|
||||
series.Points.Add(new DataPoint(0, 0));
|
||||
series.Points.Add(new DataPoint(10, 10));
|
||||
model.Series.Add(series);
|
||||
|
||||
series.TouchStarted += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "The touch gesture started on the LineSeries";
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
series.TouchDelta += (s, e) =>
|
||||
{
|
||||
series.Points.Add(series.InverseTransform(e.Position));
|
||||
model.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
series.TouchCompleted += (s, e) =>
|
||||
{
|
||||
model.Subtitle = "The touch gesture completed";
|
||||
model.InvalidatePlot(false);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("RectangleAnnotation click")]
|
||||
public static PlotModel RectangleAnnotationClick()
|
||||
{
|
||||
var plotModel = new PlotModel { Title = "RectangleAnnotation click" };
|
||||
|
||||
plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var annotation = new RectangleAnnotation() { MinimumX = 10, MaximumX = 60, MinimumY = 10, MaximumY = 20 };
|
||||
plotModel.Annotations.Add(annotation);
|
||||
|
||||
int i = 0;
|
||||
annotation.MouseDown += (s, e) =>
|
||||
{
|
||||
annotation.Text = "Clicked " + (++i) + " times.";
|
||||
plotModel.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
return plotModel;
|
||||
}
|
||||
|
||||
[Example("Clicking on an annotation")]
|
||||
public static PlotModel ClickingOnAnAnnotation()
|
||||
{
|
||||
var plotModel = new PlotModel { Title = "Clicking on an annotation", Subtitle = "Click on the rectangles" };
|
||||
|
||||
plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var annotation1 = new RectangleAnnotation { Fill = OxyColors.Green, Text = "RectangleAnnotation 1", MinimumX = 25, MaximumX = 75, MinimumY = 20, MaximumY = 40 };
|
||||
plotModel.Annotations.Add(annotation1);
|
||||
|
||||
var annotation2 = new RectangleAnnotation { Fill = OxyColors.SkyBlue, Text = "RectangleAnnotation 2", MinimumX = 25, MaximumX = 75, MinimumY = 60, MaximumY = 80 };
|
||||
plotModel.Annotations.Add(annotation2);
|
||||
|
||||
EventHandler<OxyMouseDownEventArgs> handleMouseClick = (s, e) =>
|
||||
{
|
||||
plotModel.Subtitle = "You clicked " + ((RectangleAnnotation)s).Text;
|
||||
plotModel.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
annotation1.MouseDown += handleMouseClick;
|
||||
annotation2.MouseDown += handleMouseClick;
|
||||
|
||||
return plotModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
354
Source/Examples/ExampleLibrary/Examples/PerformanceExamples.cs
Normal file
@@ -0,0 +1,354 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PerformanceExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
|
||||
[Examples("Performance")]
|
||||
public class PerformanceExamples
|
||||
{
|
||||
[Example("LineSeries, 1M points")]
|
||||
public static PlotModel LineSeries1M()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 1M points" };
|
||||
var s1 = new LineSeries();
|
||||
AddPoints(s1.Points, 1000000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 1M points, EdgeRenderingMode==PreferSpeed")]
|
||||
public static PlotModel LineSeries1MSpeed()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 1M points" };
|
||||
var s1 = new LineSeries() { EdgeRenderingMode = EdgeRenderingMode.PreferSpeed };
|
||||
AddPoints(s1.Points, 1000000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points")]
|
||||
public static PlotModel LineSeries()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points" };
|
||||
var s1 = new LineSeries();
|
||||
AddPoints(s1.Points, 100000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points (dashed line)")]
|
||||
public static PlotModel LineSeriesDashedLines()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points", Subtitle = "LineStyle = Dash" };
|
||||
var s1 = new LineSeries { LineStyle = LineStyle.Dash };
|
||||
AddPoints(s1.Points, 100000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points, markers")]
|
||||
public static PlotModel LineSeries1WithMarkers()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points", Subtitle = "MarkerType = Square" };
|
||||
var s1 = new LineSeries { MarkerType = MarkerType.Square };
|
||||
AddPoints(s1.Points, 100000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points, markers, lower resolution")]
|
||||
public static PlotModel LineSeries1WithMarkersLowRes()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points, markers, lower resolution", Subtitle = "MarkerType = Square, MarkerResolution = 3" };
|
||||
var s1 = new LineSeries { MarkerType = MarkerType.Square, MarkerResolution = 3 };
|
||||
AddPoints(s1.Points, 100000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points, round line joins")]
|
||||
public static PlotModel LineSeriesRoundLineJoins()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points", Subtitle = "LineJoin = Round" };
|
||||
var s1 = new LineSeries { LineJoin = LineJoin.Round };
|
||||
AddPoints(s1.Points, 100000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points by ItemsSource set to a List<DataPoint>")]
|
||||
public static PlotModel LineSeriesItemsSourceList()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points by ItemsSource set to a List<DataPoint>" };
|
||||
var s1 = new LineSeries();
|
||||
var points = new List<DataPoint>();
|
||||
AddPoints(points, 100000);
|
||||
s1.ItemsSource = points;
|
||||
model.Series.Add(s1);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points by ItemsSource and Mapping")]
|
||||
public static PlotModel LineSeriesItemsSourceMapping()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points by ItemsSource and Mapping", Subtitle = "Using the Mapping function" };
|
||||
var s1 = new LineSeries();
|
||||
var points = new List<DataPoint>();
|
||||
AddPoints(points, 100000);
|
||||
var rects = points.Select(pt => new OxyRect(pt.X, pt.Y, 0, 0)).ToList();
|
||||
s1.ItemsSource = rects;
|
||||
s1.Mapping = r => new DataPoint(((OxyRect)r).Left, ((OxyRect)r).Top);
|
||||
model.Series.Add(s1);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points by ItemsSource and reflection")]
|
||||
public static PlotModel LineSeriesItemsSourceReflection()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points, ItemsSource with reflection", Subtitle = "DataFieldX and DataFieldY" };
|
||||
var s1 = new LineSeries();
|
||||
var points = new List<DataPoint>();
|
||||
AddPoints(points, 100000);
|
||||
var rects = points.Select(pt => new OxyRect(pt.X, pt.Y, 0, 0)).ToList();
|
||||
s1.ItemsSource = rects;
|
||||
s1.DataFieldX = "Left";
|
||||
s1.DataFieldY = "Top";
|
||||
model.Series.Add(s1);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 100k points (thick)")]
|
||||
public static PlotModel LineSeriesThick()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 100k points (thick)", Subtitle = "StrokeThickness = 10" };
|
||||
var s1 = new LineSeries { StrokeThickness = 10 };
|
||||
AddPoints(s1.Points, 100000);
|
||||
model.Series.Add(s1);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 3k points, miter line joins")]
|
||||
public static PlotModel LineSeries2MiterLineJoins()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 3k points, miter line joins", Subtitle = "LineJoin = Miter" };
|
||||
var s1 = new LineSeries { LineJoin = LineJoin.Miter, StrokeThickness = 8.0 };
|
||||
for (int i = 0; i < 3000; i++)
|
||||
{
|
||||
s1.Points.Add(new DataPoint(i, i % 2));
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 3k points, round line joins")]
|
||||
public static PlotModel LineSeries2RoundLineJoins()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 3k points, round line joins", Subtitle = "LineJoin = Round" };
|
||||
var s1 = new LineSeries { LineJoin = LineJoin.Round, StrokeThickness = 8.0 };
|
||||
for (int i = 0; i < 3000; i++)
|
||||
{
|
||||
s1.Points.Add(new DataPoint(i, i % 2));
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LineSeries, 3k points, bevel line joins")]
|
||||
public static PlotModel LineSeries2BevelLineJoins()
|
||||
{
|
||||
var model = new PlotModel { Title = "LineSeries, 3k points, bevel line joins", Subtitle = "LineJoin = Bevel" };
|
||||
var s1 = new LineSeries { LineJoin = LineJoin.Bevel, StrokeThickness = 8.0 };
|
||||
for (int i = 0; i < 3000; i++)
|
||||
{
|
||||
s1.Points.Add(new DataPoint(i, i % 2));
|
||||
}
|
||||
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries (squares)")]
|
||||
public static PlotModel ScatterSeriesSquares()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (squares)" };
|
||||
var s1 = new ScatterSeries();
|
||||
AddPoints(s1.Points, 2000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries (squares with outline)")]
|
||||
public static PlotModel ScatterSeriesSquaresOutline()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (squares with outline)", Subtitle = "MarkerStroke = Black" };
|
||||
var s1 = new ScatterSeries { MarkerStroke = OxyColors.Black };
|
||||
AddPoints(s1.Points, 2000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries (squares without fill color)")]
|
||||
public static PlotModel ScatterSeriesSquaresOutlineOnly()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (squares without fill color)", Subtitle = ";arkerFill = Transparent, MarkerStroke = Black" };
|
||||
var s1 = new ScatterSeries { MarkerFill = OxyColors.Transparent, MarkerStroke = OxyColors.Black };
|
||||
AddPoints(s1.Points, 2000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries by ItemsSource and reflection")]
|
||||
public static PlotModel ScatterSeriesItemsSourceReflection()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (by ItemsSource)", Subtitle = "DataFieldX = 'X', DataFieldY = 'Y'" };
|
||||
model.Series.Add(new ScatterSeries { ItemsSource = GetPoints(2000), DataFieldX = "X", DataFieldY = "Y" });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries (circles)")]
|
||||
public static PlotModel ScatterSeriesCircles()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (circles)", Subtitle = "MarkerType = Circle" };
|
||||
var s1 = new ScatterSeries { MarkerType = MarkerType.Circle };
|
||||
AddPoints(s1.Points, 2000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries (circles with outline)")]
|
||||
public static PlotModel ScatterSeriesCirclesOutline()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (circles with outline)", Subtitle = "MarkerType = Circle, MarkerStroke = Black" };
|
||||
var s1 = new ScatterSeries { MarkerType = MarkerType.Circle, MarkerStroke = OxyColors.Black };
|
||||
AddPoints(s1.Points, 2000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("ScatterSeries (cross)")]
|
||||
public static PlotModel ScatterSeriesCrosses()
|
||||
{
|
||||
var model = new PlotModel { Title = "ScatterSeries (cross)", Subtitle = "MarkerType = Cross" };
|
||||
var s1 = new ScatterSeries
|
||||
{
|
||||
MarkerType = MarkerType.Cross,
|
||||
MarkerFill = OxyColors.Undefined,
|
||||
MarkerStroke = OxyColors.Black
|
||||
};
|
||||
AddPoints(s1.Points, 2000);
|
||||
model.Series.Add(s1);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LinearAxis (no gridlines)")]
|
||||
public static PlotModel LinearAxisNoGridlines()
|
||||
{
|
||||
var model = new PlotModel { Title = "LinearAxis (no gridlines)" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1 });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1 });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LinearAxis (solid gridlines)")]
|
||||
public static PlotModel LinearAxisSolidGridlines()
|
||||
{
|
||||
var model = new PlotModel { Title = "LinearAxis (solid gridlines)" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1, MajorGridlineStyle = LineStyle.Solid });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1, MajorGridlineStyle = LineStyle.Solid });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LinearAxis (dashed gridlines)")]
|
||||
public static PlotModel LinearAxisDashedGridlines()
|
||||
{
|
||||
var model = new PlotModel { Title = "LinearAxis (dashed gridlines)" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1, MajorGridlineStyle = LineStyle.Dash });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1, MajorGridlineStyle = LineStyle.Dash });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("LinearAxis (dotted gridlines)")]
|
||||
public static PlotModel LinearAxisDottedGridlines()
|
||||
{
|
||||
var model = new PlotModel { Title = "LinearAxis (dotted gridlines)" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1, MajorGridlineStyle = LineStyle.Dot });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0, Maximum = 100, MajorStep = 1, MinorStep = 1, MajorGridlineStyle = LineStyle.Dot });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("int overflow (10k)")]
|
||||
public static PlotModel IntOverflow10k()
|
||||
{
|
||||
return IntOverflow(10000);
|
||||
}
|
||||
|
||||
[Example("int overflow (50k)")]
|
||||
public static PlotModel IntOverflow50k()
|
||||
{
|
||||
return IntOverflow(50000);
|
||||
}
|
||||
|
||||
[Example("int overflow (100k)")]
|
||||
public static PlotModel IntOverflow100k()
|
||||
{
|
||||
return IntOverflow(100000);
|
||||
}
|
||||
|
||||
private static PlotModel IntOverflow(int n)
|
||||
{
|
||||
var model = new PlotModel { Title = "int overflow", Subtitle = "n = " + n };
|
||||
var ls = new LineSeries();
|
||||
int k = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
ls.Points.Add(new DataPoint(i, k += i * i));
|
||||
}
|
||||
|
||||
model.Series.Add(ls);
|
||||
return model;
|
||||
}
|
||||
|
||||
private static List<DataPoint> GetPoints(int n)
|
||||
{
|
||||
var points = new List<DataPoint>();
|
||||
AddPoints(points, n);
|
||||
return points;
|
||||
}
|
||||
|
||||
private static void AddPoints(ICollection<DataPoint> points, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
double x = Math.PI * 10 * i / (n - 1);
|
||||
points.Add(new DataPoint(x * Math.Cos(x), x * Math.Sin(x)));
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddPoints(ICollection<ScatterPoint> points, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
double x = Math.PI * 10 * i / (n - 1);
|
||||
points.Add(new ScatterPoint(x * Math.Cos(x), x * Math.Sin(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlotControllerExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using OxyPlot;
|
||||
using OxyPlot.Annotations;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using OxyPlot.Legends;
|
||||
|
||||
[Examples("PlotController examples")]
|
||||
public static class PlotControllerExamples
|
||||
{
|
||||
[Example("Basic controller example")]
|
||||
public static Example BasicExample()
|
||||
{
|
||||
var model = new PlotModel { Title = "Basic Controller example", Subtitle = "Panning with left mouse button" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, PlotCommands.PanAt);
|
||||
return new Example(model, controller);
|
||||
}
|
||||
|
||||
[Example("Show tracker without clicking")]
|
||||
public static Example HoverTracking()
|
||||
{
|
||||
var model = new PlotModel { Title = "Show tracker without clicking" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
model.Series.Add(new FunctionSeries(t => (Math.Cos(t) * 5) + Math.Cos(t * 50), t => (Math.Sin(t) * 5) + Math.Sin(t * 50), 0, Math.PI * 2, 20000));
|
||||
|
||||
// create a new plot controller with default bindings
|
||||
var controller = new PlotController();
|
||||
|
||||
// add a tracker command to the mouse enter event
|
||||
controller.BindMouseEnter(PlotCommands.HoverPointsOnlyTrack);
|
||||
|
||||
return new Example(model, controller);
|
||||
}
|
||||
|
||||
[Example("Mouse handling example")]
|
||||
public static Example MouseHandlingExample()
|
||||
{
|
||||
var model = new PlotModel { Title = "Mouse handling example" };
|
||||
var series = new ScatterSeries();
|
||||
model.Series.Add(series);
|
||||
|
||||
// Create a command that adds points to the scatter series
|
||||
var command = new DelegatePlotCommand<OxyMouseDownEventArgs>(
|
||||
(v, c, a) =>
|
||||
{
|
||||
a.Handled = true;
|
||||
var point = series.InverseTransform(a.Position);
|
||||
series.Points.Add(new ScatterPoint(point.X, point.Y));
|
||||
model.InvalidatePlot(true);
|
||||
});
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.BindMouseDown(OxyMouseButton.Left, command);
|
||||
|
||||
return new Example(model, controller);
|
||||
}
|
||||
|
||||
[Example("Clicking on an annotation")]
|
||||
public static Example ClickingOnAnAnnotation()
|
||||
{
|
||||
var plotModel = new PlotModel { Title = "Clicking on an annotation", Subtitle = "Click on the rectangles" };
|
||||
|
||||
plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
var annotation1 = new RectangleAnnotation { Fill = OxyColors.Green, Text = "RectangleAnnotation 1", MinimumX = 25, MaximumX = 75, MinimumY = 20, MaximumY = 40 };
|
||||
plotModel.Annotations.Add(annotation1);
|
||||
|
||||
var annotation2 = new RectangleAnnotation { Fill = OxyColors.SkyBlue, Text = "RectangleAnnotation 2", MinimumX = 25, MaximumX = 75, MinimumY = 60, MaximumY = 80 };
|
||||
plotModel.Annotations.Add(annotation2);
|
||||
|
||||
EventHandler<OxyMouseDownEventArgs> handleMouseClick = (s, e) =>
|
||||
{
|
||||
plotModel.Subtitle = "You clicked " + ((RectangleAnnotation)s).Text;
|
||||
plotModel.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
annotation1.MouseDown += handleMouseClick;
|
||||
annotation2.MouseDown += handleMouseClick;
|
||||
|
||||
var controller = new PlotController();
|
||||
var handleClick = new DelegatePlotCommand<OxyMouseDownEventArgs>(
|
||||
(v, c, e) =>
|
||||
{
|
||||
var args = new HitTestArguments(e.Position, 10);
|
||||
var firstHit = v.ActualModel.HitTest(args).FirstOrDefault(x => x.Element is RectangleAnnotation);
|
||||
if (firstHit != null)
|
||||
{
|
||||
e.Handled = true;
|
||||
plotModel.Subtitle = "You clicked " + ((RectangleAnnotation)firstHit.Element).Text;
|
||||
plotModel.InvalidatePlot(false);
|
||||
}
|
||||
});
|
||||
controller.Bind(new OxyMouseDownGesture(OxyMouseButton.Left), handleClick);
|
||||
|
||||
return new Example(plotModel, controller);
|
||||
}
|
||||
|
||||
[Example("Preferring an axis for manipulation")]
|
||||
public static Example PreferringAnAxisForManipulation()
|
||||
{
|
||||
var model = new PlotModel
|
||||
{
|
||||
Title = "Preferring an axis for manipulation",
|
||||
Subtitle = "Mouse wheel over plot area prefers X axis",
|
||||
};
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
|
||||
model.Series.Add(new FunctionSeries(Math.Cos, -7, 7, 0.01));
|
||||
|
||||
var controller = new PlotController();
|
||||
controller.UnbindAll();
|
||||
controller.BindMouseWheel(new DelegatePlotCommand<OxyMouseWheelEventArgs>((view, _, args) => HandleZoomByWheel(view, args)));
|
||||
controller.BindMouseWheel(OxyModifierKeys.Control, new DelegatePlotCommand<OxyMouseWheelEventArgs>((view, _, args) => HandleZoomByWheel(view, args, 0.1)));
|
||||
|
||||
return new Example(model, controller);
|
||||
|
||||
void HandleZoomByWheel(IPlotView view, OxyMouseWheelEventArgs args, double factor = 1)
|
||||
{
|
||||
var m = new ZoomStepManipulator(view)
|
||||
{
|
||||
AxisPreference = AxisPreference.X,
|
||||
Step = args.Delta * 0.001 * factor,
|
||||
FineControl = args.IsControlDown,
|
||||
};
|
||||
m.Started(args);
|
||||
}
|
||||
}
|
||||
|
||||
[Example("Show/Hide Legend")]
|
||||
public static Example ShowHideLegend()
|
||||
{
|
||||
var plotModel = new PlotModel { Title = "Show/Hide Legend", Subtitle = "Click on the rectangles" };
|
||||
|
||||
int n = 3;
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
var s = new LineSeries { Title = "Series " + i };
|
||||
plotModel.Series.Add(s);
|
||||
for (double x = 0; x < 2 * Math.PI; x += 0.1)
|
||||
{
|
||||
s.Points.Add(new DataPoint(x, (Math.Sin(x * i) / i) + i));
|
||||
}
|
||||
}
|
||||
var l = new Legend();
|
||||
|
||||
plotModel.Legends.Add(l);
|
||||
|
||||
var annotation1 = new RectangleAnnotation { Fill = OxyColors.Green, Text = "Show Legend", MinimumX = 0.5, MaximumX = 1.5, MinimumY = .2, MaximumY = 0.4 };
|
||||
plotModel.Annotations.Add(annotation1);
|
||||
|
||||
var annotation2 = new RectangleAnnotation { Fill = OxyColors.SkyBlue, Text = "Hide Legend", MinimumX = 0.5, MaximumX = 1.5, MinimumY = 0.6, MaximumY = 0.8 };
|
||||
plotModel.Annotations.Add(annotation2);
|
||||
|
||||
EventHandler<OxyMouseDownEventArgs> handleMouseClick = (s, e) =>
|
||||
{
|
||||
string annotationText = ((RectangleAnnotation)s).Text;
|
||||
if (annotationText == "Show Legend")
|
||||
{
|
||||
plotModel.IsLegendVisible = true;
|
||||
}
|
||||
else if (annotationText == "Hide Legend")
|
||||
{
|
||||
plotModel.IsLegendVisible = false;
|
||||
}
|
||||
|
||||
plotModel.Subtitle = "You clicked " + ((RectangleAnnotation)s).Text;
|
||||
plotModel.InvalidatePlot(false);
|
||||
};
|
||||
|
||||
annotation1.MouseDown += handleMouseClick;
|
||||
annotation2.MouseDown += handleMouseClick;
|
||||
|
||||
var controller = new PlotController();
|
||||
var handleClick = new DelegatePlotCommand<OxyMouseDownEventArgs>(
|
||||
(v, c, e) =>
|
||||
{
|
||||
var args = new HitTestArguments(e.Position, 10);
|
||||
var firstHit = v.ActualModel.HitTest(args).FirstOrDefault(x => x.Element is RectangleAnnotation);
|
||||
if (firstHit != null)
|
||||
{
|
||||
e.Handled = true;
|
||||
plotModel.Subtitle = "You clicked " + ((RectangleAnnotation)firstHit.Element).Text;
|
||||
plotModel.InvalidatePlot(false);
|
||||
}
|
||||
});
|
||||
controller.Bind(new OxyMouseDownGesture(OxyMouseButton.Left), handleClick);
|
||||
|
||||
return new Example(plotModel, controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
243
Source/Examples/ExampleLibrary/Examples/PlotModelExamples.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
// <copyright file="PlotModelExamples.cs" company="OxyPlot">
|
||||
// Copyright (c) 2014 OxyPlot contributors
|
||||
// </copyright>
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ExampleLibrary
|
||||
{
|
||||
using OxyPlot;
|
||||
using OxyPlot.Axes;
|
||||
using OxyPlot.Series;
|
||||
using System;
|
||||
|
||||
[Examples("PlotModel examples")]
|
||||
public static class PlotModelExamples
|
||||
{
|
||||
[Example("Title")]
|
||||
public static PlotModel Title()
|
||||
{
|
||||
var model = new PlotModel { Title = "Title" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Title and Subtitle")]
|
||||
public static PlotModel TitleAndSubtitle()
|
||||
{
|
||||
var model = new PlotModel { Title = "Title", Subtitle = "Subtitle" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Sub- and superscript in titles")]
|
||||
public static PlotModel TitleAndSubtitleWithSubSuperscript()
|
||||
{
|
||||
var model = new PlotModel { Title = "Title with^{super}_{sub}script", Subtitle = "Subtitle with^{super}_{sub}script" };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TitlePadding = 0")]
|
||||
public static PlotModel TitlePadding0()
|
||||
{
|
||||
var model = new PlotModel { Title = "TitlePadding = 0", Subtitle = "This controls the distance between the titles and the plot area. The default value is 6", TitlePadding = 0 };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TitlePadding = 100")]
|
||||
public static PlotModel TitlePadding100()
|
||||
{
|
||||
var model = new PlotModel { Title = "TitlePadding = 100", TitlePadding = 100 };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TitleHorizontalAlignment = CenteredWithinView")]
|
||||
public static PlotModel TitlesCenteredWithinView()
|
||||
{
|
||||
var model = new PlotModel { Title = "Title", Subtitle = "Subtitle", TitleHorizontalAlignment = TitleHorizontalAlignment.CenteredWithinView };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TitleClippingOff")]
|
||||
public static PlotModel TitleClippingOff()
|
||||
{
|
||||
var model = new PlotModel { Title = "This is a very long title to illustrate that title clipping is necessary, because currently it's not clipped.", ClipTitle = false };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("TitleClipping60")]
|
||||
public static PlotModel TitleClipping60()
|
||||
{
|
||||
var model = new PlotModel { Title = "This is a very long title, that shows that title clippling is working with crrently 60% of title area", TitleClippingLength = 0.6};
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("No model")]
|
||||
public static PlotModel NoModel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
[Example("Background = Undefined (default)")]
|
||||
public static PlotModel BackgroundUndefined()
|
||||
{
|
||||
var model = new PlotModel { Title = "Background = Undefined", Background = OxyColors.Undefined };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Background = 50% White")]
|
||||
public static PlotModel BackgroundWhite50()
|
||||
{
|
||||
var model = new PlotModel { Title = "Background = 50% White", Background = OxyColor.FromAColor(128, OxyColors.White) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Background = Transparent")]
|
||||
public static PlotModel BackgroundTransparent()
|
||||
{
|
||||
var model = new PlotModel { Title = "Background = Transparent", Background = OxyColors.Transparent };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Background = LightSkyBlue")]
|
||||
public static PlotModel BackgroundLightGray()
|
||||
{
|
||||
var model = new PlotModel { Title = "Background = LightSkyBlue", Background = OxyColors.LightSkyBlue };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Background = White")]
|
||||
public static PlotModel BackgroundWhite()
|
||||
{
|
||||
var model = new PlotModel { Title = "Background = White", Background = OxyColors.White };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Background = Black")]
|
||||
public static PlotModel BackgroundBlack()
|
||||
{
|
||||
var model = new PlotModel { Title = "Background = Black", Background = OxyColors.Black, TextColor = OxyColors.White, TitleColor = OxyColors.White, PlotAreaBorderColor = OxyColors.White };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, TicklineColor = OxyColors.White });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, TicklineColor = OxyColors.White });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PlotAreaBorderThickness = 2")]
|
||||
public static PlotModel PlotAreaBorderThickness2()
|
||||
{
|
||||
var model = new PlotModel { Title = "PlotAreaBorderThickness = 2", PlotAreaBorderThickness = new OxyThickness(2) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PlotAreaBorderThickness = (1,0,0,1)")]
|
||||
public static PlotModel PlotAreaBorderThickness1001()
|
||||
{
|
||||
var model = new PlotModel { Title = "PlotAreaBorderThickness = (1,0,0,1)", PlotAreaBorderThickness = new OxyThickness(1, 0, 0, 1) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PlotAreaBorderThickness = (4,1,1,4)")]
|
||||
public static PlotModel PlotAreaBorderThickness4114()
|
||||
{
|
||||
var model = new PlotModel { Title = "PlotAreaBorderThickness = (4,1,1,4)", PlotAreaBorderThickness = new OxyThickness(4, 1, 1, 4) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PlotAreaBorderThickness = 0")]
|
||||
public static PlotModel PlotAreaBorderThickness0()
|
||||
{
|
||||
var model = new PlotModel { Title = "PlotAreaBorderThickness = 0", PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("PlotAreaBorderThickness / AxisLine")]
|
||||
public static PlotModel PlotAreaBorderThickness0AxisLineThickness1()
|
||||
{
|
||||
var model = new PlotModel { Title = "PlotAreaBorderThickness = 0", Subtitle = "AxislineThickness = 1, AxislineColor = OxyColors.Blue, AxislineStyle = LineStyle.Solid", PlotAreaBorderThickness = new OxyThickness(0) };
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, AxislineThickness = 1, AxislineColor = OxyColors.Blue, AxislineStyle = LineStyle.Solid });
|
||||
model.Axes.Add(new LinearAxis { Position = AxisPosition.Left, AxislineThickness = 1, AxislineColor = OxyColors.Blue, AxislineStyle = LineStyle.Solid });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Exception handling (invalid XAxisKey)")]
|
||||
public static PlotModel InvalidAxisKey()
|
||||
{
|
||||
var model = new PlotModel();
|
||||
model.Axes.Add(new LinearAxis());
|
||||
model.Series.Add(new LineSeries { XAxisKey = "invalidKey" });
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Exception handling (with clipping)")]
|
||||
public static PlotModel ExceptionClipping()
|
||||
{
|
||||
var model = new PlotModel();
|
||||
var annotation = new RenderingCapabilities.DelegateAnnotation(rc =>
|
||||
{
|
||||
rc.PushClip(new OxyRect(50, 50, 50, 50));
|
||||
throw new Exception("This Exception should be completely visible and not clipped by the previously pushed clipping rectangle.");
|
||||
});
|
||||
|
||||
model.Annotations.Add(annotation);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Unbalanced clipping (push)")]
|
||||
public static PlotModel UnbalancedClippingPush()
|
||||
{
|
||||
var model = new PlotModel();
|
||||
var annotation = new RenderingCapabilities.DelegateAnnotation(rc =>
|
||||
{
|
||||
rc.PushClip(new OxyRect(50, 50, 50, 50));
|
||||
});
|
||||
|
||||
model.Annotations.Add(annotation);
|
||||
return model;
|
||||
}
|
||||
|
||||
[Example("Unbalanced clipping (pop)")]
|
||||
public static PlotModel UnbalancedClippingPop()
|
||||
{
|
||||
var model = new PlotModel();
|
||||
var annotation = new RenderingCapabilities.DelegateAnnotation(rc =>
|
||||
{
|
||||
rc.PopClip();
|
||||
});
|
||||
|
||||
model.Annotations.Add(annotation);
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||