Solved

Dynamic Interactive Imagemap

Posted on 2008-10-04
14
1,561 Views
Last Modified: 2012-05-05
http://www.nottinghamrealty.com/nr_comm_ipm.php?community=21
This web site has an interactive map (mouse over red dot).  How can this be done in VB.NET/ASP.NET/AJAX?
0
Comment
Question by:azyet24
  • 9
  • 5
14 Comments
 
LVL 8

Expert Comment

by:rlh68
ID: 22654325

Aside from Flash or Silverlight, and the way this site implemented it was using HTML and Javascript.

You start with a background image, in this case it's the lot map. You use this image as the base image map.
In your .aspx page, using the HTML element <map> and its sub element <area> you define <area> elements with event handlers (mouseover, click, etc.) for the areas of the map you want the users to interact with.

Additionally, this site added 'dots' to the parts of the Image Map that areas have been defined for. To do this you need to use the GDI+ objects in .Net to draw on the base image.

Image Maps:
http://www.w3schools.com/TAGS/tag_map.asp
http://www.elated.com/articles/creating-image-maps/

GDI+:
http://www.codeproject.com/KB/webforms/gdiGraph.aspx
http://www.code-magazine.com/article.aspx?quickid=03050801

Instead of using GDI+ to draw on the background, you may be able to use Javascript to position image elements on top of the image map, not completely sure about how this would effect the image map events though.


btw, that page is a pretty-nifty example of an HTML image map.

0
 

Author Comment

by:azyet24
ID: 22654410
thank  you for the comment.  I have used standard html to do this for a lont time, but not sure how to allow someone upload a lot map and specify the rollovers without a manual process.  I was hoping that there would be a way to do this programatically.  Guess not.
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22654466

Create the image map dynamically via .net code. Depending on the area's you want, define area elements in your output HTML response. Have you have ever created dynamic HTML output with asp.net?

So, say you have an array in your server side code that defines all the land lots and their positions on the image map. when you build the page you reference the array to dynamically build your area elements.

This is definitely possible in .net
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22654490

Also, this site is only using one image map for all developers.
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22674453
Because sometimes code makes more sense.

Here is some code to dynamically create an image map (using the map image from the site you posted). It doesn't put the dots YET, but its tool-tip will tell you the lot number you are hovering (only for lots 1 through 5, i didn't code them all). If we are still discussing the same thing, I will post code that puts dots at the map area positions via JavaScript.

The code consists of 3 parts:
1. HtmlImageMap Object
2. HtmlImageMapArea Object
3. Code to be placed in .aspx code behind's load event. This loads the image map into the page.

Also, I used the empty image map (no dots) from the site found at this url:
http://www.nottinghamrealty.com/nr_comm_ipm.php?org_id=2&map_id=346&community=21&plat_id=1&bld_id=721&stat_id=&button=Go

Once working, this will create an html image map on the page with areas defined for Lots 1-5. Hovering lots 1-5 will show their lot number.

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' HTML IMAGE MAP

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Public Class HtmlImageMap

    Inherits System.Web.UI.Control
 

    Private _name As String = String.Empty

    Private _areas As ArrayList

    Private _imageMapUrl As String = String.Empty
 
 

    Public Sub New(ByVal name As String, ByVal imagePath As String)

        _areas = New ArrayList

        _name = name

        _imageMapUrl = imagePath

    End Sub
 

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        Dim htmlMap As New HtmlGenericControl("map")

        Dim img As New HtmlImage
 

        img.Src = _imageMapUrl

        img.Attributes.Add("usemap", "#" & _name)

        img.RenderControl(writer)
 

        htmlMap.Attributes.Add("name", _name)

        For Each area As HtmlImageMapArea In _areas

            htmlMap.Controls.Add(area)

        Next

        htmlMap.RenderControl(writer)
 

    End Sub
 

    Public Property Name() As String

        Get

            Return _name

        End Get

        Set(ByVal Value As String)

            _name = Value.Trim

        End Set

    End Property
 

    Public Property ImageMapUrl() As String

        Get

            Return _imageMapUrl

        End Get

        Set(ByVal Value As String)

            _imageMapUrl = Value.Trim

        End Set

    End Property
 

    Public Property Areas() As ArrayList

        Get

            Return _areas

        End Get

        Set(ByVal Value As ArrayList)

            _areas = Value

        End Set

    End Property
 

End Class
 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' HTML IMAGE MAP AREA

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Public Class HtmlImageMapArea

    Inherits System.Web.UI.Control
 

    Public Enum ShapeType

        Rect

        Circle

        Polygon

    End Enum
 

    Private _href As String = String.Empty

    Private _shape As ShapeType = ShapeType.Rect

    Private _coords As New ArrayList

    Private _title As String = String.Empty
 

    Public Sub New()

    End Sub
 

    Public Sub New(ByVal shape As ShapeType, ByVal coords As ArrayList, ByVal href As String)

        _shape = shape

        _href = href.Trim

        _coords = coords

    End Sub
 

    Public Sub New(ByVal shape As ShapeType, ByVal coords As String, ByVal href As String)

        _shape = shape

        _href = href.Trim

        Dim arrCoords() As String = coords.Trim.Split(",")

        For Each coord As String In arrCoords

            _coords.Add(coord)

        Next

    End Sub
 

    Public Sub New(ByVal shape As ShapeType, ByVal coords As String, ByVal href As String, ByVal title As String)

        _shape = shape

        _href = href.Trim

        Dim arrCoords() As String = coords.Trim.Split(",")

        For Each coord As String In arrCoords

            _coords.Add(coord)

        Next

        _title = title

    End Sub
 

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        Dim area As New HtmlGenericControl("area")
 

        If _coords.Count > 0 Then

            area.Attributes.Add("shape", _shape.ToString.ToLower)

            Dim coords As String = String.Empty

            For Each coord As Int16 In _coords

                coords &= coord & ","

            Next

            area.Attributes.Add("coords", coords.TrimEnd(","))

            area.Attributes.Add("href", _href)

            area.Attributes.Add("title", _title)

            area.RenderControl(writer)

        End If
 

    End Sub
 

    Public Property Href() As String

        Get

            Return _href

        End Get

        Set(ByVal Value As String)

            _href = Value.Trim

        End Set

    End Property
 

    Public Property Shape() As ShapeType

        Get

            Return _shape

        End Get

        Set(ByVal Value As ShapeType)

            _shape = Value

        End Set

    End Property
 

    Public Property Coords() As ArrayList

        Get

            Return _coords

        End Get

        Set(ByVal Value As ArrayList)

            _coords = Value

        End Set

    End Property
 

    Public Property Title() As String

        Get

            Return _title

        End Get

        Set(ByVal Value As String)

            _title = Value.Trim

        End Set

    End Property

End Class
 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' CODE TO BE PLACED IN LOAD EVENT OF THE PAGE YOU WANT TO ADD THE IMAGE MAP TO

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

     ' point to the location you saved the image to

      Dim image As String = ResolveUrl("~/images/viewmap2.php.png")

      Dim im As New HtmlImageMap("TestMap", image)

      im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "51,67,68,94", "#", "Lot 5"))

      im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "70,68,86,92", "#", "Lot 4"))

      Me.Controls.Add(im)

Open in new window

0
 

Author Comment

by:azyet24
ID: 22674545
ok so you are defining the area in your code-behind.  Did you pull the image into dreamweaver or some program to draw the lots and then use the coordinates, or is there a better way?

But yes, this is what I'm looking for...however, when a new site is designed, there is still a manual process to grid these images..right?
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22674713

Yes, I opened the image in MS Paint and got the coords using a manual process that involved positioning the cursor over each point to get the rect coords. I then typed the coords into my code behind.

Using the above basic example, Yes you would need to recode (at the very least copy and past) the coords for every site. To really be reusable the objects should be modified to load the image map and coords from a datasource, like a database or xml file. Then once created (as long as it didn't change), the map would never need to be recreated, you could then use the maps over and over on any .Net page or site you wanted without recoding the coords. And placing one in a page could be done with a single line of code.

Me.Controls.Add(New HtmlImageMap("images/maps/summer_wood_estates.xml"))


I know of no such software that can create image maps from 'visually' reviewing an image and building a list of coords. Though there could be some software that assists in creating coord maps, taking away some of the work.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:azyet24
ID: 22674848
Understood.  I'll take you up on your offer to demo putting dots on the map and if you don't mind, could you show how I could pull data into the popup (popup that would appear on the mouse over that then gives details about that lot)?
0
 
LVL 8

Accepted Solution

by:
rlh68 earned 500 total points
ID: 22676085
Ok, here is the proof-of-concept demo that places dots at each image map area location. The dots have a mouseover event that show the lot detail when the dot is hovered. The detail popup is low-tech, just an alert box showing the lot data.

You need to use the image map objects with this post and not the ones from the previous post, the objects have changed slightly.

The code consists of 6 parts:
1. HtmlImageMap Object
2. HtmlImageMapArea Object
3. Code to be placed in .aspx code behind's load event. This loads the image map into the page.
4. Javascript code placed in the HTML <head> element of your .aspx page. Used to create and position the dot images.
5. jQuery Javascript library. jQuery simplifies a ton of the JavaScript work. You will need this to make this code work.
You can download jQuery here, http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.2.6.js (If you are not familiar with jQuery you will be, it will be included by Microsoft in future .Net versions).

Also, I used the red dot image that is attached as a file to this post, along with the lot map from the previous post.

This version proves that this can be done using HTML, Javascript, and .Net. However, this example also needs more work to be really useful, some limitations:
 - The controls names referenced in Javascript should be written dynamically by .Net.
 - Only supports one image map per page.
 - Javascript code will currently only work with map area shapes of type rect.
 - and more I am sure.


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' HTML IMAGE MAP

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Public Class HtmlImageMap

    Inherits System.Web.UI.Control
 

    Private _name As String = String.Empty

    Private _areas As ArrayList

    Private _imageMapUrl As String = String.Empty

    Private _left As Int32 = 0

    Private _top As Int32 = 0
 

    Public Sub New(ByVal name As String, ByVal imagePath As String)

        _areas = New ArrayList

        _name = name

        _imageMapUrl = imagePath

    End Sub
 

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        Dim htmlMap As New HtmlGenericControl("map")

        Dim img As New HtmlImage

        Dim container As New HtmlGenericControl("div")
 

        container.Attributes.Add("id", _name & "_container")

        container.Style.Add("position", "relative")

        container.Style.Add("left", _left)

        container.Style.Add("top", _top)
 

        img.Src = _imageMapUrl

        img.Attributes.Add("id", _name)

        img.Attributes.Add("name", _name)

        img.Attributes.Add("usemap", _name & "_map")
 

        htmlMap.Attributes.Add("id", _name & "_map")

        htmlMap.Attributes.Add("name", _name & "_map")

        For Each area As HtmlImageMapArea In _areas

            htmlMap.Controls.Add(area)

        Next
 

        container.Controls.Add(img)

        container.Controls.Add(htmlMap)

        container.RenderControl(writer)
 

    End Sub
 

    Public Property Name() As String

        Get

            Return _name

        End Get

        Set(ByVal Value As String)

            _name = Value.Trim

        End Set

    End Property
 

    Public Property ImageMapUrl() As String

        Get

            Return _imageMapUrl

        End Get

        Set(ByVal Value As String)

            _imageMapUrl = Value.Trim

        End Set

    End Property
 

    Public Property Areas() As ArrayList

        Get

            Return _areas

        End Get

        Set(ByVal Value As ArrayList)

            _areas = Value

        End Set

    End Property
 

    Public Property Left() As Integer

        Get

            Return _left

        End Get

        Set(ByVal Value As Integer)

            _left = Value

        End Set

    End Property
 

    Public Property Top() As Integer

        Get

            Return _top

        End Get

        Set(ByVal Value As Integer)

            _top = Value

        End Set

    End Property
 

End Class
 
 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' HTML IMAGE MAP AREA

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Public Class HtmlImageMapArea

    Inherits System.Web.UI.Control
 

    Public Enum ShapeType

        Rect

        Circle

        Polygon

    End Enum
 

    Private _href As String = String.Empty

    Private _shape As ShapeType = ShapeType.Rect

    Private _coords As New ArrayList

    Private _params As String = String.Empty
 

    Public Sub New()

    End Sub
 

    Public Sub New(ByVal shape As ShapeType, ByVal coords As ArrayList, ByVal href As String)

        _shape = shape

        _href = href.Trim

        _coords = coords

    End Sub
 

    Public Sub New(ByVal shape As ShapeType, ByVal coords As String, ByVal href As String)

        _shape = shape

        _href = href.Trim

        Dim arrCoords() As String = coords.Trim.Split(",")

        For Each coord As String In arrCoords

            _coords.Add(coord)

        Next

    End Sub
 

    Public Sub New(ByVal shape As ShapeType, ByVal coords As String, ByVal href As String, ByVal params As String)

        _shape = shape

        _href = href.Trim

        Dim arrCoords() As String = coords.Trim.Split(",")

        For Each coord As String In arrCoords

            _coords.Add(coord)

        Next

        _params = params

    End Sub
 

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        Dim area As New HtmlGenericControl("area")
 

        If _coords.Count > 0 Then

            area.Attributes.Add("shape", _shape.ToString.ToLower)

            Dim coords As String = String.Empty

            For Each coord As Int16 In _coords

                coords &= coord & ","

            Next

            area.Attributes.Add("coords", coords.TrimEnd(","))

            area.Attributes.Add("href", _href)

            area.Attributes.Add("params", _params)

            area.RenderControl(writer)

        End If
 

    End Sub
 

    Public Property Href() As String

        Get

            Return _href

        End Get

        Set(ByVal Value As String)

            _href = Value.Trim

        End Set

    End Property
 

    Public Property Shape() As ShapeType

        Get

            Return _shape

        End Get

        Set(ByVal Value As ShapeType)

            _shape = Value

        End Set

    End Property
 

    Public Property Coords() As ArrayList

        Get

            Return _coords

        End Get

        Set(ByVal Value As ArrayList)

            _coords = Value

        End Set

    End Property
 

    Public Property JavascriptParameters() As String

        Get

            Return _params

        End Get

        Set(ByVal Value As String)

            _params = Value.Trim

        End Set

    End Property
 

End Class
 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' CODE TO BE PLACED IN LOAD EVENT OF THE PAGE YOU WANT TO ADD THE IMAGE MAP TO

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

        Dim image As String = ResolveUrl("~/images/maps/viewmap2.php.png")

        Dim im As New HtmlImageMap("SummerWoodEstates", image)

        im.Left = 300

        im.Top = 50
 

        ' define Lot #3

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "89,70,105,93", "#", "Lot #: 3|Builder: Fred Riley Homes|Price: $3.000.000"))

        ' define Lot #4

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "70,70,85,95", "#", "Lot #: 4|Builder: R&S Builders|Price: $4.000.000"))

        ' define Lot #5

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "50,70,65,97", "#", "Lot #: 5|Builder: Fred Riley Homes|Price: $5.000.000"))

        ' define Lot #59

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "160,320,177,344", "#", "Lot #: 59|Builder: Universal Build, Inc.|Price: $59.000.000"))

        ' define Lot #83

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "100,513,120,531", "#", "Lot #: 83|Builder: Fred Riley Homes|Price: $83.000.000"))

        ' define Lot #84

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "177,482,200,499", "#", "Lot #: 84|Builder: Universal Build, Inc.|Price: $84.000.000"))

        ' define Lot #117

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "469,382,496,401", "#", "Lot #: 117|Builder: Fred Riley Homes|Price: $117.000.000"))

        ' define Lot #149

        im.Areas.Add(New HtmlImageMapArea(HtmlImageMapArea.ShapeType.Rect, "442,193,459,213", "#", "Lot #: 149|Builder: R&S Builders|Price: $149.000.000"))

     

        Me.FindControl("Form1").Controls.Add(im)
 
 

<!-- CODE TO BE PLACE IN HTML HEAD AREA -->

		<script type="text/javascript" lang="javascript" src="scripts/jquery-1.2.6.js"></script>

		

		<script type="text/javascript" lang="javascript">

		

		// called when a lot is hovered with cursor

		function ShowLotDetail(el,strParams){

			// code to split params to show pop-up

			// basic example

			window.alert(strParams.split("|")[0]+'\n'+strParams.split("|")[1]+'\n'+strParams.split("|")[2]);	

		}

		

		$(document).ready(function() {

			// do stuff when DOM is ready			

			

			// creates a new image element at each area coord			

			$('#SummerWoodEstates_map area').each(function(i) {

				var coords = $(this).attr("coords");

				var params = $(this).attr("params");																		

				var dotTop = parseInt(coords.split(',')[1])+3;

				var dotLeft = parseInt(coords.split(',')[0])+3;

				var onhover = "javascript:ShowLotDetail(this,'"+params+"');";

				

				// create and add image dot with param data to the image element container

				$('#SummerWoodEstates_container').append('<img src="./images/dot_red.gif" style="position:absolute;left:'+dotLeft+'px;top:'+dotTop+'px;" onmouseover="'+onhover+'" />');

							

			});			

			

		 });		

		</script>

Open in new window

dot-red.gif
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22676090
Oops, a correction, "The code consists of 6 parts:" should read "The code consists of 5 parts:"
0
 

Author Comment

by:azyet24
ID: 22684178
I'm getting an error at line 26, 27

            container.Style.Add("left", _left)
            container.Style.Add("top", _top)

Error:
Compiler Error Message: BC30519: Overload resolution failed because no accessible 'Add' can be called without a narrowing conversion:
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22687059
Try replacing those two lines with these,

     container.Style.Add("left", _left.ToString)
        container.Style.Add("top", _top.ToString)

or these...

        container.Style.Add("left", CType(_left, String))
        container.Style.Add("top", CType(_top, String))
0
 

Author Comment

by:azyet24
ID: 22692066
    container.Style.Add("left", _left.ToString)
        container.Style.Add("top", _top.ToString)

Worked. You have satisfied my request for this EE question...could you perhaps point me in the direction that I need to actually fill an AJAX popup with data for the lots (from database)?
0
 
LVL 8

Expert Comment

by:rlh68
ID: 22693087

"could you perhaps point me in the direction that I need to actually fill an AJAX popup with data for the lots (from database)?"

That's a tough question.

You need SQL and knowledge of .Net data objects to get the data from the database.
You need Javascript (AJAX) to retrieve the data from the server without reloading the page.
You need HTML, CSS, and Javascript to create, display, populate, and hide the popup.

This sample is for an RSS reader but the basic idea is the same, and it uses jQuery.
http://encosia.com/2008/06/26/use-jquery-and-aspnet-ajax-to-build-a-client-side-repeater/

Fill popup from AJAX (more complicated because it uses raw Javascript)
http://www.devarticles.com/c/a/JavaScript/Displaying-Dynamic-Content-with-Pop-Up-DIVs-with-the-DOM-and-AJAX/2/


 
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
DataGridview Currency Formating? 22 38
Binding a check box in an Asp.net DataGrid 4 26
Showdialog 8 20
Copy/Clone an object. 9 15
Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
User art_snob (http://www.experts-exchange.com/M_6114203.html) encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now