public void DrawProfilesModule() { // Get subject node id Int64 qsNodeId; if (Int64.TryParse(HttpContext.Current.Request.QueryString["subject"].ToString(), out qsNodeId) == false) { throw new InvalidOperationException(String.Format("Expected Int64 NodeId, '{0}' was returned.", HttpContext.Current.Request.QueryString["subject"].ToString())); } // Get stored proc based on timeline type string timelineType = base.GetModuleParamString("TimelineType"); string proc = null; switch (timelineType) { case "CoAuthor": proc = "[Profile.Module].[NetworkTimeline.Person.CoAuthorOf.GetData]"; break; case "Concept": proc = "[Profile.Module].[NetworkTimeline.Person.HasResearchArea.GetData]"; break; default: throw new InvalidOperationException("Please select ChartType."); } // Get data Profiles.Profile.Utilities.DataIO dataIO = new Profiles.Profile.Utilities.DataIO(); DataView dataView = dataIO.GetNetworkTimeline(new RDFTriple(qsNodeId), proc); // Draw timeline chart if (dataView.Count > 0) { int x = 0, y = 0, i, a, b, j, c, d, n, w, k = 0; bool drawAvg; string label = null; if (int.TryParse(dataView[0]["a"].ToString(), out a) == false) { throw new InvalidOperationException("Value 'a' is not a number"); } if (int.TryParse(dataView[0]["b"].ToString(), out b) == false) { throw new InvalidOperationException("Value 'b' is not a number"); } if (int.TryParse(dataView[0]["n"].ToString(), out n) == false) { throw new InvalidOperationException("Value 'n' is not a number"); } j = b - a; c = Convert.ToInt32(j / 2 + 0.5); d = Convert.ToInt32(j / 15) + 1; w = 400; SolidBrush brushWhite = new SolidBrush(Color.White); SolidBrush brushAvg = new SolidBrush(Color.FromArgb(204, 0, 30)); SolidBrush brushPub = new SolidBrush(Color.Blue); Pen penTimeline = new Pen(Color.FromArgb(170, 170, 204), 2); Pen penTimelineThin = new Pen(Color.FromArgb(230, 230, 230), 1); Pen penYears = new Pen(Color.FromArgb(102, 102, 102), 1); Pen penGraphBox = new Pen(Color.FromArgb(102, 102, 102), 1); Bitmap bitmap = new Bitmap(w + 30, n * 20 + 40); Graphics graphic = Graphics.FromImage(bitmap); graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; // Draw background white graphic.FillRectangle(brushWhite, 0, 0, w + 30, n * 20 + 40); // Draw year key at top graphic.DrawLine(penYears, new Point(15, 20), new Point(15 + w, 20)); for (i = 0; i <= j; i++) { x = 15 + Convert.ToInt32((w * i / j)); graphic.DrawLine(penYears, new Point(x, 15), new Point(x, 20)); if ((j - i) % d == 0) { graphic.DrawString( (a + i).ToString(), new Font("Arial", 7), new SolidBrush(Color.Black), new Point(x - 10, 0) ); } } // Draw timelines for (i = 0; i <= dataView.Count - 1; i++) { if (label != dataView[i]["label"].ToString()) { k++; } x = Convert.ToInt32(Convert.ToSingle(dataView[i]["x"]) * w + 0.5) + 15; y = k * 20 + 20; if (label != dataView[i]["label"].ToString()) { label = dataView[i]["label"].ToString(); //oGraphic.DrawString(sLabel, New Font("Arial", 7), New SolidBrush(Color.Black), New Point(10, y)) graphic.DrawLine(penTimelineThin, new PointF(15, y), new PointF(15 + w, y)); graphic.DrawLine(penTimeline, new PointF(15 + (Convert.ToSingle(dataView[i]["MinX"])) * w, y), new PointF(15 + (Convert.ToSingle(dataView[i]["MaxX"])) * w, y)); } graphic.FillRectangle(brushPub, x - 1, y - 3, 3, 6); drawAvg = false; if (i == dataView.Count - 1) { drawAvg = true; } else if (label != dataView[i + 1]["label"].ToString()) { drawAvg = true; } if (drawAvg) { x = Convert.ToInt32(Convert.ToSingle(dataView[i]["AvgX"]) * w + 0.5) + 15; graphic.FillEllipse(brushAvg, new Rectangle(x - 5, y - 5, 10, 10)); } } graphic.DrawLine(penGraphBox, new Point(15, 20), new Point(15, 30 + 20 * n)); // Write out image byte[] imageArray; using (System.IO.MemoryStream imageStream = new System.IO.MemoryStream()) { bitmap.Save(imageStream, ImageFormat.Png); imageArray = new byte[imageStream.Length]; imageStream.Seek(0, System.IO.SeekOrigin.Begin); imageStream.Read(imageArray, 0, Convert.ToInt32(imageStream.Length)); } timelineImage.Src = "data:image/png;base64," + Convert.ToBase64String(imageArray); // Write out timeline detail list StringBuilder sb = new StringBuilder(); label = string.Empty; for (i = 0; i <= dataView.Count - 1; i++) { if (label != dataView[i]["label"].ToString()) { sb.AppendFormat("<a href=\"{0}\">{1}</a><br/>", dataView[i]["ObjectURI"].ToString(), dataView[i]["label"].ToString()); label = dataView[i]["label"].ToString(); } } timelineDetails.InnerHtml = sb.ToString(); string altText = ""; StringBuilder tableText = new StringBuilder(); tableText.AppendLine("<div class=\"listTable\" style=\"margin-top: 12px, margin-bottom:8px \"><table>"); tableText.AppendLine("<tr><th>Name</th><th>Number of Publications</th><th>First Publication Year</th><th>Most Recent Publication Year</th><th>Average Publication Date</th></tr>"); switch (timelineType) { case "CoAuthor": for (i = 0; i < dataView.Count; i++) { bool run = false; if (i == dataView.Count - 1) { run = true; } else if (dataView[i]["label"].ToString() != dataView[i + 1]["label"].ToString()) { run = true; } if (run) { string l = dataView[i]["label"].ToString(); double AvgX = Double.Parse(dataView[i]["AvgX"].ToString()); double Avg = (double)a + (double)j * AvgX; int AvgYear = (int)Avg; int AvgMonth = (int)((Avg - (double)AvgYear) * (double)12); string month = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(AvgMonth + 1); altText = altText + l + ", " + dataView[i]["PublicationCount"].ToString() + " publications between " + dataView[i]["FirstPublicationYear"].ToString() + " and " + dataView[i]["LastPublicationYear"].ToString() + ", average publication date " + month + " " + AvgYear + ". "; tableText.AppendLine("<tr><td style=\"text-align:left\"><a href=\"" + dataView[i]["ObjectURI"].ToString() + "\">" + l + "</a></td><td>" + dataView[i]["PublicationCount"].ToString() + "</td><td>" + dataView[i]["FirstPublicationYear"].ToString() + "</td><td>" + dataView[i]["LastPublicationYear"].ToString() + "</td><td style=\"text-align:left\">" + month + " " + AvgYear + "</td></tr>"); } } break; case "Concept": for (i = 0; i < dataView.Count; i++) { bool run = false; if (i == dataView.Count - 1) { run = true; } else if (dataView[i]["label"].ToString() != dataView[i + 1]["label"].ToString()) { run = true; } if (run) { string l = dataView[i]["label"].ToString(); double AvgX = Double.Parse(dataView[i]["AvgX"].ToString()); double Avg = (double)a + (double)j * AvgX; int AvgYear = (int)Avg; int AvgMonth = (int)((Avg - (double)AvgYear) * (double)12); string month = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(AvgMonth + 1); altText = altText + l + ", " + dataView[i]["NumPubsThis"].ToString() + " publications between " + dataView[i]["FirstPublicationYear"].ToString() + " and " + dataView[i]["LastPublicationYear"].ToString() + ", average publication date " + month + " " + AvgYear + ". "; tableText.AppendLine("<tr><td style=\"text-align:left\"><a href=\"" + dataView[i]["ObjectURI"].ToString() + "\">" + l + "</a></td><td>" + dataView[i]["NumPubsThis"].ToString() + "</td><td>" + dataView[i]["FirstPublicationYear"].ToString() + "</td><td>" + dataView[i]["LastPublicationYear"].ToString() + "</td><td style=\"text-align:left\">" + month + " " + AvgYear + "</td></tr>"); } } break; } tableText.AppendLine("</table></div>"); timelineImage.Alt = altText; litNetworkText.Text = tableText.ToString(); } if (dataView.Count == 0) { timelineImage.Visible = false; } }