public string GetHtml() { var html = string.Empty; var chartQueryPieChartData = new Dictionary <string, long>(); var chartQueryResultsLocal = Database.GetInstance().GetActivityPieChartData(_date); // merge with remote data if necessary chartQueryPieChartData = RemoteDataHandler.VisualizeWithRemoteData() ? RemoteDataHandler.MergeActivityData(chartQueryResultsLocal, Database.GetInstanceRemote().GetActivityPieChartData(_date)) : chartQueryResultsLocal; if (chartQueryPieChartData.Count == 0) { html += VisHelper.NotEnoughData(Dict.NotEnoughDataMiniSurvey); return(html); } var chartUrl = PreparePieChartUrl(chartQueryPieChartData); var totalHoursWorked = Database.GetInstance().GetTotalHoursWorked(_date); html += VisHelper.ChartTitle("Distribution of the Activity on your Computer"); html += "<p style='text-align: center;'>Total hours worked on your computer: <strong>" + totalHoursWorked + "</strong>.</p>"; html += string.IsNullOrEmpty(chartUrl) ? VisHelper.NotEnoughData() : "<p style='text-align: center;'><img src='" + chartUrl + "'/></p>"; return(html); }
public string GetHtml() { var html = String.Empty; var productivityGaugeData = new List <ProductivityTimeDto>(); // fetch data sets var productivityGaugeDataLocal = Database.GetInstance().GetUserProductivityData(_date, false); // merge with remote data if necessary productivityGaugeData = RemoteDataHandler.VisualizeWithRemoteData() ? RemoteDataHandler.MergeProductivityData(productivityGaugeDataLocal, Database.GetInstanceRemote().GetUserProductivityData(_date, false)) : productivityGaugeDataLocal; html += VisHelper.ChartTitle("Your Perceived Productivity"); if (productivityGaugeData.Count == 0) { html += VisHelper.NotEnoughData(Dict.NotEnoughDataMiniSurvey); return(html); } // Calculate Productivityvalue var productivityValue = CalculateWeightedProductivityValue(productivityGaugeData); ///////////////////// // Some strings for the attributes ///////////////////// const string gaugeChartName = "gaugeChartName"; const int height = 100; ///////////////////// // CSS ///////////////////// html += "<style type='text/css'>"; html += ".c3-gauge-value { fill: white; visibility:hidden; }"; // hack to hide the gauge value html += "</style>"; ///////////////////// // HTML ///////////////////// //html += "<p style='text-align: center;'>Average productivity based on your manual selection in the mini-surveys<br />(1 = very unproductive, 7 = very productive).</p>"; html += "<div id='" + gaugeChartName + "' align='center'></div>"; ///////////////////// // JS ///////////////////// var productivityValueString = Math.Round(productivityValue, 1).ToString().Replace(',', '.'); var data = "columns: [ ['PerceivedProductivity', " + productivityValueString + "] ], type: 'gauge'"; const string gauge = " label : { show: false }, min: 1, max: 7, width: 36"; const string color = "pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'], threshold: { unit: 'value', max: 7, values: [1, 2, 4, 6] }"; var size = "height: " + height; var parameters = " bindto: '#" + gaugeChartName + "', data: { " + data + " }, gauge: { " + gauge + " }, color: { " + color + " }, size: { " + size + " }"; html += "<script type='text/javascript'>"; html += "var " + gaugeChartName + " = c3.generate({ " + parameters + " });"; html += "</script>"; return(html); }
/// <summary> /// Creates a line graph showing the user input level /// </summary> /// <returns></returns> private string CreateUserInputLineGraph() { var html = string.Empty; // fetch data sets var userInputDataLocal = Database.GetInstance().GetUserInputTimelineData(_date); if (userInputDataLocal == null || userInputDataLocal.Count < 3) // 3 is the minimum number of input-data-items { html += VisHelper.NotEnoughData(Dict.NotEnoughDataMiniSurvey); return(html); } ///////////////////// // Some strings for the attributes ///////////////////// const string userInputLineGraph = "userInputLineGraph"; const int width = 770; const int height = 150; ///////////////////// // HTML ///////////////////// html += "<div id='" + userInputLineGraph + "' align='right'></div>"; ///////////////////// // JS ///////////////////// var ticks = CalculateLineChartAxisTicks(_date); var timeAxis = userInputDataLocal.Aggregate("", (current, a) => current + (Helpers.JavascriptTimestampFromDateTime(a.Key) + ", ")).Trim().TrimEnd(','); var userInputFormattedData = userInputDataLocal.Aggregate("", (current, p) => current + (p.Value + ", ")).Trim().TrimEnd(','); const string colors = "'User_Input_Level' : '#007acb'"; var data = "x: 'timeAxis', columns: [['timeAxis', " + timeAxis + "], ['User_Input_Level', " + userInputFormattedData + " ] ], type: 'spline', colors: { " + colors + " }, axis: { 'PerceivedProductivity': 'y' }"; var size = "width: " + width + ", height: " + height; const string legend = "show: true"; // can only be shown on the right side, and bottom (not left) ... :( const string tooltip = "show: false"; const string point = "show: false"; var axis = "x: { localtime: true, type: 'timeseries', tick: { values: [ " + ticks + "], format: function(x) { return formatDate(x.getHours()); }} }, y: { show: true, min: 0 }"; var parameters = " bindto: '#" + userInputLineGraph + "', padding: { right: -10 }, data: { " + data + " }, legend: { " + legend + " }, axis: { " + axis + " } , size: { " + size + " }, tooltip: { " + tooltip + " }, point: { " + point + " }"; // padding: { left: 0px, right: 0px }, html += "<script type='text/javascript'>"; html += "var formatDate = function(hours) { var suffix = 'AM'; if (hours >= 12) { suffix = 'PM'; hours = hours - 12; } if (hours == 0) { hours = 12; } if (hours < 10) return '0' + hours + ' ' + suffix; else return hours + ' ' + suffix; };"; html += "var " + userInputLineGraph + " = c3.generate({ " + parameters + " });"; // return x.getHours() + ':' + x.getMinutes(); html += "</script>"; return(html); }
public string GetHtml() { // calculate maxWidth // TODO: do later // produce visualizations (html) var html = string.Empty; html += VisHelper.ChartTitle("Timeline of your Context, User Input and Perceived Productivity"); html += CreateContextGantTimeline(); html += CreateUserInputLineGraph(); html += CreateProdTasksLineGraph(); return(html); }
private int OnStats(HttpReqResp req) { try { var html = string.Empty; var date = VisHelper.GetVisualizationDateFromUrlParameters(req); //var visType = VisHelper.GetVisualizationTypesFromUrlParameters(req); // log request Database.GetInstance().LogInfo(string.Format("The participant opened the retrospection/visualization for '{0}'.", date)); // prepare charts var contextTimelineChart = new ContextTimelineChart(date); var productivityGauge = new ProductivityGaugeChart(date); var activityPie = new ActivityPieChart(date); // organize & draw charts html += "<style type='text/css'>"; html += "td { border: 3px solid #B0B0B0; }"; html += "</style>"; html += "<table cellpadding='20' style='margin-left: auto; margin-right: auto;'>"; // border-color: #F1F1F1; vertical-align: top; horizontal-align: center;' html += "<tr><td style='vertical-align:top;'>" + productivityGauge.GetHtml() + "</td><td style='vertical-align:top;' rowspan='2'>" + contextTimelineChart.GetHtml() + "</td></tr>"; html += "<tr><td style='vertical-align:top;'>" + activityPie.GetHtml() + "</td></tr>"; html += "</table>"; var title = Dict.RetrospectionPageTitle + " for the " + date.Date.ToShortDateString(); if (RemoteDataHandler.VisualizeWithRemoteData()) { title += " (visualizing local and remote data)"; } //title += "<a href=\"settings\">" + Settings.SettingsTitle + "</a>"; html = ((string)_resourceManager.GetObject("personalanalytics_html")) .Replace("{content}", html) //.Replace("{menu}", Menu) .Replace("{title}", title); req.Write(html); req.SetHeader("Content-Type", "text/html; charset=utf-8"); } catch (Exception e) { req.Write(e.ToString()); req.SetHeader("Content-Type", "text/html; charset=utf-8"); } return(200); }
private string CreateContextGantTimeline() { var html = string.Empty; // fetch raw data sets var activityDataSet = new List <ActivitiesDto>(); activityDataSet = Database.GetInstance().GetActivitiesTimelineData(_date); var taskDataSet = new Dictionary <string, List <StartEndTimeDto> >(); taskDataSet = Database.GetInstance().GetTaskGantTimelineData(_date); // merge with remote data if necessary TODO: finish! // tasksWorkedOnDataSet = RemoteDataHandler.VisualizeWithRemoteData() // ? RemoteDataHandler.MergeTasksData(tasksWorkedOnDataLocal, Database.GetInstanceRemote().GetTasksWorkedOnData(_date)) // : tasksWorkedOnDataLocal; Console.WriteLine(taskDataSet); // check data available if (activityDataSet == null || activityDataSet.Count <= 2) { html += VisHelper.NotEnoughData(Dict.NotEnoughDataMiniSurvey); return(html); } ///////////////////// // Some strings for the attributes ///////////////////// const string contextGantTimeline = "contextGantTimeline"; const string labelData = "labelData"; //const string hoverRes = "hoverRes"; //const string coloredDiv = "coloredDiv"; //const string hoverDetails = "hoverDetails"; const int visWidth = 850; //1200; ///////////////////// // JS ///////////////////// html += "<script type='text/javascript'>"; html += "var oldOnload2 = window.onload;"; html += "window.onload = function() { "; // start #1 html += "if (typeof oldOnload2 == 'function') { oldOnload2(); } "; // create formatted javascript data list html += "var " + labelData + " = [" + CreateJavascriptDataList(taskDataSet, activityDataSet) + "]; "; // define configuration // hint: d is the current rendering object, i is the index during d3 rendering, datum is the id object //const string hoverFunction = "function (d, i, datum) { var div = $('#" + hoverRes + "'); var colors = " + contextGantTimeline + ".colors(); div.find('." + coloredDiv + "').css('background-color', colors(i)); div.find('#" + hoverDetails + "').text(datum.label + ' from: ' + d.starting_time + ', to: ' + d.ending_time); }"; html += "var " + contextGantTimeline + " = d3.timeline().width(" + visWidth + ").stack().margin({left: 140, right: 1, top: -20, bottom: 0});"; //.hover(" + hoverFunction + ");"; //TODO: commented out hover stuff html += "var svg = d3.select('#" + contextGantTimeline + "').append('svg').attr('width', " + visWidth + ").datum(" + labelData + ").call(" + contextGantTimeline + "); "; html += "}; "; // end #1 html += "</script>"; ///////////////////// // HTML ///////////////////// html += "<div id='" + contextGantTimeline + "' align='right'></div>"; //html += "<div id='" + hoverRes + "'><div class='" + coloredDiv + "'></div><div id='" + hoverDetails + "'></div>" + "</div>"; html += GetLegendForCategories(activityDataSet, visWidth); return(html); }
private string CreateProdTasksLineGraph() { var html = string.Empty; // fetch data sets var productivityDataSet = new List <ProductivityTimeDto>(); var tasksWorkedOnDataSet = new List <TasksWorkedOnTimeDto>(); var tasksWorkedOnDataLocal = Database.GetInstance().GetTasksWorkedOnData(_date); var productivityDataLocal = Database.GetInstance().GetUserProductivityData(_date, true); // merge with remote data if necessary tasksWorkedOnDataSet = RemoteDataHandler.VisualizeWithRemoteData() ? RemoteDataHandler.MergeTasksData(tasksWorkedOnDataLocal, Database.GetInstanceRemote().GetTasksWorkedOnData(_date)) : tasksWorkedOnDataLocal; productivityDataSet = RemoteDataHandler.VisualizeWithRemoteData() ? RemoteDataHandler.MergeProductivityData(productivityDataLocal, Database.GetInstanceRemote().GetUserProductivityData(_date, false)) : productivityDataLocal; if (tasksWorkedOnDataSet == null || tasksWorkedOnDataSet.Count <= 1 || productivityDataSet == null || productivityDataSet.Count <= 1) { html += VisHelper.NotEnoughData(Dict.NotEnoughDataMiniSurvey); return(html); } ///////////////////// // Some strings for the attributes ///////////////////// const string prodTasksLineGraph = "prodTasksLineGraph"; const int width = 730; //780; const int height = 130; ///////////////////// // CSS ///////////////////// html += "<style type='text/css'>"; html += ".c3-line { stroke-width: 2px; }"; //html += ".c3-axis-y-label { color: #007acc; fill: #007acc; font-size: 1.4em; }"; // left axis label color //html += ".c3-axis-y2-label { fill: 'gray'; font-size: 1.4em; }"; // right axis label color html += "</style>"; ///////////////////// // HTML ///////////////////// html += "<div id='" + prodTasksLineGraph + "' align='right'></div>"; ///////////////////// // JS ///////////////////// var ticks = CalculateLineChartAxisTicks(_date); var timeAxis = tasksWorkedOnDataSet.Aggregate("", (current, a) => current + (a.Time + ", ")).Trim().TrimEnd(','); var productivityFormattedData = productivityDataSet.Aggregate("", (current, p) => current + (p.UserProductvity + ", ")).Trim().TrimEnd(','); var tasksFormattedData = tasksWorkedOnDataSet.Aggregate("", (current, t) => current + (t.TasksWorkedOn + ", ")).Trim().TrimEnd(','); const string colors = "'Number_Of_Activities_In_Session': '#007acc', 'Perceived_Productivity': 'gray'"; var data = "x: 'timeAxis', columns: [['timeAxis', " + timeAxis + "], ['Number_Of_Activities_In_Session', " + tasksFormattedData + " ], ['Perceived_Productivity', " + productivityFormattedData + " ] ], type: 'spline', colors: { " + colors + " } , axes: { 'PerceivedProductivity': 'y', 'NumberOfTasksWorkedOn': 'y2' }"; var size = "width: " + width + ", height: " + height; const string tooltip = "show: false"; //(tasksWorkedOnDataSet.Count > 4) ? " show: false " : " show: true "; // only hide if there are more than 4 elements const string legend = "show: true"; // can only be shown on the right side, and bottom (not left) ... :( const string point = "show: false"; //var axis = "x: { localtime: true, type: 'timeseries', tick: { values: [ " + ticks + "], format: function(x) { return pad2(x.getHours()) + ':' + pad2(x.getMinutes()); }} }, y: { max: 7, min: 1, label: { text: 'Perceived Productivity', position: 'outer-right' } }, y2: { show: true, min: 0, label: { text: 'Number of tasks worked on', position: 'outer-right' } }"; var axis = "x: { localtime: true, type: 'timeseries', tick: { values: [ " + ticks + "], format: function(x) { return formatDate(x.getHours()); }} }, y: { show: false, max: 7, min: 1 }, y2: { show: false, min: 0 }"; var parameters = " bindto: '#" + prodTasksLineGraph + "', data: { " + data + " }, legend: { " + legend + " }, axis: { " + axis + " } , size: { " + size + " }, tooltip: { " + tooltip + " }, point: { " + point + " } "; html += "<script type='text/javascript'>"; html += "var formatDate = function(hours) { var suffix = 'AM'; if (hours >= 12) { suffix = 'PM'; hours = hours - 12; } if (hours == 0) { hours = 12; } if (hours < 10) return '0' + hours + ' ' + suffix; else return hours + ' ' + suffix; };"; html += "var " + prodTasksLineGraph + " = c3.generate({ " + parameters + " });"; // return x.getHours() + ':' + x.getMinutes(); html += "</script>"; return(html); }