DevExpress_Chart3DEX

using System.Collections.Generic; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Media3D; using _3DTools; using DevExpress.Xpf.Charts; using DevExpress.Xpf.Charts.Native; namespace zybio.DMP.Client.Commons { public class Chart3DContainerEx : Chart3DContainer { Viewport3D viewport3D { get { var prop = typeof(Chart3DContainer).GetField("viewport3D", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (prop != null) { return prop.GetValue(this) as Viewport3D; } return null; } } Chart3DControlEx chart3dControl; public Chart3DContainerEx(Chart3DControlEx chart) : base(chart) { chart3dControl = chart; } protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); viewport3D.Children.Clear(); XYZChartDomainEx domain = CreateDomain(viewport3D); domain.ValidateSeriesPointsCache(); domain.Render(viewport3D); } XYZChartDomainEx CreateDomain(Viewport3D visualContainer) { return new XYZChartDomainEx(chart3dControl, new Rect(0, 0, visualContainer.RenderSize.Width, visualContainer.RenderSize.Height), new XYZChartBox(chart3dControl)); } } public class XYZChartDomainEx : XYZChartDomain { public new Chart3DControlEx Chart { get; } double PlaneDepthFixed { get { return Chart.PlaneDepthFixed; } } XYZAxis3DInfo axisXInfo { get { var field = typeof(XYZChartDomain).GetField("axisXInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as XYZAxis3DInfo; } return null; } set { var field = typeof(XYZChartDomain).GetField("axisXInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { field.SetValue(this, value); } } } XYZAxis3DInfo axisZInfo { get { var field = typeof(XYZChartDomain).GetField("axisZInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as XYZAxis3DInfo; } return null; } set { var field = typeof(XYZChartDomain).GetField("axisZInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { field.SetValue(this, value); } } } XYZAxis3DInfo axisYInfo { get { var field = typeof(XYZChartDomain).GetField("axisYInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as XYZAxis3DInfo; } return null; } set { var field = typeof(XYZChartDomain).GetField("axisYInfo", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { field.SetValue(this, value); } } } List<Series3DLabelData> SeriesLabelDataList { get { var field = typeof(XYZChartDomain).GetField("seriesLabelDataList", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as List<Series3DLabelData>; } return null; } set { var field = typeof(XYZChartDomain).GetField("seriesLabelDataList", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { field.SetValue(this, value); } } } public AxesBoxCreator BoxCreator { get { var field = typeof(XYZChartDomain).GetField("boxCreator", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as AxesBoxCreator; } return null; } set { var field = typeof(XYZChartDomain).GetField("boxCreator", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { field.SetValue(this, value); } } } private BoxPlane VisiblePlanes { get { var field = typeof(XYZChartDomain).GetField("visiblePlanes", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return (BoxPlane)field.GetValue(this); } return BoxPlane.Back | BoxPlane.Bottom | BoxPlane.Fore | BoxPlane.Left | BoxPlane.Right | BoxPlane.Top; } set { var field = typeof(XYZChartDomain).GetField("visiblePlanes", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { field.SetValue(this, value); } } } public XYZChartDomainEx(Chart3DControlEx chart, Rect viewport, XYZChartBox chartBox) : base(chart, viewport, chartBox) { Chart = chart; if (Chart.AxisMode == EnAxisMode.Cube) { BoxCreator = new CubeXYZAxesBoxCreator(this, chart.Cache, DiagramBox); } else { BoxCreator = new XYZAxesBoxCreator(this, chart.Cache, DiagramBox, VisiblePlanes); } } public new void Render(Viewport3D visualContainer) { ModelVisual3D modelVisual = new ModelVisual3D(); Model3DGroup modelHolder = new Model3DGroup(); modelHolder.Transform = ModelTransform; Render3DContent(modelHolder, visualContainer); Model3DGroup group = new Model3DGroup(); group.Children.Add(CreateLighting()); group.Children.Add(modelHolder); modelVisual.Content = group; visualContainer.Camera = Camera; visualContainer.Children.Add(modelVisual); visualContainer.Clip = new RectangleGeometry(Viewport); } void Render3DContent(Model3DGroup modelHolder, Viewport3D visualContainer) { Crosshair3DHolder crosshairHolder = CreateCrosshair3DHolder(); if (Chart.AxisMode == EnAxisMode.Cube) { ((CubeXYZAxesBoxCreator)BoxCreator).CreateDiagramModel(modelHolder, visualContainer); } else { BoxCreator.CreateDiagramModel(modelHolder); } CreateSeriesModel(modelHolder); BoxCreator.CreateAxesLabels(modelHolder); CreateSeriesLabelsModel(modelHolder); CreateCrosshairModel(modelHolder, crosshairHolder); Chart.Cache.ProjectionContainer.ApplyProjectionPosition(VisiblePlanes, DiagramBox); } Crosshair3DHolder CreateCrosshair3DHolder() { if (Chart.Cache.Crosshair3DHolder == null) Chart.Cache.Crosshair3DHolder = new Crosshair3DHolder(); Chart.Cache.Crosshair3DHolder.AxisXInfo = axisXInfo; Chart.Cache.Crosshair3DHolder.AxisZInfo = axisZInfo; Chart.Cache.Crosshair3DHolder.AxisYInfo = axisYInfo; Chart.Cache.Crosshair3DHolder.ScaleFactor = CrosshairScaleFactor; return Chart.Cache.Crosshair3DHolder; } void CreateSeriesModel(Model3DGroup modelHolder) { if (Chart.Cache.SeriesModel == null) { var method = typeof(XYZChartDomain).GetMethod("CreateSeriesModel", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.ExactBinding); var obj = method.Invoke(this, new object[] { Chart.Cache.ProjectionContainer }); if (obj is Model3D seriesModel) { Chart.Cache.SeriesModel = seriesModel; } } //Chart.Cache.SeriesModel = CreateSeriesModel(); modelHolder.Children.Add(Chart.Cache.SeriesModel); } void CreateSeriesLabelsModel(Model3DGroup modelHolder) { List<LabelModelContainer> labelContainers = new List<LabelModelContainer>(); foreach (Series3DLabelData seriesData in SeriesLabelDataList) seriesData.CreateLabelsModel(this, modelHolder, labelContainers, Chart.ViewController.GetRefinedSeries(seriesData.Series)); foreach (LabelModelContainer modelContainer in labelContainers) modelHolder.Children.Add(modelContainer.Model); } void CreateCrosshairModel(Model3DGroup modelHolder, Crosshair3DHolder crosshairHolder) { Model3D model = CreateCrosshairModel(); crosshairHolder.CrosshairModel = model; modelHolder.Children.Add(model); } Model3D CreateCrosshairModel() { Model3DGroup marker = new Model3DGroup(); if (Chart.ActualCrosshairOptions.ShowMarker) { var markerModel = Chart.ActualCrosshairOptions.MarkerModel ?? CreateDefaultMarkerModel(); marker.Children.Add(markerModel); } marker.Transform = new ScaleTransform3D(0, 0, 0); AssignTagObjectToMeshModel(marker, new CrosshairMarker3D()); return marker; } Model3D CreateDefaultMarkerModel() { SphereModelCalculator sphereModelCalculator = new SphereModelCalculator(8); GeometryInfo geometry = sphereModelCalculator.GetGeometry(1); MeshGeometry3D marker1 = new MeshGeometry3D() { Positions = geometry.Points, TriangleIndices = geometry.TriangleIndices }; MaterialGroup material = new MaterialGroup(); material.Children.Add(new DiffuseMaterial(new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xDE, 0x39, 0xCD)))); material.Children.Add(new SpecularMaterial(new SolidColorBrush(System.Windows.Media.Color.FromRgb(229, 229, 229)), 20.0)); return new GeometryModel3D(marker1, material); } void AssignTagObjectToMeshModel(Model3D model, object tag) { Model3DGroup model3DGroup = model as Model3DGroup; if (model3DGroup != null) { foreach (Model3D child in model3DGroup.Children) AssignTagObjectToMeshModel(child, tag); } else { GeometryModel3D geometryModel3D = model as GeometryModel3D; if (geometryModel3D != null) { MeshGeometry3D meshGeometry3D = geometryModel3D.Geometry as MeshGeometry3D; if (meshGeometry3D != null) meshGeometry3D.SetValue(FrameworkElement.TagProperty, tag); } } } } public class Chart3DControlEx : DevExpress.Xpf.Charts.Chart3DControl { public Chart3DControlEx() : base() { var diagramContainer = new Chart3DContainerEx(this); var prop = typeof(DevExpress.Xpf.Charts.Chart3DControl).GetField("diagramContainer", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); prop.SetValue(this, diagramContainer); } public new ViewController ViewController { get { var field = typeof(DevExpress.Xpf.Charts.Chart3DControl).GetField("viewController", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as ViewController; } return null; } } public XYZChartCache Cache { get { var field = typeof(DevExpress.Xpf.Charts.Chart3DControl).GetProperty("Cache", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.ExactBinding); if (field != null) { return field.GetValue(this) as XYZChartCache; } return null; } } public Crosshair3DOptions ActualCrosshairOptions { get { return CrosshairOptions ?? new Crosshair3DOptions(); } } public EnAxisMode AxisMode { get; set; } = EnAxisMode.Cube; } public enum EnAxisMode { Panel = 0, Cube = 1 } /// <summary> /// 顯示立方體座標 /// </summary> public class CubeXYZAxesBoxCreator : XYZAxesBoxCreator { IDomainBox3D _domain; XYZChartCache _cache; Diagram3DBox _diagramBox; ScreenSpaceLines3D AxisX1 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisX2 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisX3 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisX4 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisY1 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisY2 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisY3 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisY4 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisZ1 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisZ2 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisZ3 { get; set; } = new ScreenSpaceLines3D(); ScreenSpaceLines3D AxisZ4 { get; set; } = new ScreenSpaceLines3D(); public CubeXYZAxesBoxCreator(IDomainBox3D domain, XYZChartCache cache, Diagram3DBox diagramBox) : base(domain, cache, diagramBox, BoxPlane.None) { _domain = domain; _cache = cache; _diagramBox = diagramBox; } public void CreateDiagramModel(Model3DGroup modelHolder, Viewport3D visualContainer) { CalcDiagramPlanes(modelHolder.Transform); visualContainer.Children.Add(AxisX1); visualContainer.Children.Add(AxisX2); visualContainer.Children.Add(AxisX3); visualContainer.Children.Add(AxisX4); visualContainer.Children.Add(AxisY1); visualContainer.Children.Add(AxisY2); visualContainer.Children.Add(AxisY3); visualContainer.Children.Add(AxisY4); visualContainer.Children.Add(AxisZ1); visualContainer.Children.Add(AxisZ2); visualContainer.Children.Add(AxisZ3); visualContainer.Children.Add(AxisZ4); } void CalcDiagramPlanes(Transform3D trans) { double correction = Diagram3DBox.DiagramPlanesCorrection; Point3D zeroPoint = new Point3D(-correction, -correction, -correction); zeroPoint = new Point3D(zeroPoint.X, zeroPoint.Y, zeroPoint.Z); correction *= 2; double width = _diagramBox.InnerWidth + correction; double height = _diagramBox.InnerHeight + correction; double depth = _diagramBox.InnerDepth + correction; double xMin = zeroPoint.X, yMin = zeroPoint.Y, zMin = zeroPoint.Z; double xMax = width, yMax = height, zMax = depth; //座標軸顏色,採取Chart的DomainBrush屬性 var brush = ((XYZChartDomainEx)_domain).Chart.DomainBrush; System.Windows.Media.Color axisColor = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(brush.ToString()); AxisX1.Color = axisColor; AxisX1.Transform = trans; AxisX1.Points.Add(new Point3D(xMin, yMin, zMin)); AxisX1.Points.Add(new Point3D(xMax, yMin, zMin)); AxisX2.Color = axisColor; AxisX2.Transform = trans; AxisX2.Points.Add(new Point3D(xMin, yMin, zMax)); AxisX2.Points.Add(new Point3D(xMax, yMin, zMax)); AxisX3.Color = axisColor; AxisX3.Transform = trans; AxisX3.Points.Add(new Point3D(xMin, yMax, zMax)); AxisX3.Points.Add(new Point3D(xMax, yMax, zMax)); AxisX4.Color = axisColor; AxisX4.Transform = trans; AxisX4.Points.Add(new Point3D(xMin, yMax, zMin)); AxisX4.Points.Add(new Point3D(xMax, yMax, zMin)); AxisY1.Color = axisColor; AxisY1.Transform = trans; AxisY1.Points.Add(new Point3D(xMin, yMin, zMin)); AxisY1.Points.Add(new Point3D(xMin, yMax, zMin)); AxisY2.Color = axisColor; AxisY2.Transform = trans; AxisY2.Points.Add(new Point3D(xMax, yMin, zMin)); AxisY2.Points.Add(new Point3D(xMax, yMax, zMin)); AxisY3.Color = axisColor; AxisY3.Transform = trans; AxisY3.Points.Add(new Point3D(xMax, yMin, zMax)); AxisY3.Points.Add(new Point3D(xMax, yMax, zMax)); AxisY4.Color = axisColor; AxisY4.Transform = trans; AxisY4.Points.Add(new Point3D(xMin, yMin, zMax)); AxisY4.Points.Add(new Point3D(xMin, yMax, zMax)); AxisZ1.Color = axisColor; AxisZ1.Transform = trans; AxisZ1.Points.Add(new Point3D(xMin, yMin, zMin)); AxisZ1.Points.Add(new Point3D(xMin, yMin, zMax)); AxisZ2.Color = axisColor; AxisZ2.Transform = trans; AxisZ2.Points.Add(new Point3D(xMax, yMin, zMin)); AxisZ2.Points.Add(new Point3D(xMax, yMin, zMax)); AxisZ3.Color = axisColor; AxisZ3.Transform = trans; AxisZ3.Points.Add(new Point3D(xMax, yMax, zMin)); AxisZ3.Points.Add(new Point3D(xMax, yMax, zMax)); AxisZ4.Color = axisColor; AxisZ4.Transform = trans; AxisZ4.Points.Add(new Point3D(xMin, yMax, zMin)); AxisZ4.Points.Add(new Point3D(xMin, yMax, zMax)); } } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章