Search code examples
c#wpfgnuplotcoordinate-systemsoxyplot

Draw graphs - show only single points


(C # Application for WPF)

I have a problem and I have to "draw" a coordinate system and enter only the coordinates (without lines) as seen in the picture.

Here you can see the coordinate system with the points. Later, only the coordinates with a circle or a point are to be specified.

I would like to use a library, because I also have to draw a frame and I thought with a library would it be easy. So I've discovered GnuPlot, Oxyplot and draw myself. GnuPlot is unfortunately stupid since it has no library for a C # application. (Or if you have one, please let me know). Therefore, I used OxyPlot, but unfortunately OxyPlot shows me only the coordinate system. Now to my question. Is there anything better to draw coordinate systems with the coordinates? It should meet the following requirements:

  • It should be a preview application, that is, if I change the size it should happen directly
  • I would like to make a frame, so it should help me in the process
  • there should be a library
  • it should be for a C # application
  • I would like to be first point marks for the X, Y coordinates, but later it should be circles with a circle diameter
  • later as a Bitmap

As mentioned above, I've used it with OxyPlot, but unfortunately it does not draw a graph (I used the sample documentation)

Maybe you have better ideas / a solution for OxyPlot.

Thanks in advance and I am happy about every reply.

XAML:

 <Window x:Class="TestOxyPlot.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:oxy="http://oxyplot.org/wpf"
            xmlns:local="clr-namespace:TestOxyPlot"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <oxy:Plot x:Name="oxyPlot" Title="{Binding Title}" Margin="207,53,0,0">
                <oxy:Plot.Series>
                    <oxy:LineSeries ItemsSource="{Binding Points}"/>
                </oxy:Plot.Series>
            </oxy:Plot>
            <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="44,64,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" MouseLeave="textBox_MouseLeave" TextChanged="textBox_TextChanged"/>
            <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="44,101,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" TextChanged="textBox1_TextChanged"/>
            <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="68,174,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
        </Grid>
    </Window>

  using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using OxyPlot;

    namespace TestOxyPlot
    {
        /// <summary>
        /// Interaktionslogik für MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.Title = "Example 2";
                this.Points = new List<DataPoint>
                    {
                                      new DataPoint(0, 4),
                                      new DataPoint(10, 13),
                                      new DataPoint(20, 15),
                                      new DataPoint(30, 16),
                                      new DataPoint(40, 12),
                                      new DataPoint(50, 12)
                                  };


            }
            public string Title { get; private set; }

            public IList<DataPoint> Points { get; private set; }

            private void textBox_MouseLeave(object sender, MouseEventArgs e)
            {


           }

            private void textBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                try
                {
                    oxyPlot.Width = Int32.Parse(textBox.Text);
                }
                catch (Exception error)
                {
                    MessageBox.Show("Message: " + error);
                }

            }

            private void button_Click(object sender, RoutedEventArgs e)
            {

            }

            private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
            {
                try
                {
                    oxyPlot.Width = Int32.Parse(textBox.Text);
                }
                catch (Exception error)
                {
                    MessageBox.Show("Message: " + error);
                }
            }
        }
    }

Solution

  • Add this code

     DataContext = this;
    

    after this line

     InitializeComponent();
    

    and it will show the graph. Also, in order to remove the line and just draw the Markers, use something like this LineSeries:

    <oxy:LineSeries ItemsSource="{Binding Points}" LineStyle="None"  MarkerType="Circle" MarkerSize="5" MarkerFill="Black"/>
    

    Edit

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            double randomNumX;
            double randomNumY;
            int h = DateTime.Now.Hour;
            int m = DateTime.Now.Minute;
            int s = DateTime.Now.Second;
            String u = h.ToString() + m.ToString() + s.ToString();
            int iu = Int32.Parse(u);
            Random zufall = new Random(iu);
    
            Points = new List<DataPoint>();
            for (int i = 0; i < 10; i++)
            {
                randomNumX = zufall.NextDouble() * (10 - -10) + -10;
                randomNumY = zufall.NextDouble() * (10 - -10) + -10;
                Points.Add(new DataPoint(randomNumX, randomNumY));
            }
            ls.ItemsSource = Points;
        }
    

    and

    <DockPanel>
        <Button DockPanel.Dock="Top" Click="Button_Click" Content="Click Me"/>
        <oxy:Plot x:Name="oxyPlot" Title="{Binding Title}">
            <oxy:Plot.Axes>
                <oxy:LinearAxis Position="Bottom" />
                <oxy:LinearAxis Position="Right" MinimumPadding="0.1" MaximumPadding="0.1"/>
            </oxy:Plot.Axes>
            <oxy:Plot.Series>
                <oxy:LineSeries x:Name="ls" ItemsSource="{Binding Points}" LineStyle="None"  MarkerType="Circle" MarkerSize="5" MarkerFill="Black"/>
            </oxy:Plot.Series>
        </oxy:Plot> 
    </DockPanel>
    

    By the way, for some reason, using ObservationCollection or InvalidatePlot(true) didn't work