diff --git a/GoogleChartsNGraphsControls/BaseDesignTimeSupport.cs b/GoogleChartsNGraphsControls/BaseDesignTimeSupport.cs index 427620b..b3b2bd5 100644 --- a/GoogleChartsNGraphsControls/BaseDesignTimeSupport.cs +++ b/GoogleChartsNGraphsControls/BaseDesignTimeSupport.cs @@ -536,6 +536,101 @@ public Interval() { } } + [Serializable()] + public class CHAPTimelineOptions + { + public enum ZOOMINTERVALS { MINUTE, HOUR, DAY, WEEK, MONTH, QUARTERLY, TRIMESTER, SIXMONTHS, YEAR } + public enum TIMELINENODESTYLE { BOX, DOT, }; + + private double getMilliseconds(ZOOMINTERVALS zi) + { + switch(zi) + { + case ZOOMINTERVALS.DAY: + return 1000 * 60 * 60 * 24; + case ZOOMINTERVALS.HOUR: + return 1000 * 60 * 60; + case ZOOMINTERVALS.MINUTE: + return 1000 * 60; + case ZOOMINTERVALS.MONTH: + return (1000 * 60 * 60 * 24) * 31d; + case ZOOMINTERVALS.QUARTERLY: + return (1000 * 60 * 60 * 24) * 31d * 3; + case ZOOMINTERVALS.SIXMONTHS: + return (1000 * 60 * 60 * 24) * 31d * 6; + case ZOOMINTERVALS.TRIMESTER: + return (1000 * 60 * 60 * 24) * 31d * 4; + case ZOOMINTERVALS.WEEK: + return 1000 * 60 * 60 * 24 * 7; + case ZOOMINTERVALS.YEAR: + return (1000 * 60 * 60 * 24) * 31d * 12; + default: + return (1000 * 60 * 60 * 24) * 31d; + } + } + + public CHAPTimelineOptions() { } + + [DataMember(Name = "width")] + public string Width { get; set; } + + [DataMember(Name = "height")] + public string Height { get; set; } + + [DataMember(Name = "min")] + public DateTime? MinDateRange { get; set; } + + [DataMember(Name = "max")] + public DateTime? MaxDateRange { get; set; } + + [DataMember(Name = "zoomMin")] + public ZOOMINTERVALS? ZoomMin { get; set; } + + [DataMember(Name = "zoomMax")] + public ZOOMINTERVALS? ZoomMax { get; set; } + + [DataMember(Name = "editable")] + public bool? Editable { get; set; } + + [DataMember(Name = "animate")] + public bool? AnimateTransitions { get; set; } + + [DataMember(Name = "eventMargin")] + public int? Margin { get; set; } + + [DataMember(Name = "showButtonNew")] + public bool? CreateNewButton { get; set; } + + [DataMember(Name = "showNavigation")] + public bool? ShowNavigation { get; set; } + + // minimal margin beteen events and the axis + [DataMember(Name = "eventMarginAxis")] + public int? AxisMargin { get; set; } + + // in combination with grouping + [DataMember(Name = "showMajorLabels")] + public bool? MajorLabels { get; set; } + + [DataMember(Name = "axisOnTop")] + public bool? AxisOnTop { get; set; } + + [DataMember(Name = "groupsChangeable ")] + public bool? GroupsChangeable { get; set; } + + [DataMember(Name = "groupsOnRight")] + public bool? GroupsOnRight { get; set; } + + [DataMember(Name = "stackEvents")] + public bool? StackEvents { get; set; } + + [DataMember(Name = "cluster")] + public bool? ClusterEvents { get; set; } + + + } + + //[Serializable()] //[DataContract(Name = "interval")] //public class Interval @@ -559,16 +654,78 @@ public Interval() { } // public float? Opacity { get; set; } // 0 - 1 //} - + public class ComboChartLineSeries { + public enum LINETYPE { DASHED, LONG_DASH, SHORT_DASH, DOTTED, LONG_DOTTED, SHORT_DOTTED}; + public enum FUNCTION_TYPE { FIXED, AVG, COUNT, SUM, MAX, MIN, STD_DEV, VARIANCE, MEDIAN }; + private List Options = new List(); + + private string getDashDotted(LINETYPE? LT) + { + switch(LT) + { + case LINETYPE.DASHED: + return "[14, 2, 7, 2]"; + case LINETYPE.DOTTED: + return "[4, 4]"; + case LINETYPE.LONG_DASH: + return "[2, 2, 20, 2, 20, 2]"; + case LINETYPE.LONG_DOTTED: + return "[10,2]"; + case LINETYPE.SHORT_DASH: + return "[5, 1, 3]"; + case LINETYPE.SHORT_DOTTED: + return "[4,1]"; + default: + return "[14, 2, 7, 2]"; + } + } + + public ComboChartLineSeries() + { + this.LineType = SeriesType.Line; + } + public int Column { get; set; } + public FUNCTION_TYPE FunctType { get; set; } public SeriesType LineType { get; set; } - public Color? Color { get; set; } + public LINETYPE? DashedLine { get; set; } + public int? LineWidth { get; set; } + public string LineName { get; set; } + public decimal FixedValue { get; set; } + public Color? LineColor { get; set; } + + public void AddOption(string key, string value) + { + this.Options.Add(string.Format("{0}:'{1}'", key, value)); + } + public void AddOption(string key, double value) + { + this.Options.Add(string.Format("{0}:{1}", key, value)); + } + public void ClearOptions() + { + this.Options.Clear(); + } public override string ToString() { - return string.Format("{0}: {{ type:'{1}', color:'gray', lineWidth:'2', lineDashStyle:[5,1,3] }}", Column, LineType.ToString().ToLower()); + List options = new List(); + if (this.LineColor != null) + options.Add(string.Format("color:'{0}'", this.LineColor.HexConverter())); + if (this.LineWidth != null) + options.Add(string.Format("lineWidth:{0}", this.LineWidth.ToString())); + if (this.DashedLine != null) + options.Add(string.Format("lineDashStyle:{0}", getDashDotted(this.DashedLine))); + if (this.Options.Count() > 0) + options.AddRange(Options); + + + if (options.Count() > 0) + return string.Format("{0}: {{ type:'{1}', {2} }}", Column, LineType.ToString().ToLower(), string.Join(", ", options)); + else + return string.Format("{0}: {{ type:'{1}' }}", Column, LineType.ToString().ToLower()); } } [Serializable()] diff --git a/GoogleChartsNGraphsControls/BaseEvents.cs b/GoogleChartsNGraphsControls/BaseEvents.cs index 8f57b7d..50e1199 100644 --- a/GoogleChartsNGraphsControls/BaseEvents.cs +++ b/GoogleChartsNGraphsControls/BaseEvents.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading.Tasks; namespace GoogleChartsNGraphsControls { diff --git a/GoogleChartsNGraphsControls/BaseGVI.cs b/GoogleChartsNGraphsControls/BaseGVI.cs index 1622543..7d5983f 100644 --- a/GoogleChartsNGraphsControls/BaseGVI.cs +++ b/GoogleChartsNGraphsControls/BaseGVI.cs @@ -23,9 +23,10 @@ public enum GOOGLECHART COLUMNCHART, GAUGE, LINECHART, MAP, MOTIONCHART, ORGANIZATIONCHART, PIECHART, WORDCLOUD, SCATTERCHART, TABLEARROW, TABLEBAR, - CANDLESTICK, COMBO, HISTOGRAM, DONUT, TREEMAP, TIMELINE, - WORDTREE, - CALENDAR, ANNOTATION, SANKEY + CANDLESTICK, COMBO, HISTOGRAM, DONUT, TREEMAP, + TIMELINE, WORDTREE, CALENDAR, ANNOTATION, SANKEY, + + CHAP_TIMELINE, CHAP_GRAPH, CHAP_GRAPH3D, CHAP_NETWORK } #region Formatter - for use with the IGoogleFormatter only @@ -38,6 +39,79 @@ public enum GOOGLECHART /// easily debugged or matching that on the Google Vis site /// + private static string jschap = + @" + + /******************************************************************************** + * GoogleVisualizationControls.NET {{ver}} + * http://code.google.com/p/googlevisualizationsdotnet/ + * Visualization: {3} + * Div Element: {0} + *********************************************************************************/ + google.load('visualization', '1'); + google.setOnLoadCallback( draw_{0} ); + var chart_{0} = undefined; + function draw_{0}() {{ + var container = document.getElementById('{0}'); + var chart = new links.{3}(container); + var arrayD = __DATATABLE__; + var data = new google.visualization.DataTable( arrayD ); + + + /********* Formatter Hooks: your function will be called before render ********/ + chart.formatters = function(chart,data){{ + /*FORMATTERS*/ + }} + /********* View Hooks: DataTables are placed in a View and invoke your functions before going to render ********/ + chart.formatView = function(chart,view){{ + /*VIEW_FUNCTIONS*/ + }} + + /********* Extended Functions **********************/ + chart.reload = function(args, url) + {{ + if (url == undefined || url == null){{ + url = '{QueryString}'; + }} + m_SendAndDraw(container, chart, url, args) + }}; + chart.load = function(data) + {{ + m_JustDraw(container, chart, data); + }}; + chart.format = function(data) + {{ + {formatter} + }}; + + /********* User Defined Functions **********************/ + {4} + + /********* Extended Params **********************/ + chart.opts = {1}; + chart.container = container; + + + + /********* Init Chart Load **********************/ + chart.draw(data, chart.opts); + + + /********* Update These Image Src **********************/ + {SETIMAGEFOR} + + + + + + /********* Save Chart Into DOM / Always Last **********************/ + chart_{0} = chart; + + + +}} +"; + private static string jscode3 = @" @@ -211,6 +285,12 @@ public BaseGVI() dic.Add(GOOGLECHART.ANNOTATION, new string[] { "annotationchart", "AnnotationChart" }); dic.Add(GOOGLECHART.SANKEY, new string[] { "sankey", "Sankey" }); dic.Add(GOOGLECHART.WORDTREE, new string[] { "wordtree", "WordTree" }); + + + dic.Add(GOOGLECHART.CHAP_TIMELINE, new string[] { "chap_timeline", "Timeline" }); + dic.Add(GOOGLECHART.CHAP_GRAPH, new string[] { "chap_graph", "Graph" }); + dic.Add(GOOGLECHART.CHAP_GRAPH3D, new string[] { "chap_graph3d", "Graph3D" }); + dic.Add(GOOGLECHART.CHAP_NETWORK, new string[] { "chap_network", "Network" }); } } @@ -224,6 +304,10 @@ public BaseGVI() internal void RegisterGVIScriptsEx(BaseWebControl PageControl, DataTable dt, GOOGLECHART CHARTTYPE) { string JAVASCRIPT = jscode3; + + if (CHARTTYPE == GOOGLECHART.CHAP_TIMELINE) + JAVASCRIPT = jschap; + string options,formatter = string.Empty; string imagereplace = string.Empty; List events = RenderGVIEvents(PageControl); diff --git a/GoogleChartsNGraphsControls/CHAPTimeline.bmp b/GoogleChartsNGraphsControls/CHAPTimeline.bmp new file mode 100644 index 0000000..f04bf8a Binary files /dev/null and b/GoogleChartsNGraphsControls/CHAPTimeline.bmp differ diff --git a/GoogleChartsNGraphsControls/CHAPTimeline.cs b/GoogleChartsNGraphsControls/CHAPTimeline.cs new file mode 100644 index 0000000..05b1e17 --- /dev/null +++ b/GoogleChartsNGraphsControls/CHAPTimeline.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ComponentModel; +using System.Web.UI; +using System.Drawing; +using System.Web.UI.WebControls; +using System.Data; +using System.Runtime.Serialization; + +namespace GoogleChartsNGraphsControls +{ + [DefaultProperty("GviShowTip")] + [ToolboxData("<{0}:CHAPTimeline runat=server>")] + [ToolboxBitmap(typeof(CHAPTimeline))] + [DataContract] + public class CHAPTimeline : BaseWebControl + { + private DateTime? visibleChartRangeStart + { + get + { + if (ViewState["visibleChartRangeStart"] == null) + return null; + + DateTime? s = (DateTime?)ViewState["visibleChartRangeStart"]; + return s; + } + set + { + ViewState["visibleChartRangeStart"] = value; + } + } + private DateTime? visibleChartRangeEnd + { + get + { + if (ViewState["visibleChartRangeEnd"] == null) + return null; + + DateTime? s = (DateTime?)ViewState["visibleChartRangeEnd"]; + return s; + } + set + { + ViewState["visibleChartRangeEnd"] = value; + } + } + + public void SetVisibleChartRange(DateTime start, DateTime end) + { + this.visibleChartRangeStart = start; + this.visibleChartRangeEnd = end; + } + public void ChartData(CHAPTimelineEvent[] ListOfEvents) + { + + if ((this.dt == null) || (this.dt.Columns.Count == 0)) + { + this.dt = new DataTable(); + // there always must be a date + dt.Columns.Add("start", typeof(DateTime)); + dt.Columns.Add("end", typeof(DateTime)); + dt.Columns.Add("content"); + } + + + foreach(var ee in ListOfEvents) + { + this.dt.Rows.Add(ee.ToRow()); + } + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + if (!this.Page.ClientScript.IsClientScriptBlockRegistered(this.GetType().BaseType, "REGISTER_CHAP_TIMELINE")) + { + this.Page.ClientScript.RegisterClientScriptBlock(this.GetType().BaseType, "REGISTER_CHAP_TIMELINE", + Resource1.ResourceManager.GetString("timeline_min", System.Globalization.CultureInfo.CurrentCulture), true); + this.Page.ClientScript.RegisterClientScriptBlock(this.GetType().BaseType, "REGISTER_CHAP_TIMELINE_LOCALES", + Resource1.ResourceManager.GetString("timeline_locales", System.Globalization.CultureInfo.CurrentCulture), true); + + + this.Page.Header.Controls.Add(new LiteralControl("" )); + + + this.Page.Header.Controls.Add(new LiteralControl("")); + + } + + + } + + protected override void RenderContents(HtmlTextWriter output) + { + this.GviTitle = string.IsNullOrEmpty(this.GviTitle) ? this.dt.TableName : this.GviTitle; + this.gvi.RegisterGVIScriptsEx(this, this.dt, BaseGVI.GOOGLECHART.CHAP_TIMELINE); + output.Write(Text); + } + + public override string ToString() + { + List myconverters = new List(); + myconverters.Add(new CustomConvertersColorToRGB()); + myconverters.Add(new CustomConvertersAxis()); + myconverters.Add(new CustomConvertersLegend()); + myconverters.Add(new CustomConverterEnum()); + myconverters.Add(new CustomConverterTrendLine()); + + Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings() + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = myconverters + }; + + string s = string.Empty; + s = Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.None, settings); + return s; + } + } +} diff --git a/GoogleChartsNGraphsControls/DataStructs.cs b/GoogleChartsNGraphsControls/DataStructs.cs index cd59e61..6481117 100644 --- a/GoogleChartsNGraphsControls/DataStructs.cs +++ b/GoogleChartsNGraphsControls/DataStructs.cs @@ -51,22 +51,84 @@ public TimelineEvent(string EventCategory, DateTime EventDate, int value, string public string OptionalAnnotationTitle { get; set; } public string OptionalAnnotationText { get; set; } } + public class CHAPTimelineEvent + { + public class ImgFormatContent + { + public ImgFormatContent() { } + public ImgFormatContent(string img, string title) + { + this.IconUrl = img; + this.Title = title; + } + public string IconUrl { get; set; } + public string Title { get; set; } + public override string ToString() + { + return string.Format("