Пример #1
0
        public void InternalRegenerateCloud()
        {
            _source = new WriteableBitmap((int)_layoutRoot.ActualWidth, (int)_layoutRoot.ActualHeight);
            int arraySize = (int)((_layoutRoot.ActualWidth / 4) + 2) * (int)((_layoutRoot.ActualHeight / 4) + 2);

            _mapping = new int[arraySize];
            for (int i = 0; i < arraySize; i++)
            {
                _mapping[i] = -1;
            }

            if (Entries.Count() < 2)
            {
                _image.Source = _source;
                _image.InvalidateArrange();
                return;
            }

            _random = new Random(10202);

            double minSize = Entries.OrderByDescending(e => e.SizeValue).Take(MaxWords).Min(e => e.SizeValue);

            if (!double.IsNaN(MinimumValue))
            {
                minSize = Math.Min(MinimumValue, minSize);
            }
            double maxSize  = Math.Max(Entries.Max(e => e.SizeValue), MinimumLargestValue);
            double range    = Math.Max(0.00001, maxSize - minSize);
            double minColor = Entries.OrderByDescending(e => e.SizeValue).Take(MaxWords).Min(e => e.ColorValue);
            double maxColor = Entries.OrderByDescending(e => e.SizeValue).Take(MaxWords).Max(e => e.ColorValue);
            double maxAngle = Entries.OrderByDescending(e => e.SizeValue).Take(MaxWords).Max(e => e.Angle);

            if (!double.IsNaN(MinimumLargestAngleValue))
            {
                maxAngle = Math.Max(MinimumLargestAngleValue, maxAngle);
            }
            double minAngle = Entries.OrderByDescending(e => e.SizeValue).Take(MaxWords).Min(e => e.Angle);

            if (!double.IsNaN(MaximumLowestAngleValue))
            {
                minAngle = Math.Min(MaximumLowestAngleValue, minAngle);
            }


            double colorRange = Math.Max(0, maxColor - minColor);

            double angleRange = Math.Max(0, maxAngle - minAngle);

            //If there's a centre value then specify the range
            if (!double.IsNaN(AngleCenterValue))
            {
                var lr = AngleCenterValue - minAngle;
                var ur = maxAngle - AngleCenterValue;
                angleRange = Math.Max(ur, lr);
            }


            var txt = new TextBlock
            {
                FontFamily = FontFamily,
                FontSize   = 100,
                Text       = "x"
            };


            double areaPerLetter = ((txt.ActualWidth)) / (range);

            double         targetWidth    = _layoutRoot.ActualWidth * LargestSizeWidthProportion;
            WordCloudEntry od             = Entries.OrderByDescending(e => (e.SizeValue - minSize) * e.Word.Length).First();
            double         maxFontSize    = Math.Max(MinFontSize * 2.7, 100 / (((od.SizeValue - minSize) * od.Word.Length * areaPerLetter) / targetWidth));
            double         fontMultiplier = Math.Min((maxFontSize - MinFontSize) / range, 200);

            var points = new[]
            {
                new Point((int)(_layoutRoot.ActualWidth / 2), (int)(_layoutRoot.ActualHeight / 2)),
                new Point((int)(_layoutRoot.ActualWidth / 4), (int)(_layoutRoot.ActualHeight / 4)),
                new Point((int)(_layoutRoot.ActualWidth / 4), (int)(3 * _layoutRoot.ActualHeight / 2)),
                new Point((int)(3 * _layoutRoot.ActualWidth / 4), (int)(_layoutRoot.ActualHeight / 2)),
                new Point((int)(3 * _layoutRoot.ActualWidth / 4), (int)(3 * _layoutRoot.ActualHeight / 4))
            };


            int currentPoint = 0;

            foreach (WordCloudEntry e in Entries.OrderByDescending(e => e.SizeValue).Take(MaxWords))
            {
again:
                double position = 0.0;
                Point centre = points[currentPoint];

                double angle = 0.0;
                if (double.IsNaN(AngleCenterValue))
                {
                    angle = angleRange >= 0.01 ? -90 + (((e.Angle - minAngle) / angleRange) * 90) : 0;
                }
                else
                {
                    angle = angleRange >= 0.01 ? 90 * ((e.Angle - AngleCenterValue) / angleRange) : 0;
                }
                WriteableBitmap bm = CreateImage(e.Word,
                                                 ((e.SizeValue - minSize) * fontMultiplier) + MinFontSize,
                                                 SelectedItems.Contains(Entries.IndexOf(e)) ? -1 : (colorRange >= 0.01 ? (e.ColorValue - minColor) / colorRange : 1), e.Color,
                                                 angle);
                Dictionary <Point, List <Point> > lst = CreateCollisionList(bm);
                bool collided = true;
                do
                {
                    Point spiralPoint = GetSpiralPoint(position);
                    int   offsetX     = (bm.PixelWidth / 2);
                    int   offsetY     = (bm.PixelHeight / 2);
                    var   testPoint   = new Point((int)(spiralPoint.X + centre.X - offsetX), (int)(spiralPoint.Y + centre.Y - offsetY));
                    if (position > (2 * Math.PI) * 580)
                    {
                        if (++currentPoint >= points.Length)
                        {
                            goto done;
                        }
                        goto again;
                    }
                    int cols = CountCollisions(testPoint, lst);
                    if (cols == 0)
                    {
tryagain:
                        double oldY = testPoint.Y;
                        if (Math.Abs(testPoint.X + offsetX - centre.X) > 10)
                        {
                            if (testPoint.X + offsetX < centre.X)
                            {
                                do
                                {
                                    testPoint.X += 2;
                                } while (testPoint.X + offsetX < centre.X && CountCollisions(testPoint, lst) == 0);
                                testPoint.X -= 2;
                            }
                            else
                            {
                                do
                                {
                                    testPoint.X -= 2;
                                } while (testPoint.X + offsetX > centre.X && CountCollisions(testPoint, lst) == 0);
                                testPoint.X += 2;
                            }
                        }
                        if (Math.Abs(testPoint.Y + offsetY - centre.Y) > 10)
                        {
                            if (testPoint.Y + offsetY < centre.Y)
                            {
                                do
                                {
                                    testPoint.Y += 2;
                                } while (testPoint.Y + offsetY < centre.Y && CountCollisions(testPoint, lst) == 0);
                                testPoint.Y -= 2;
                            }
                            else
                            {
                                do
                                {
                                    testPoint.Y -= 2;
                                } while (testPoint.Y + offsetY > centre.Y && CountCollisions(testPoint, lst) == 0);
                                testPoint.Y += 2;
                            }
                            if (testPoint.Y != oldY)
                            {
                                goto tryagain;
                            }
                        }


                        collided = false;
                        CopyBits(testPoint, bm, lst, Entries.IndexOf(e));
                    }
                    else
                    {
                        if (cols <= 2)
                        {
                            position += (2 * Math.PI) / 100;
                        }
                        else
                        {
                            position += (2 * Math.PI) / 40;
                        }
                    }
                } while (collided);
            }
done:
            _image.Source = _source;
            _image.InvalidateArrange();
        }
Пример #2
0
        private WordDrawing CreateWordGeometryDrawing(WordCloudEntry word)
        {
            var wordDrawing = new WordDrawing(word, CurrentTheme, DpiScale);

            return(wordDrawing);
        }
Пример #3
0
 public LayoutItem(WordCloudEntry entry, PointD location, RectangleD measured)
 {
     Entry    = entry;
     Location = location;
     Measured = measured;
 }
Пример #4
0
        /*
        public class WordBitmap {
            public byte[] pixels;
            public int width;
            public int height;
            public int stride;

            private BitmapData bitmapData;
            private Bitmap bmps;

            public WordBitmap(Bitmap bmp) {
                //copy the pixels
                bitmapData = bmp.LockBits(
                    new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height),
                    ImageLockMode.ReadOnly,
                    PixelFormat.Format32bppArgb);
                int numbytes = Math.Abs(bitmapData.Stride) * bitmapData.Height;
                pixels = new byte[numbytes];

                // Copy the RGB values into the array.
                System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, pixels, 0, numbytes);
                stride = bitmapData.Stride;
                bmps = bmp;
                width = bmp.Width;
                height = bmp.Height;
            }

            public void Dispose() {
                bmps.UnlockBits(bitmapData);
                bitmapData = null;
                pixels = null;
            }
        } */
        public static void Main(string[] args)
        {
            string fnin = null;
            string fnout = null;
            string fontt = null;
            string svgfn = null;
            string pdffn = null;
            string cf = null;
            bool cd = false;

            for(int i=0;i<args.Length;i++) if(args[i][0] == '-') switch(args[i][1]) {
            case 'i':
                fnin = args[i+1];
                break;
            case 'o':
                fnout = args[i+1];
                break;
            case 'f':
                fontt = args[i+1];
                break;
            case 'c':
                cf = args[i+1];
                break;
            case 'd':
                cd = true;
                break;
            case 's':
                svgfn = args[i+1];
                break;
            case 'p':
                pdffn = args[i+1];
                break;
            default:
                Console.Error.WriteLine("Unknown switch: {0}!",args[i]);
                break;
            }

            if(cd) {
                if(cf == null) {
                    Console.Error.WriteLine("Error: No configfile specified!");
                    return;
                }
                StreamWriter sw = new StreamWriter(cf);
                WordCloud cloud1 = new WordCloud();
                XmlSerializer s = new XmlSerializer(typeof(WordCloud));
                s.Serialize(sw,cloud1);
                sw.Close();
                return;
            }

            if(fnin == null || (fnout == null && pdffn == null && svgfn == null)) {
                Console.Error.WriteLine("Error: no input or output file name given!");
                return;
            }

            WordCloud cloud;
            if(cf != null) {
                StreamReader s1 = new StreamReader(cf);
                XmlSerializer s = new XmlSerializer(typeof(WordCloud));
                cloud = (WordCloud)s.Deserialize(s1);
            }
            else cloud = new WordCloud();

            if(fontt != null) {
                cloud.fontname = fontt;
            }

            cloud.svgfn = svgfn;
            cloud.pdffn = pdffn;

            StreamReader sr = new StreamReader(fnin);

            Color c = new Color(0,0,0);
            int r,g,b;
            if(cloud.colorstring != null)
                if(cloud.colorstring.Length >= 7)
                    if(cloud.colorstring[0] == '#')
            if(int.TryParse(cloud.colorstring.Substring(1,2),System.Globalization.NumberStyles.AllowHexSpecifier,null,out r)
             && int.TryParse(cloud.colorstring.Substring(3,2),System.Globalization.NumberStyles.AllowHexSpecifier,null,out g)
             && int.TryParse(cloud.colorstring.Substring(5,2),System.Globalization.NumberStyles.AllowHexSpecifier,null,out b))
                            c = new Color( ((double)r) / 255.0, ((double)g) / 255.0, ((double)b) / 255.0 );

            cloud.Entries = new List<WordCloudEntry>();
            while(!sr.EndOfStream) {
                string line = sr.ReadLine();
                if(line == null) break;
                if(line.Length == 0) break;
                string[] e = line.Split(new char[]{':'});
                if(e.Length < 2) break;
                WordCloudEntry e2 = new WordCloudEntry();
                e2.Word = e[0];
                e2.SizeValue = Convert.ToDouble(e[1]);
                e2.ColorValue = 0.0;
                e2.Color = c;
                e2.Angle = 0.0;
                cloud.Entries.Add(e2);
            }
            sr.Close();
            cloud.InternalRegenerateCloud();
            if(fnout != null) cloud.Save(fnout);
        }