這段代碼如何生成與另一個類似的圖表?我已經發布了我的整個代碼,如果有人是這方面的專家,請分享您的意見。我不明白在 WPF 中完全繪圖!我仍在閱讀該主題。
我的代碼:
private void GenerateGraphBtn_Click(object sender, RoutedEventArgs e)
{
// Setting up the bounds of the graph
const double margin = 30;
double xmin = margin;
double xmax = (DrawGraphArea.Width / 2);
double ymin = margin;
double ymax = (DrawGraphArea.Height / 2);
const double step = 12;
// ##########################################################
// Make the X axis.
GeometryGroup xaxis_geom = new GeometryGroup();
// Creates the long Horisontal Line
xaxis_geom.Children.Add(new LineGeometry(
new Point(0, ymax), new Point(DrawGraphArea.Width / 2, ymax)));
// Adds all the mini lines on the horisontal axis (bottom)
for (double x = xmin step;
x <= (DrawGraphArea.Width / 2) - step; x = step)
{
xaxis_geom.Children.Add(new LineGeometry(
new Point(x, ymax - margin / 2),
new Point(x, ymax margin / 2)));
}
/* Adds all the lines that were created in the above code to the graph.
* Stroke thickness = line thickness
* Stroke = line colour
* Data = the geometry you are adding (the points that you have created in the above code)
*/
Path xaxis_path = new Path();
xaxis_path.StrokeThickness = 2;
xaxis_path.Stroke = Brushes.DarkRed;
xaxis_path.Data = xaxis_geom;
DrawGraphArea.Children.Add(xaxis_path);
// ##########################################################
// Creates the Y axis.
GeometryGroup yaxis_geom = new GeometryGroup();
// Adds the long Vertical Line
yaxis_geom.Children.Add(new LineGeometry(
new Point(xmin, 0), new Point(xmin, DrawGraphArea.Height / 2)));
// Adds the mini lines on the vertical axis (Left)
for (double y = step; y <= (DrawGraphArea.Height / 2) - step; y = step)
{
yaxis_geom.Children.Add(new LineGeometry(
new Point(xmin - margin / 2, y),
new Point(xmin margin / 2, y)));
}
// Adds them all to the graph.
Path yaxis_path = new Path();
yaxis_path.StrokeThickness = 1;
yaxis_path.Stroke = Brushes.Black;
yaxis_path.Data = yaxis_geom;
DrawGraphArea.Children.Add(yaxis_path);
// ##########################################################
// This creates the brushes colours
Random rand = new Random();
// This will then go along and create all the colour
for (int data_set = 0; data_set < 1; data_set )
{
int last_y = rand.Next((int)ymin, (int)ymax);
// This is where you add the points to the graph
// Little bit confusing as it is adding 3 lines at once
PointCollection points = new PointCollection();
for (double x = xmin; x <= xmax; x = step)
{
last_y = rand.Next(last_y - 10, last_y 10);
if (last_y < ymin) last_y = (int)ymin;
if (last_y > ymax) last_y = (int)ymax;
points.Add(new Point(x, last_y));
}
// Adds the lines that connect the points
Polyline polyline = new Polyline();
polyline.StrokeThickness = 2;
polyline.Stroke = Brushes.Red;
polyline.Points = points;
// Add the line / points
DrawGraphArea.Children.Add(polyline);
}
}
當前結果:

想要的結果:

uj5u.com熱心網友回復:
你走在正確的道路上來解決它,我用你的代碼作為指導。

所以,第一個是提供你想要的結果的代碼,
這將轉到 MainWindow xaml:
<Window x:Class="WpfApp2.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:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="20" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Button" HorizontalAlignment="Left" Click="GenerateGraphBtn_Click" />
<Canvas Grid.Row="2" x:Name="GrpahArea" Margin="40" />
</Grid>
</Window>
這進入了 MainWindow 的代碼隱藏
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private Point[] GenerateGraphPoints(int minimumX, int maximumX, int minimumY, int maximumY)
{
var result = new List<Point>();
var rnd = new Random();
for (var x = minimumX; x < maximumX; x )
result.Add(new Point(x, rnd.Next(minimumY, maximumY)));
return result.ToArray();
}
private void PlotXAxes(Panel drawArea, int minimumX, int maximumX, int step, int miniLineExtent)
{
var geometryGroup = new GeometryGroup();
var axePositionY = drawArea.ActualHeight;
geometryGroup.Children.Add(new LineGeometry(new Point(0, axePositionY), new Point(drawArea.ActualWidth, axePositionY)));
var factorX = drawArea.ActualWidth / (maximumX - minimumX);
for (var i = minimumX; i < maximumX; i )
if (i % step == 0)
{
geometryGroup.Children.Add(new LineGeometry(
new Point(i * factorX, axePositionY - miniLineExtent),
new Point(i * factorX, axePositionY miniLineExtent)));
drawArea.Children.Add(new Label
{
Margin = new Thickness(i*factorX, axePositionY miniLineExtent, 0, 0),
Content = i,
Foreground = Brushes.Black
});
}
var path = new Path
{
StrokeThickness = 2,
Stroke = Brushes.DarkRed,
Data = geometryGroup
};
drawArea.Children.Add(path);
}
private void PlotYAxes(Panel drawArea, int minimumY, int maximumY, int step, int miniLineExtent)
{
var labelSize = new Size(30, 26);
var geometryGroup = new GeometryGroup();
var axePositionX = 0;
geometryGroup.Children.Add(new LineGeometry(new Point(axePositionX, 0), new Point(axePositionX, drawArea.ActualHeight)));
var factorY = drawArea.ActualHeight / (maximumY - minimumY);
for (var i = minimumY; i < maximumY; i )
if (i % step == 0)
{
geometryGroup.Children.Add(new LineGeometry(
new Point(axePositionX - miniLineExtent, (maximumY-i) * factorY),
new Point(axePositionX miniLineExtent, (maximumY-i) * factorY)));
drawArea.Children.Add(new Label
{
Width = labelSize.Width,
Height = labelSize.Height,
Margin = new Thickness(
axePositionX - miniLineExtent - labelSize.Width,
(maximumY - i) * factorY - (labelSize.Height / 2), 0, 0),
Content = i,
Foreground = Brushes.Black
});
}
var path = new Path
{
StrokeThickness = 2,
Stroke = Brushes.DarkRed,
Data = geometryGroup
};
drawArea.Children.Add(path);
}
private void PlotGraph(Point[] points, Panel drawArea, int minimumX, int maximumX, int minimumY, int maximumY)
{
var factorX = drawArea.ActualWidth / (maximumX-minimumX);
var factorY = drawArea.ActualHeight / (maximumY-minimumY);
for (var i = 0; i < points.Length; i )
{
points[i].X *= factorX;
//points[i].Y *= factorY;
points[i].Y = (maximumY - points[i].Y) * factorY; //since zero of Y should be in bottom we "swap" the Y value.
}
Polyline polyline = new Polyline();
polyline.StrokeThickness = 2;
polyline.Stroke = Brushes.Blue;
polyline.Points = new PointCollection(points);
drawArea.Children.Add(polyline);
}
private void GenerateGraphBtn_Click(object sender, RoutedEventArgs e)
{
//Step 1: define the data limits and generate the data, this has nothing to do with the view.
const int xmin = 0, xmax = 12;
const int ymin = 0, ymax = 800;
var graphPoints = GenerateGraphPoints(xmin, xmax, ymin, ymax);
//Step 2: Draw yAxes
PlotYAxes(GrpahArea, ymin, ymax, 100, 2);
//Step 3: Draw xAxes
PlotXAxes(GrpahArea, xmin, xmax, 1, 2);
//Step 4: Plot Grpah
var plotPoints = new Point[graphPoints.Length]; //graphPoints is our model, we usually wish to keep the original value of model.
graphPoints.CopyTo(plotPoints,0); //plotPoints is what we going to scale and adjust to the view.
PlotGraph(plotPoints, GrpahArea, xmin, xmax, ymin, ymax);
}
}
}
現在到我回答的第二部分,構建圖形組件并不是那么簡單的任務,主要是因為圖形通常被開發為對許多應用程式通用,因此允許的自定義量需要非常大,這就是為什么其他人正確地指導您到一個準備好的圖書館。
此外,我在答案中提供給您的代碼不是 MVVM 風格,它與您提供的代碼非常接近。這是因為以 MVVM 風格撰寫它需要創建一組視圖模型類并將它們系結到視圖,考慮到自定義,與您要求解決的相比,這是一項相當大的作業。
盡管如此,我希望提供的代碼可以幫助您做任何您想做的事情。
更新,添加標簽:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private Point[] GenerateGraphPoints(int minimumX, int maximumX, int minimumY, int maximumY)
{
var result = new List<Point>();
var rnd = new Random();
for (var x = minimumX; x < maximumX; x )
result.Add(new Point(x, rnd.Next(minimumY, maximumY)));
return result.ToArray();
}
private void PlotXAxes(Panel drawArea, int minimumX, int maximumX, int step, int miniLineExtent, string title)
{
var geometryGroup = new GeometryGroup();
var axePositionY = drawArea.ActualHeight;
geometryGroup.Children.Add(new LineGeometry(new Point(0, axePositionY), new Point(drawArea.ActualWidth, axePositionY)));
var factorX = drawArea.ActualWidth / (maximumX - minimumX);
for (var i = minimumX; i < maximumX; i )
if (i % step == 0)
{
geometryGroup.Children.Add(new LineGeometry(
new Point(i * factorX, axePositionY - miniLineExtent),
new Point(i * factorX, axePositionY miniLineExtent)));
drawArea.Children.Add(new Label
{
Margin = new Thickness(i*factorX, axePositionY miniLineExtent, 0, 0),
Content = i,
Foreground = Brushes.Black
});
}
var path = new Path
{
StrokeThickness = 2,
Stroke = Brushes.DarkRed,
Data = geometryGroup
};
drawArea.Children.Add(path);
var titleLabel = new Label
{
Margin = new Thickness(drawArea.ActualWidth - 50, drawArea.ActualHeight - 20, 0, 0),
Content = title
};
drawArea.Children.Add(titleLabel);
}
private void PlotYAxes(Panel drawArea, int minimumY, int maximumY, int step, int miniLineExtent, string title)
{
var labelSize = new Size(30, 26);
var geometryGroup = new GeometryGroup();
var axePositionX = 0;
geometryGroup.Children.Add(new LineGeometry(new Point(axePositionX, 0), new Point(axePositionX, drawArea.ActualHeight)));
var factorY = drawArea.ActualHeight / (maximumY - minimumY);
for (var i = minimumY; i < maximumY; i )
if (i % step == 0)
{
geometryGroup.Children.Add(new LineGeometry(
new Point(axePositionX - miniLineExtent, (maximumY-i) * factorY),
new Point(axePositionX miniLineExtent, (maximumY-i) * factorY)));
drawArea.Children.Add(new Label
{
Width = labelSize.Width,
Height = labelSize.Height,
Margin = new Thickness(
axePositionX - miniLineExtent - labelSize.Width,
(maximumY - i) * factorY - (labelSize.Height / 2), 0, 0),
Content = i,
Foreground = Brushes.Black
});
}
var path = new Path
{
StrokeThickness = 2,
Stroke = Brushes.DarkRed,
Data = geometryGroup
};
drawArea.Children.Add(path);
var titleLabel = new Label
{
Margin = new Thickness(0, 0, 0, 0),
Content = title
};
drawArea.Children.Add(titleLabel);
}
private void PlotGraph(Point[] points, Panel drawArea, int minimumX, int maximumX, int minimumY, int maximumY)
{
var factorX = drawArea.ActualWidth / (maximumX-minimumX);
var factorY = drawArea.ActualHeight / (maximumY-minimumY);
for (var i = 0; i < points.Length; i )
{
points[i].X *= factorX;
//points[i].Y *= factorY;
points[i].Y = (maximumY - points[i].Y) * factorY; //since zero of Y should be in bottom we "swap" the Y value.
}
Polyline polyline = new Polyline();
polyline.StrokeThickness = 2;
polyline.Stroke = Brushes.Blue;
polyline.Points = new PointCollection(points);
drawArea.Children.Add(polyline);
}
private void GenerateGraphBtn_Click(object sender, RoutedEventArgs e)
{
//Step 1: define the data limits and generate the data, this has nothing to do with the view.
const int xmin = 0, xmax = 12;
const int ymin = 0, ymax = 800;
var graphPoints = GenerateGraphPoints(xmin, xmax, ymin, ymax);
GrpahArea.Children.Add(new Label
{
Content = "Profits over months",
Margin = new Thickness(GrpahArea.ActualWidth / 2 - 100, -50, 0, 0)
});
//Step 2: Draw yAxes
PlotYAxes(GrpahArea, ymin, ymax, 100, 2, "Profits");
//Step 3: Draw xAxes
PlotXAxes(GrpahArea, xmin, xmax, 1, 2, "Months");
//Step 4: Plot Grpah
var plotPoints = new Point[graphPoints.Length]; //graphPoints is our model, we usually wish to keep the original value of model.
graphPoints.CopyTo(plotPoints,0); //plotPoints is what we going to scale and adjust to the view.
PlotGraph(plotPoints, GrpahArea, xmin, xmax, ymin, ymax);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/384788.html
