Ejemplo n.º 1
0
        override public void generate()
        {
            //remove any old child graphical elements
            Children.Clear();

            //compute total volume of pairs
            double totalVolume = innerValues.Sum<double>(x=>x);
            totalVolume += outerValues.Sum<double>(x => x);

            //compute pair volumes
            List<double> pairVolumes = new List<double>();
            for (int x = 0; x < innerValues.Count(); x++)
            {
                pairVolumes.Add(innerValues[x] + outerValues[x]);
            }

            //determine rotational angles per pair
            List<double> pairRotationalAngles = new List<double>();
            pairVolumes.ForEach(x => pairRotationalAngles.Add((x / totalVolume)*360.0)); //in degrees!

            double h = 0.0; //hue
            double s = 0.0; //saturation

            for (int x = 0; x < innerValues.Count(); x++)
            {
                //Draw the outer ring
                Wedge w = new Wedge();
                w.center = center;
                w.sweep = pairRotationalAngles[x];
                w.innerRadius = (innerValues[x] / pairVolumes[x]) * 100.0;
                w.outerRadius = (outerValues[x] / pairVolumes[x]) * 100.0;
                w.rotationAngle = h;

                //vary the color by both hue and saturation (for the colorblind)
                Color c = ColorUtils.computeFromHSV(h, 1.0-s, 0.9);
                w.Fill = new SolidColorBrush(c);
                w.Stroke = System.Windows.Media.Brushes.Black;

                //use a slightly darker version of the color as the stroke on the wedge
                w.Stroke = new SolidColorBrush(scaled(c, .8));
                w.StrokeThickness = 2;

                //temporary labelling!
                w.ToolTip = outerValueLabels[x];
                this.Children.Add(w);

                //draw the inner ring
                w = new Wedge();
                w.center = center;
                w.sweep = pairRotationalAngles[x];
                w.innerRadius = 0.0;
                w.outerRadius = (innerValues[x] / pairVolumes[x]) * 100.0;
                w.rotationAngle = h;

                c = ColorUtils.computeFromHSV(h, 1.0-s, 0.75);
                w.Fill = new SolidColorBrush(c);
                w.Fill.Opacity = 1.0;
                w.Stroke = new SolidColorBrush(scaled(c, .8));
                w.StrokeThickness = 2;

                //temporary labelling!
                w.ToolTip = innerValueLabels[x];
                this.Children.Add(w);

                h += pairRotationalAngles[x];

                s += pairVolumes[x] / totalVolume;
            }
        }
Ejemplo n.º 2
0
        public override void generate()
        {
            //remove any old child graphical elements
            Children.Clear();

            //figure out the number of pie slices we will have
            int sliceCount = slices.Count();

            double angle = 0.0;

            double sliceIncrement = 360.0 / sliceCount;

            for (int s = 0; s < sliceCount; s++)
            {

                //determine the number of rings that we will have
                int ringCount = slices[s].rings.Count();

                //determine the ring increment
                double ringIncrement = (maxRadius - minRadius) / ringCount;
                double innerRadius = minRadius;

                for (int r = 0; r < ringCount; r++)
                {

                    //determine the number of wedges per ring
                    int wedgeCount = slices[s].rings[r].values.Count();

                    //determine the sweep increment
                    double wedgeIncrement = sliceIncrement / wedgeCount;

                    double wedgeAngle = angle;

                    double max = slices[s].rings[r].values.Max();

                    for (int w = 0; w < wedgeCount; w++)
                    {
                        //create a wedge...
                        Wedge wedge = new Wedge();
                        wedge.center = center;
                        wedge.innerRadius = innerRadius;
                        wedge.outerRadius = innerRadius + ((slices[s].rings[r].values[w] / max) * ringIncrement); //this needs to be adjusted to compare amongst the multiple data values at this level - max = 100%, then scale down from there...
                        wedge.sweep = wedgeIncrement;
                        wedge.rotationAngle = wedgeAngle;

                        wedge.Fill = new SolidColorBrush(ColorUtils.computeFromHSV(220.0, (double)w / (double)(wedgeCount), 0.85));
                        wedge.Stroke = System.Windows.Media.Brushes.Black;
                        wedge.StrokeThickness = 0.5;

                        Children.Add(wedge);

                        wedgeAngle += wedgeIncrement;
                    }

                    innerRadius += ringIncrement;
                }

                angle += sliceIncrement;
            }

            //draw all the circles...
            //draw outer circle
            Ellipse e = new Ellipse();
            e.Width = maxRadius;
            e.Height = maxRadius;
            e.Stroke = System.Windows.Media.Brushes.Black;
            e.StrokeThickness = 1.0;
            e.RenderTransform = new TranslateTransform(center.X, center.Y);

            //Children.Add(e);

            //draw inner circle
            e = new Ellipse();
            e.Width = minRadius;
            e.Height = minRadius;
            e.Stroke = System.Windows.Media.Brushes.Black;
            e.StrokeThickness = 1.0;
            e.RenderTransform = new TranslateTransform(center.X, center.Y);

            //Children.Add(e);

            for (int x = 0; x < sliceCount; x++)
            {
                Line l = new Line();
                l.X1 = minRadius * Math.Cos((x * (2 * Math.PI / sliceCount)));
                l.Y1 = minRadius * Math.Sin(x * (2 * Math.PI / sliceCount));
                l.X2 = maxRadius * Math.Cos(x * (2 * Math.PI / sliceCount));
                l.Y2 = maxRadius * Math.Sin(x * (2 * Math.PI / sliceCount));
                l.Stroke = System.Windows.Media.Brushes.Purple;

                l.StrokeThickness = 1.0;
                l.RenderTransform = new TranslateTransform(center.X, center.Y);
                //Children.Add(l);
            }

        }
Ejemplo n.º 3
0
        public override void generate()
        {
            //remove any old child graphical elements
            Children.Clear();

            //draw a scale underneath the other images
            for (double x = 10.0; x < 100.0; x+=10.0)
            {
                Ellipse ellipse = new Ellipse();
                ellipse.Width = x*2.0;
                ellipse.Height = x*2.0;
                ellipse.Stroke = System.Windows.Media.Brushes.LightBlue;
                ellipse.StrokeThickness = 0.5;
                ellipse.RenderTransform = new TranslateTransform(center.X - x, center.Y-x);
                this.Children.Add(ellipse);
            }

            int polyCount = data.Count(); //number of stars

            Star star = new Star();
            star.center = center;
            star.numPoints = polyCount;
            star.radii = new List<double>();

            double maxStarValue = 0.0;
            for (int x = 0; x < polyCount; x++)
            {
                if (data[x][starIndex] > maxStarValue)
                {
                    maxStarValue = data[x][starIndex];
                }
            }

            for (int x = 0; x < polyCount; x++)
            {
                star.radii.Add((data[x][starIndex]/maxStarValue)*100.0);
            }

            star.Fill = System.Windows.Media.Brushes.Khaki;
            star.Stroke = System.Windows.Media.Brushes.Brown;
            star.StrokeThickness = 0.5;

            //generate the points used to locate the pie charts, etc.
            star.generateGeometry();
            this.Children.Add(star);

            //build the wedges at each star tip
            for (int x = 0; x < polyCount; x++)
            {
                //compute information for wedges
                double sum = data[x].Sum<double>(z => z);
                sum -= data[x][starIndex]; //remove the value used to calculate the star arms from the pie chart total

                double angle = 0.0;

                for (int y = 0; y < data[x].Count(); y++)
                {
                    if (y != starIndex) //skip this index if it's the one used to calculate the star arms
                    {
                        //Draw the outer ring
                        Wedge w = new Wedge();
                        w.center = star.tips[x];
                        w.sweep = data[x][y] / sum * 90.0;
                        w.innerRadius = 0.0;
                        w.outerRadius = 50.0;
                        w.rotationAngle = angle;

                        //running total of value to aid with the colorblind!
                        Color c = ColorUtils.computeFromHSV(angle * 4.0, 1.0, 0.9);
                        w.Fill = new SolidColorBrush(c);
                        w.Stroke = System.Windows.Media.Brushes.Black;
                        w.Stroke = new SolidColorBrush(scaled(c, .8));
                        w.StrokeThickness = 0.5;
                        RotateTransform rotation = new RotateTransform(180 - 45 - (360.0 / polyCount) * x);
                        rotation.CenterX = star.tips[x].X;
                        rotation.CenterY = star.tips[x].Y;
                        w.RenderTransform = rotation;
                        this.Children.Add(w);

                        angle += w.sweep;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Recursively generates the wedges for each node in the hierarchical value tree.
        /// </summary>
        /// <param name="node">The node from which to create a wedge.</param>
        /// <param name="innerRadius">The inner radius of the wedge.</param>
        /// <param name="radius">The radius length (poor naming!).</param>
        /// <param name="arc">The arc of the wedge.</param>
        /// <param name="rotationalAngle">The rotational angle of the wedge (rotational transform, essentially).</param>
        private void generate(HierarchicalValue node, double innerRadius, double radius, double arc, double rotationalAngle)
        {
            Wedge wedge = new Wedge();

            wedge.center = center;
            wedge.innerRadius = innerRadius;
            wedge.outerRadius = innerRadius + radius;
            wedge.sweep = arc;
            wedge.rotationAngle = rotationalAngle;

            //use a default black stroke around each wedge
            wedge.Stroke = System.Windows.Media.Brushes.Black;
            wedge.StrokeThickness = 0.5;
            wedge.Fill = brushes[node.tag]; //lookup the unique color based on the tag for this node
            wedge.ToolTip = node.name;

            wedges.Add(wedge);

            //arc percentage for children...
            var h = rotationalAngle;

            if (rotationalAngle < 180.0)
            {
                //create wedges for all of the children of this node
                foreach (HierarchicalValue child in node.children)
                {
                    //sweep is related to the value the child contributes to the parent value
                    var angle = arc * (child.totalValues() / (node.totalValues() - node.value));
                    generate(child, wedge.outerRadius, radius, angle, h);
                    h += angle; //advance around the parent's arc
                }
            }
            else {
                // Process in reverse order
                //create wedges for all of the children of this node
                for(int i = node.children.Count - 1;i >= 0;i--)
                {
                    HierarchicalValue child = node.children[i];

                    //sweep is related to the value the child contributes to the parent value
                    var angle = arc * (child.totalValues() / (node.totalValues() - node.value));
                    generate(child, wedge.outerRadius, radius, angle, h);
                    h += angle; //advance around the parent's arc
                }
            }
        }