//========= 方法 ///<summary>添加节点</summary> public SettleNode addNode(string name) { SettleNode node = new SettleNode(owner, this); node.nodename = name; nodes.Add(node); return node; }
void genNode(SettleNode pnode, EnumerableRowCollection <DataRow> rows, int colidx) { int colcount = DataSource.Table.Columns.Count; int idx = 0; foreach (string sortname in rows.GroupBy(p => p.Field <string>(colidx)).OrderBy(p => p.Key).Select(p => p.Key)) { SettleNode node = pnode.addNode(sortname); if (colidx == 0) { node.mbrush = MediaHelper.getSolidBrush((EMaterailColor)idx, EMaterialColorDeep.浅色).Clone(); idx++; } else { node.mbrush = pnode.mbrush.Clone(); } node.splitDir = colidx % 2 != 0 ? SettleNode.ESplitDir.z方向 : SettleNode.ESplitDir.x方向; if (colcount - 3 == colidx) { node.energy = rows.Where(p => p.Field <string>(colidx) == sortname).Sum(p => double.Parse(p[colcount - 2].ToString())); node.fee = rows.Where(p => p.Field <string>(colidx) == sortname).Sum(p => double.Parse(p[colcount - 2].ToString()) * double.Parse(p[colcount - 1].ToString())); } else { EnumerableRowCollection <DataRow> subrows = rows.Where(p => p.Field <string>(colidx) == sortname); genNode(node, subrows, colidx + 1); } } }
public void init() { mgAll.Children.Add(mgModel); mgAll.Children.Add(mgLabel); mgAll.Children.Add(mgFlag); root.initModel(); curSettle = root; }
///<summary>数据源更新,重构数据类</summary> private void updateData() { SettleNode root = new SettleNode(_datas); root.nodename = rootTitle; root.mbrush = new SolidColorBrush(Colors.OrangeRed); root.splitDir = SettleNode.ESplitDir.z方向; genNode(root, DataSource.Table.AsEnumerable(), 0); _datas.root = root; }
private void createPie(SettleNode node) { GeometryModel3D model, labelmodel; MeshGeometry3D mesh; MaterialGroup mat; Model3DGroup mgmodel = new Model3DGroup(); Model3DGroup mglabel = new Model3DGroup(); double sum = node.nodes.Sum(p => p.fee); double startAngle = 0, endAngle; double radius = 1; double holeradius = 0.5 * radius, heightratio = 1; int segcount = 1; int coloridx = 0; foreach (SettleNode e0 in node.nodes) { endAngle = startAngle + e0.fee / sum * 360; segcount = (int)Math.Abs((endAngle - startAngle) * 4); mesh = Model3DHelper.genPieSlice(radius, holeradius, heightratio, startAngle, endAngle, segcount, Model3DHelper.EPieType.棱形面); mat = (MaterialGroup)this.FindResource("matslice" + (coloridx % 12).ToString()); model = new GeometryModel3D(mesh, mat); mgmodel.Children.Add(model); Vector3D vec = new Vector3D(); vec.X = 1.1 * radius * Math.Cos((startAngle + endAngle) / 2 / 180 * Math.PI); vec.Y = model.Bounds.SizeY; /// 2; vec.Z = -1.1 * radius * Math.Sin((startAngle + endAngle) / 2 / 180 * Math.PI); mesh = (MeshGeometry3D)this.FindResource("meshText"); string text = e0.nodename + ":" + (e0.fee / sum).ToString("p1"); labelmodel = Model3DHelper.genTextPanel(mesh, Brushes.White, new SolidColorBrush(darkc[coloridx % 12]), 32, text, rotationY, 0.2, vec, 0.5, 0.38); mglabel.Children.Add(labelmodel); //重新绑定旋转 AxisAngleRotation3D axis3d = new AxisAngleRotation3D(); axis3d.Axis = new Vector3D(0, 1, 0); Binding anglebind = new Binding(); anglebind.Source = rotationY; anglebind.Path = new PropertyPath(AxisAngleRotation3D.AngleProperty); anglebind.Mode = BindingMode.OneWay; anglebind.Converter = new ConverterNegative(); BindingOperations.SetBinding(axis3d, AxisAngleRotation3D.AngleProperty, anglebind); ((labelmodel.Transform as Transform3DGroup).Children[1] as RotateTransform3D).Rotation = axis3d; startAngle = endAngle; coloridx++; } mgRight.Children.Add(mgmodel); mgRight.Children.Add(mglabel); }
/// <summary> /// 显示细节回调函数 /// </summary> /// <param name="ray3DResult">射线测试结果</param> /// <param name="mousePoint">点击的屏幕坐标点</param> /// <returns>是否命中模型显示了要细节</returns> private bool showDetail(RayMeshGeometry3DHitTestResult ray3DResult, Point mousePoint) { SettleNode one = ray3DResult.ModelHit.GetValue(ToolTipService.ToolTipProperty) as SettleNode; //======= 注:点击打开细节视图 if (one != null) { toolTips.IsOpen = false; //isclick = true; UCDetail.showNodeDetail(one, mousePoint - new Point(mainViewport3D.ActualWidth / 2, mainViewport3D.ActualHeight / 2)); return(true); } else { if (UCDetail.Visibility == Visibility.Visible) { UCDetail.closeDetail(); } return(false); } }
private void addCube(SettleNode node) { GeometryModel3D model; MeshGeometry3D mesh; MaterialGroup mat; Transform3DGroup tg; ////底 //mesh = Share.Model3DHelper.genCubePlaneMesh(4); //mat = (MaterialGroup)Application.Current.FindResource("matTransWhite"); //model = new GeometryModel3D(mesh, mat); //tg = new Transform3DGroup(); //tg.Children.Add(new ScaleTransform3D(1, 1, 1, -1, 0, 0)); //tg.Children.Add(new TranslateTransform3D(-1, -1, 0)); //model = new GeometryModel3D(mesh, mat); //model.Transform = tg; //mgLeft.Children.Add(model); ////顶 //mesh = Share.Model3DHelper.genCubePlaneMesh(4); //mat = (MaterialGroup)Application.Current.FindResource("matTransWhite"); //model = new GeometryModel3D(mesh, mat); //tg = new Transform3DGroup(); //tg.Children.Add(new ScaleTransform3D(1, 1, 1, -1, 0, 0)); //tg.Children.Add(new TranslateTransform3D(-1, 1, 0)); //model = new GeometryModel3D(mesh, mat); //model.Transform = tg; //mgLeft.Children.Add(model); //主体 mat = (MaterialGroup)Application.Current.FindResource("matTransRed"); mesh = (MeshGeometry3D)Application.Current.FindResource("meshCyl"); tg = new Transform3DGroup(); tg.Children.Add(new ScaleTransform3D(1, 2, 1, 0, -1, 0)); tg.Children.Add(new TranslateTransform3D(0, 1, 0)); model = new GeometryModel3D(mesh, mat); model.Transform = tg; mgLeft.Children.Add(model); }
/// <summary> /// 显示Tooltips回调函数 /// </summary> /// <param name="ray3DResult">射线测试结果</param> /// <param name="position">鼠标移动的屏幕坐标点</param> /// <returns>是否命中模型显示了Tooltips</returns> private bool showTooltips(RayMeshGeometry3DHitTestResult ray3DResult, Point position) { SettleNode one = ray3DResult.ModelHit.GetValue(ToolTipService.ToolTipProperty) as SettleNode; //===== tooltips if (one != null) { //填充信息 ttContent.Text = String.Format("{0}:{1:f0}\r\n{2}:{3:f0}\r\n{4}:{5:f4}", volumeTitle, one.fee, heightTitle, one.energy, sectionTitle, one.price); double ToolTipOffset = 5; toolTips.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint; toolTips.PlacementTarget = mainViewport3D; toolTips.HorizontalOffset = position.X + ToolTipOffset; toolTips.VerticalOffset = position.Y + ToolTipOffset; toolTips.IsOpen = true; return(true); } else { toolTips.IsOpen = false; return(false); } }
internal void showNodeDetail(SettleNode node, Vector vec_translate) { vectranslate = vec_translate; ScaleTransform3D mscale;//,scale; //TranslateTransform3D translate; title.Text = node.nodename; if (mgLeft.Children.Count == 0) { addCube(node); } //主体 mscale = (((mgLeft as Model3DGroup).Children[0] as GeometryModel3D).Transform as Transform3DGroup).Children[0] as ScaleTransform3D; mscale.ScaleX = node.scaleVec.X / node.layerScale * 3; mscale.ScaleY = node.scaleVec.Y / node.layerScale; mscale.ScaleZ = node.scaleVec.Z / node.layerScale * 3; ////顶 //scale = (((mgLeft as Model3DGroup).Children[1] as GeometryModel3D).Transform as Transform3DGroup).Children[0] as ScaleTransform3D; //scale.ScaleZ = node.scaleVec.Z / node.layerScale * 3; //translate = (((mgLeft as Model3DGroup).Children[1] as GeometryModel3D).Transform as Transform3DGroup).Children[1] as TranslateTransform3D; //translate.OffsetY = mscale.ScaleY*2-1.001; ////底 //scale = (((mgLeft as Model3DGroup).Children[0] as GeometryModel3D).Transform as Transform3DGroup).Children[0] as ScaleTransform3D; //scale.ScaleZ = node.scaleVec.Z / node.layerScale * 3; //电量标志 grdFlag.Children.Clear(); Point ptop, pbottom, pcenter, pfronttop, pfrontbottom; GeneralTransform3DTo2D gtransform = modelMain.TransformToAncestor(grdmain); ptop = gtransform.Transform(new Point3D(mgLeft.Bounds.X, mgLeft.Bounds.Y + mgLeft.Bounds.SizeY, 0)); pbottom = gtransform.Transform(new Point3D(mgLeft.Bounds.X, mgLeft.Bounds.Y, 0)); pcenter = gtransform.Transform(new Point3D(mgLeft.Bounds.X + mgLeft.Bounds.SizeX / 2, mgLeft.Bounds.Y, 0)); pfronttop = gtransform.Transform(new Point3D(mgLeft.Bounds.X + mgLeft.Bounds.SizeX / 2, mgLeft.Bounds.Y + mgLeft.Bounds.SizeY, mgLeft.Bounds.Z + mgLeft.Bounds.SizeZ)); pfrontbottom = gtransform.Transform(new Point3D(mgLeft.Bounds.X + mgLeft.Bounds.SizeX / 2, mgLeft.Bounds.Y, mgLeft.Bounds.Z + mgLeft.Bounds.SizeZ)); Path path; path = new Path() { StrokeThickness = 1, Stroke = Brushes.White }; PathGeometry geo = new PathGeometry(); PathFigure fig = new PathFigure(); fig.StartPoint = ptop; fig.Segments.Add(new LineSegment(new Point(ptop.X - 10, ptop.Y), true)); fig.Segments.Add(new LineSegment(new Point(ptop.X - 10, pbottom.Y), true)); fig.Segments.Add(new LineSegment(new Point(pbottom.X, pbottom.Y), true)); geo.Figures.Add(fig); fig = new PathFigure(); fig.StartPoint = new Point(ptop.X - 10, (ptop.Y + pbottom.Y) / 2); fig.Segments.Add(new LineSegment(new Point(ptop.X - 45, (ptop.Y + pbottom.Y) / 2), true)); fig.Segments.Add(new LineSegment(new Point(ptop.X - 65, (ptop.Y + pbottom.Y) / 2 - 10), true)); geo.Figures.Add(fig); path.Data = geo; grdFlag.Children.Add(path); path = new Path() { StrokeThickness = 1, Fill = Brushes.Blue }; path.Data = new EllipseGeometry(new Point(ptop.X - 65, (ptop.Y + pbottom.Y) / 2 - 10), 5, 5); grdFlag.Children.Add(path); TextBlock txt = new TextBlock() { Foreground = Brushes.Yellow, VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left }; txt.Text = heightTitle + ":" + node.energy.ToString("f0"); txt.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); txt.Margin = new Thickness(ptop.X - 65 - txt.DesiredSize.Width / 2, (ptop.Y + pbottom.Y) / 2 - 10 - txt.DesiredSize.Height - 5, 0, 0); grdFlag.Children.Add(txt); //电价标志 path = new Path() { StrokeThickness = 1, Stroke = Brushes.White }; geo = new PathGeometry(); fig = new PathFigure(); fig.StartPoint = new Point(pcenter.X, ptop.Y); fig.Segments.Add(new LineSegment(new Point(pcenter.X, ptop.Y - 20), true)); fig.Segments.Add(new LineSegment(new Point(pcenter.X - 50, ptop.Y - 40), true)); geo.Figures.Add(fig); path.Data = geo; grdFlag.Children.Add(path); path = new Path() { StrokeThickness = 1, Fill = Brushes.Blue }; path.Data = new EllipseGeometry(new Point(pcenter.X - 50, ptop.Y - 40), 5, 5); grdFlag.Children.Add(path); txt = new TextBlock() { Foreground = Brushes.Yellow, VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left }; txt.Text = sectionTitle + ":" + node.price.ToString("f4"); txt.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); txt.Margin = new Thickness(pcenter.X - 50 - txt.DesiredSize.Width / 2, ptop.Y - 40 - txt.DesiredSize.Height - 5, 0, 0); grdFlag.Children.Add(txt); //费用标志 path = new Path() { StrokeThickness = 1, Stroke = Brushes.White }; geo = new PathGeometry(); fig = new PathFigure(); fig.StartPoint = new Point(pcenter.X, pfronttop.Y + (pfrontbottom.Y - pfronttop.Y) * 0.25); fig.Segments.Add(new LineSegment(new Point(pcenter.X + 60, pfronttop.Y + (pfrontbottom.Y - pfronttop.Y) * 0.25), true)); fig.Segments.Add(new LineSegment(new Point(pcenter.X + 80, pfronttop.Y + (pfrontbottom.Y - pfronttop.Y) * 0.25 - 20), true)); geo.Figures.Add(fig); path.Data = geo; grdFlag.Children.Add(path); path = new Path() { StrokeThickness = 1, Fill = Brushes.Blue }; path.Data = new EllipseGeometry(new Point(pcenter.X + 80, pfronttop.Y + (pfrontbottom.Y - pfronttop.Y) * 0.25 - 20), 5, 5); grdFlag.Children.Add(path); txt = new TextBlock() { Foreground = Brushes.Yellow, VerticalAlignment = VerticalAlignment.Top, HorizontalAlignment = HorizontalAlignment.Left }; txt.Text = volumeTitle + ":" + node.fee.ToString("f0"); txt.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); txt.Margin = new Thickness(pcenter.X + 60, pfronttop.Y + (pfrontbottom.Y - pfronttop.Y) * 0.25 - 20 - txt.DesiredSize.Height - 5, 0, 0); grdFlag.Children.Add(txt); mgRight.Children.Clear(); createPie(node); //动画放大 this.Visibility = Visibility.Visible; thisScale.BeginAnimation(ScaleTransform.ScaleXProperty, daOpen); thisScale.BeginAnimation(ScaleTransform.ScaleYProperty, daOpen); DoubleAnimation tax = new DoubleAnimation(vectranslate.X, 0, TimeSpan.FromSeconds(0.3), FillBehavior.HoldEnd); DoubleAnimation tay = new DoubleAnimation(vectranslate.Y, 0, TimeSpan.FromSeconds(0.3), FillBehavior.HoldEnd); thisTranslate.BeginAnimation(TranslateTransform.XProperty, tax); thisTranslate.BeginAnimation(TranslateTransform.YProperty, tay); }
public SettleNode(SettleDatas zowner, SettleNode zparent) { owner = zowner; parent = zparent; }