private void CreateNodesAndLinks(IEnumerable <SankeyData> datas) { currentSliceNodes = new List <SankeyNode>(); currentLinks = new List <SankeyLink>(); styleManager.DefaultNodeLinksPaletteIndex = 0; foreach (var data in datas) { if (!currentSliceNodes.Exists(n => n.Name == data.From)) { currentSliceNodes.Add(CreateNode(data, data.From)); } if (!currentSliceNodes.Exists(n => n.Name == data.To)) { currentSliceNodes.Add(CreateNode(data, data.To)); } var fromNode = currentSliceNodes.Find(findNode => findNode.Name == data.From); if (fromNode != null) { var toNode = currentSliceNodes.Find(findNode => findNode.Name == data.To); if (toNode != null) { // merge links which has the same from & to if (currentLinks != null) { var previousLink = currentLinks.Find(findLink => findLink.FromNode.Name == fromNode.Name && findLink.ToNode.Name == toNode.Name); if (previousLink != null) { previousLink.Weight += data.Weight; continue; } } // create link var shape = new Path(); shape.MouseEnter += LinkMouseEnter; shape.MouseLeave += LinkMouseLeave; shape.MouseLeftButtonUp += LinkMouseLeftButtonUp; shape.Tag = new SankeyLinkFinder(data.From, data.To); shape.Fill = diagram.UsePallette != SankeyPalette.None ? fromNode.Shape.Fill.CloneCurrentValue() : data.LinkBrush == null?styleManager.DefaultLinkBrush.CloneCurrentValue() : data.LinkBrush.CloneCurrentValue(); var link = new SankeyLink(fromNode, toNode, shape, data.Weight, shape.Fill.CloneCurrentValue()); fromNode.OutLinks.Add(link); toNode.InLinks.Add(link); currentLinks.Add(link); } } } }
private void RecoverHighlights(SankeyLink link, bool resetHighlightStatus = true) { link.Shape.Fill = link.OriginalBrush.CloneCurrentValue(); link.FromNode.Shape.Fill = link.FromNode.OriginalBrush.CloneCurrentValue(); link.ToNode.Shape.Fill = link.ToNode.OriginalBrush.CloneCurrentValue(); link.ToNode.Label.Style = link.FromNode.Label.Style = diagram.LabelStyle; link.ToNode.Label.Opacity = link.FromNode.Label.Opacity = OriginalLabelOpacity; if (resetHighlightStatus) { link.IsHighlight = false; link.FromNode.IsHighlight = false; link.ToNode.IsHighlight = false; } }
private SankeyLink DrawLink(SankeyLink link) { // create tooltip var toolTip = new ToolTip(); toolTip.Template = diagram.ToolTipTemplate; link.Shape.ToolTip = toolTip; toolTip.DataContext = link; var startPoint = new Point(); var line1EndPoint = new Point(); var bezier1ControlPoint1 = new Point(); var bezier1ControlPoint2 = new Point(); var bezier1EndPoint = new Point(); var line2EndPoint = new Point(); var bezier2ControlPoint1 = new Point(); var bezier2ControlPoint2 = new Point(); if (diagram.SankeyFlowDirection == FlowDirection.TopToBottom) { line1EndPoint.Y = startPoint.Y = link.FromNode.Y + link.FromNode.Shape.Height; bezier2ControlPoint2.X = startPoint.X = link.FromNode.X + link.FromPosition; bezier1ControlPoint1.X = line1EndPoint.X = startPoint.X + link.Width; line2EndPoint.Y = bezier1EndPoint.Y = link.ToNode.Y; bezier2ControlPoint1.X = line2EndPoint.X = link.ToNode.X + link.ToPosition; bezier1ControlPoint2.X = bezier1EndPoint.X = line2EndPoint.X + link.Width; var length = line2EndPoint.Y - line1EndPoint.Y; bezier2ControlPoint2.Y = bezier1ControlPoint1.Y = diagram.LinkCurvature * length + startPoint.Y; bezier2ControlPoint1.Y = bezier1ControlPoint2.Y = (1 - diagram.LinkCurvature) * length + startPoint.Y; } else { line1EndPoint.X = startPoint.X = link.FromNode.X + link.FromNode.Shape.Width; bezier2ControlPoint2.Y = startPoint.Y = link.FromNode.Y + link.FromPosition; bezier1ControlPoint1.Y = line1EndPoint.Y = startPoint.Y + link.Width; line2EndPoint.X = bezier1EndPoint.X = link.ToNode.X; bezier2ControlPoint1.Y = line2EndPoint.Y = link.ToNode.Y + link.ToPosition; bezier1ControlPoint2.Y = bezier1EndPoint.Y = line2EndPoint.Y + link.Width; var length = line2EndPoint.X - line1EndPoint.X; bezier2ControlPoint2.X = bezier1ControlPoint1.X = diagram.LinkCurvature * length + startPoint.X; bezier2ControlPoint1.X = bezier1ControlPoint2.X = (1 - diagram.LinkCurvature) * length + startPoint.X; } var geometry = new PathGeometry() { Figures = new PathFigureCollection() { new PathFigure() { StartPoint = startPoint, Segments = new PathSegmentCollection() { new LineSegment() { Point = line1EndPoint }, new BezierSegment() { Point1 = bezier1ControlPoint1, Point2 = bezier1ControlPoint2, Point3 = bezier1EndPoint }, new LineSegment() { Point = line2EndPoint }, new BezierSegment() { Point1 = bezier2ControlPoint1, Point2 = bezier2ControlPoint2, Point3 = startPoint } } }, } }; link.Shape.Data = geometry; return(link); }