Sam's profileSamb Business Intelligen...PhotosBlogListsMore Tools Help

Blog


    April 24

    Injecting Bitmaps streams into Images in WPF from Web Service Calls

    Whew, that's a big title.  Ran into a great contact at the Atlantic City HLS DevCon, who asked me to post this code.

    chemvisual

    OK, so, that little image of the chemical structure on the bottom comes at me as a stream from a web service call to Chemspider.

    Here's the call, and the creation of the bitmap image...

    try
                {
                    com.chemspider.www.TradeSearch.Search search = new com.chemspider.www.TradeSearch.Search();
                    int[] ids = search.SimpleSearch2IdList(ChemSpiderSearchText.Text);
                    Random r = new Random();
                    double ri;
                    int r1;

                    if (ids != null && ids.Length > 0)
                    {
                        foreach (int id in ids)
                        {
                            Canvas search_result = new Canvas();

                            search_result.Width = 400;
                            search_result.Height = 500;

                            ri = r.NextDouble() * 30;
                            r1 = (int)ri;
                            r1 = r1 + 220;
                            search_result.Background = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255, (byte)r1, (byte)r1, (byte)r1));
                            search_result.Tag = "NR";
                            PinBoard.Children.Add(search_result);

                            object[] details = search.GetRecordDetails(id.ToString());

                            Label title = new Label();
                            title.Content = id.ToString();
                            search_result.Children.Add(title);

                            Label urllink = new Label();
                            Canvas.SetTop(urllink, 30);
                            urllink.Content = String.Format("http://www.chemspider.com/Chemical-Structure.{0}.html", id);
                            search_result.Children.Add(urllink);

                            TextBox CKIKey = new TextBox();
                            Canvas.SetTop(CKIKey, 50);
                            CKIKey.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
                            CKIKey.Width = 380;
                            CKIKey.Height = 90;
                            CKIKey.Text = details[1].ToString();
                            search_result.Children.Add(CKIKey);

                            TextBox CHI = new TextBox();
                            CHI.MaxLines = 5;
                            Canvas.SetTop(CHI, 100);
                            CHI.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
                            CHI.Width = 380;
                            CHI.Height = 90;
                            CHI.Text = details[2].ToString();
                            search_result.Children.Add(CHI);

                            TextBox smiles = new TextBox();
                            smiles.MaxLines = 5;
                            smiles.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
                            smiles.Width = 380;
                            smiles.Height = 90;
                            Canvas.SetTop(smiles, 200);
                            smiles.Text = details[3].ToString();
                            search_result.Children.Add(smiles);

                            // Get the image of the structure...
                            //com.chemspider.www.TradeSearch.GetRecordImageCompletedEventArgs img = new com.chemspider.www.TradeSearch.GetRecordImageCompletedEventArgs);
                            byte[] bigimg = search.GetRecordImage(id.ToString());
                            System.Windows.Controls.Image myImage = new System.Windows.Controls.Image();

                            BitmapImage bitImg = new BitmapImage();

                            bitImg.BeginInit();

                            MemoryStream ms = new MemoryStream(bigimg);

                            bitImg.StreamSource = ms;

                            bitImg.EndInit();

                            myImage.Source = bitImg;
                            bitImg = null;

                            myImage.Width = 150;
                            myImage.Height = 150;
                            Canvas.SetLeft(myImage, 10);
                            Canvas.SetTop(myImage, 300);
                            search_result.Children.Add(myImage);

                            // Position the result in an overall canvas by posx, posy (posx is incremented to give your results a staggered look)

                  // I animated mine, which is why I peeled that out here...

                   posx = posx + 45;

                        }
                    }
                    else
                    {
                        MessageBox.Show("No Results Found.");
                    }
                }
                catch
                {
                }

    April 23

    HLS DevCon in Atlantic City, NJ - Gene Expression Map Demo

    I'm just about to do my presentation on WPF and Visualization in Life Sciences and wanted to post this up to my blog.

    You can find my slides here (on SkyDrive).

    At the end of the presentation, I built a Gene Expression map using WPF.  Here are the steps to do it yourself, if you are so inclined.

    genex

    First, using Visual Studio 2008, start a new Windows program and create a new WPF Application.

    Here's the XAML...

    <Window x:Class="GeneExpression.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Gene Expression Map" Height="300" Width="300" WindowState="Maximized" >
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="35"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Slider x:Name="Zoom" Minimum="1" Maximum="200" Width="200" Value="1" Grid.Row="0" ValueChanged="slider_ValueChanged"/>
            <ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" Grid.Row="1">
            <Canvas x:Name="Backgrounder" Grid.Row="1" Width="1500" Height="1500" HorizontalAlignment="Left" VerticalAlignment= "Top"/>
            </ScrollViewer>
        </Grid>
    </Window>

     

    In the code-behind (XAML.cs)...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace GeneExpression
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                Draw_Map();
            }

            private void Sparkle(object sender, MouseEventArgs e)
            {
                double newposx, newposy;
                ((System.Windows.FrameworkElement)(sender)).Width = 12;
                ((System.Windows.FrameworkElement)(sender)).Height = 4;
                newposx = Canvas.GetLeft(((System.Windows.FrameworkElement)(sender))) - 1;
                newposy = Canvas.GetTop(((System.Windows.FrameworkElement)(sender))) - 1;
                Canvas.SetLeft(((System.Windows.FrameworkElement)(sender)),newposx);
                Canvas.SetTop(((System.Windows.FrameworkElement)(sender)),newposy);
            }

            private void NoSparkle(object sender, MouseEventArgs e)
            {
                double newposx, newposy;
                ((System.Windows.FrameworkElement)(sender)).Width = 10;
                ((System.Windows.FrameworkElement)(sender)).Height = 2;
                newposx = Canvas.GetLeft(((System.Windows.FrameworkElement)(sender))) + 1;
                newposy = Canvas.GetTop(((System.Windows.FrameworkElement)(sender))) + 1;
                Canvas.SetLeft(((System.Windows.FrameworkElement)(sender)),newposx);
                Canvas.SetTop(((System.Windows.FrameworkElement)(sender)),newposy);
            }

            private void slider_ValueChanged(object sender, RoutedEventArgs e)
            {
                try
                {
                    double ffactor;
                    ffactor = ((System.Windows.Controls.Primitives.RangeBase)(sender)).Value;
                    ScaleTransform myscale;
                    myscale = new ScaleTransform(ffactor, ffactor);
                    Backgrounder.RenderTransform = myscale;

                }
                catch (Exception)
                { }
            }
            private void Draw_Map()
            {
                double xx, yy;
                double markval;
                int markcolor;
                Random r1 = new Random();
                for (yy = 0; yy < 300; yy++)
                {
                    for (xx = 0; xx < 300; xx++)
                    {
                        Rectangle Gene = new Rectangle();
                        Gene.MouseEnter += new MouseEventHandler(Sparkle);
                        Gene.MouseLeave += new MouseEventHandler(NoSparkle);
                        Gene.Width = 10;
                        Gene.Height = 2;
                        Canvas.SetLeft(Gene, xx * 11);
                        Canvas.SetTop(Gene, yy * 3);
                        Backgrounder.Children.Add(Gene);
                        Gene.Fill = new SolidColorBrush(Colors.Black);
                        markval = r1.NextDouble() * 255;
                        markcolor = (int)markval;
                        Gene.ToolTip = markcolor.ToString();
                        if (markcolor < 125)
                        {
                            markcolor = markcolor * 2;
                            Gene.Fill = new SolidColorBrush(Color.FromArgb(255,(byte)markcolor,0,0));
                        }
                        else
                        {
                            Gene.Fill = new SolidColorBrush(Color.FromArgb(255, 0,(byte)markcolor, 0));
                        }
                    }
                }

            }
        }

    }

     

    I met a lot of great folks at DevCon(my first Health Care Devcon) - and I can't wait to see you this coming year.

    Thanks for coming!

    April 15

    Home Foreclosure Heat Map

    http://hotpads.com/pages/features/foreclosures.htm

    This is just plain scary!

    HotPads Foreclosure Heat Maps portray the markets hit hardest by the recent housing crisis and the increased foreclosure rates. These foreclosure heat maps visually illustrate the foreclosures per capita and display color-coded foreclosure rates by county and state.

     

    foreclosure heat map

    April 09

    Intelligence for the Masses...

    Sometimes, no matter how much time you spend on visualization, the raw data should speak for itself.

    correction

    Hawaii, the Highest Mountain on Earth?

    http://www.nsf.gov/news/special_reports/scivis/popup/hawaii.htm

    I thought this was an interesting visualization. Even though a cardinal rule of baselines is broken here, they manage to pull off using the curvature of the Earth as a baseline.

    Mount Everest is the highest mountain on Earth above sea level, but it’s not the world’s tallest mountain. That honor goes to the Hawaiian volcano Mauna Kea. When measured from its base on the Pacific Ocean floor, it is about 1,000 meters taller than Mount Everest. Mauna Kea is part of a 5,600-kilometer-long string of volcanoes stretching westward from the main Hawaiian island.

    steph_comp_04

    Credit: Nils Sparwasser, Thorsten Andresen, Stephan Reiniger; Robert Meisner, German Aerospace Center (DLR)

    April 04

    Rendering Live Web Pages in WPF

    I got a lot of help from my friend Michael Peters, of Oculus, so pay his blog a visit for me.

    In working on WPF, there are a number of reasons why someone might want to render a "live" web page on a canvas. By "live", I don't mean a dumb thumbnail - although that can have value too - I mean a fully navigable Web page that you can click and navigate.

    Here's how to do it. Download the WPFInterop codeplex entry. Create a Canvas (mine is called Pinboard) and add this code to create a dynamic button:

    Canvas backgrounder = new Canvas();

    backgrounder.Background = new SolidColorBrush(Colors.Blue);
    backgrounder.Width = 860;
    backgrounder.Height = 1110;

    Button pageresult = new Button();
    pageresult.Width = 850;
    pageresult.Height = 1100;
    Canvas.SetLeft(pageresult, 5);
    Canvas.SetTop(pageresult, 5);
    Uri wpURL = new Uri(sourceResult.Url);
    pageresult.Content = openwebFile(wpURL);
    pageresult.ToolTip = "Title: " + sourceResult.Title + "\nDescription: " + sourceResult.Description + "\nSummary: " + sourceResult.Summary + "\n\nURL: " + sourceResult.Url;

    PinBoard.Children.Add(backgrounder);

    Canvas.SetLeft(backgrounder, posx);
    Canvas.SetTop(backgrounder, posy);
    backgrounder.Children.Add(pageresult);

     

    The Function, openwebFile returns a grid with the web page addressable by the URL (wpURL).

    private Grid openwebFile(Uri url)

    {

    Grid myGrid = new Grid();

    System.Windows.Forms.WebBrowser sampleWB = new System.Windows.Forms.WebBrowser();

    sampleWB.Size = new System.Drawing.Size(850, 1100);

    sampleWB.Url = url;

    WPFInterop.InteropInfoMesa2.Win32HostRenderer sampleRender = new WPFInterop.InteropInfoMesa2.Win32HostRenderer();

    sampleRender.ContentControl = sampleWB;

    myGrid.Children.Add(sampleRender);

    return myGrid;

    }

    Here's the net effect of many web pages from a search coming back from Microsoft Live Web Service:

    webpages

    It doesn't work perfectly (yet), so keep an eye out for new releases.                 

    Ray Tracing Molecules using the IBM BlueGene SuperComputer

    http://arxiv.org/PS_cache/arxiv/pdf/0801/0801.1500v1.pdf

    Michael McGuigan of the Brookhaven National Laboratory is using a BlueGene Supercomputer to perform Ray Tracing in real time against exceptionally complex objects. Instead of lighting each polygon and calculating impinging light on its surface, Ray Tracing, on the other hand, scans an imaginary particle of light through each pixel, bouncing and refracting in the way real light performs. This enables images of amazing realism. Intel is also talking more and more about this.

    tacyon

    Image of the 1e79 Atp phosphorylase molecule rendered with ambient
    occlusion lighting on a Blue Gene/L with the parallel tachyon raytracer.