/// <summary>
    /// This function is called by the trigger whenever
    /// this trigger has been TRIGGERED.
    /// </summary>
    /// <param name="current">
    /// The current value of the targeted controller.
    /// </param>
    /// <param name="previous">
    /// The previous value of the targeted controller.
    /// </param>
    /// <param name="difference">
    /// The value difference of the targeted controller.
    /// </param>
    /// <param name="adjustedDifference">
    /// The adjusted value difference of the targeted controller.
    /// This value is the difference value as if it took place over a
    /// certain time period, controlled by VisBaseController.mc_fTargetAdjustedDifferenceTime.  The
    /// default of this essientially indicates a frame rate of 60 fps to determine
    /// the adjusted difference.  This should be used for almost all difference
    /// calculations, as it is NOT frame rate dependent.
    /// </param>
    public override void OnTriggered(float current, float previous, float difference, float adjustedDifference)
    {
        Rigidbody rigidbodyComp = GetComponent <Rigidbody>();

        if (rigidbodyComp != null)
        {
            //get normalized direction
            Vector3 normalDir = forceDirection.normalized;

            //get the source value
            float value = current;
            if (controllerValue == ControllerSourceValue.Previous)
            {
                value = previous;
            }
            else if (controllerValue == ControllerSourceValue.Difference)
            {
                value = adjustedDifference;
            }

            //calc the property value
            float forceValue = VisHelper.ConvertBetweenRanges(value,
                                                              minControllerValue,
                                                              maxControllerValue,
                                                              minForceValue,
                                                              maxForceValue,
                                                              invertValue);

            //add force
            rigidbodyComp.AddForce(normalDir * forceValue, forceMode);
        }
    }
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            //var chartQueryPieChartData = new Dictionary<string, long>();
            var chartQueryResultsLocal = Queries.GetActivityPieChartData(_date);

            // merge with remote data if necessary //TODO: REMOTE DATA
            //chartQueryPieChartData = RemoteDataHandler.VisualizeWithRemoteData()
            //    ? RemoteDataHandler.MergeActivityData(chartQueryResultsLocal, Queries.GetActivityPieChartData(_date))
            //    : chartQueryResultsLocal;

            /////////////////////
            // data cleaning
            /////////////////////
            //// remove IDLE (doesn't belong to activity on computer)
            //if (chartQueryResultsLocal.ContainsKey(Dict.Idle))
            //    chartQueryResultsLocal.Remove(Dict.Idle);

            // calculate total active time
            var totalHoursWorked = chartQueryResultsLocal.Sum(x => x.Value);

            // check if we have enough data
            if (chartQueryResultsLocal.Count == 0 || totalHoursWorked < _minTimeWorked)
            {
                html += VisHelper.NotEnoughData(Dict.NotEnoughData);
                return(html);
            }

            PrepareDataForVisualization(chartQueryResultsLocal);


            /////////////////////
            // HTML
            /////////////////////
            html += "<p style='text-align: center;'>Total hours worked on your computer: <strong>" + Math.Round(totalHoursWorked, 1) + "</strong>.</p>";
            html += "<div id='" + VisHelper.CreateChartHtmlTitle(Title) + "' style='height:75%;'  align='center'></div>";


            /////////////////////
            // JS
            /////////////////////
            var columns = string.Empty;

            foreach (var program in chartQueryResultsLocal)
            {
                columns += string.Format(CultureInfo.InvariantCulture, "['{0}', {1}], ", program.Key, Math.Round(program.Value, 1));
            }

            var data = "columns: [ " + columns + "], type: 'pie'";

            html += "<script type='text/javascript'>";
            html += "var " + VisHelper.CreateChartHtmlTitle(Title) + " = c3.generate({ bindto: '#" + VisHelper.CreateChartHtmlTitle(Title) + "', data: { " + data + "}, pie: { label: { format: function (value, ratio, id) { return value + 'h';}}}, padding: { top: 0, right: 0, bottom: 0, left: 0 }, legend: { show: true, position: 'bottom' }});";
            html += "</script>";

            return(html);
        }
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var queryResultsLocal = Queries.GetLongestFocusOnProgram(_date);
            var durInMin          = (queryResultsLocal == null) ? 0 : queryResultsLocal.DurationInSec / 60.0;

            if (queryResultsLocal == null || durInMin <= _minFocusTime)
            {
                html += VisHelper.NotEnoughData(string.Format(CultureInfo.InvariantCulture, "We either don't have enough data or you didn't focus on a single program for more than {0} minutes on this day.", _minFocusTime));
                return(html);
            }

            /////////////////////
            // HTML
            /////////////////////
            html += "<p style='text-align: center; margin-top:-0.7em;'><strong style='font-size:2.5em; color:" + Shared.Settings.RetrospectionColorHex + ";'>" + Math.Round(durInMin, 0) + "</strong> min</p>";
            html += string.Format(CultureInfo.InvariantCulture, "<p style='text-align: center; margin-top:-0.7em;'>in {0}<br />from {1} to {2}</p>",
                                  ProcessNameHelper.GetFileDescription(queryResultsLocal.Process),
                                  queryResultsLocal.From.ToShortTimeString(),
                                  queryResultsLocal.To.ToShortTimeString());

            return(html);
        }
    /// <summary>
    /// This function is called by the base modifier whenever
    /// the value of the targeted controller is updated.
    /// </summary>
    /// <param name="current">
    /// The current value of the targeted controller.
    /// </param>
    /// <param name="previous">
    /// The previous value of the targeted controller.
    /// </param>
    /// <param name="difference">
    /// The value difference of the targeted controller.
    /// </param>
    /// <param name="adjustedDifference">
    /// The adjusted value difference of the targeted controller.
    /// This value is the difference value as if it took place over a
    /// certain time period, controlled by VisBaseController.mc_fTargetAdjustedDifferenceTime.  The
    /// default of this essientially indicates a frame rate of 60 fps to determine
    /// the adjusted difference.  This should be used for almost all difference
    /// calculations, as it is NOT frame rate dependent.
    /// </param>
    public override void OnValueUpdated(float current, float previous, float difference, float adjustedDifference)
    {
        //get the source value
        float value = current;

        if (controllerSourceValue == ControllerSourceValue.Previous)
        {
            value = previous;
        }
        else if (controllerSourceValue == ControllerSourceValue.Difference)
        {
            value = adjustedDifference;
        }

        //calc the property value
        float propertyValue = VisHelper.ConvertBetweenRanges(value,
                                                             minControllerValue,
                                                             maxControllerValue,
                                                             minPropertyValue,
                                                             maxPropertyValue,
                                                             invertValue);

        //call to abstract function to set the property
        SetProperty(propertyValue);
    }
Esempio n. 5
0
        /// <summary>
        /// Creates a list of one-hour axis times
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private static string CalculateLineChartAxisTicks(DateTimeOffset date)
        {
            var dict = new Dictionary <DateTime, int>();

            VisHelper.PrepareTimeAxis(date, dict, 60);

            return(dict.Aggregate("", (current, a) => current + (DateTimeHelper.JavascriptTimestampFromDateTime(a.Key) + ", ")).Trim().TrimEnd(','));
        }
    /// <summary>
    /// This is called when this component is started.
    /// </summary>
    public override void Start()
    {
        base.Start();

        maxControllerValue = VisHelper.Validate(maxControllerValue, -1000000.0f, 1000000.0f, Defaults.maxControllerValue, this, "maxControllerValue", false);
        minControllerValue = VisHelper.Validate(minControllerValue, -1000000.0f, maxControllerValue, Mathf.Min(Defaults.minControllerValue, maxControllerValue), this, "minControllerValue", false);
        maxPropertyValue   = VisHelper.Validate(maxPropertyValue, -1000000.0f, 1000000.0f, Defaults.maxPropertyValue, this, "maxPropertyValue", false);
        minPropertyValue   = VisHelper.Validate(minPropertyValue, -1000000.0f, maxPropertyValue, Mathf.Min(Defaults.minPropertyValue, maxPropertyValue), this, "minPropertyValue", false);
    }
Esempio n. 7
0
        public override string GetHtml()
        {
            var html = string.Empty;


            /////////////////////
            // fetch data sets
            /////////////////////
            var programUsePerDay = GetProgramUsePerDay();
            var totalHoursPerDay = GetTotalHoursPerDay(programUsePerDay);

            if (programUsePerDay.Count < 1)
            {
                html += VisHelper.NotEnoughData(Dict.NotEnoughData);
                return(html);
            }


            /////////////////////
            // HTML
            /////////////////////

            html += string.Format(CultureInfo.InvariantCulture, "<table id='{0}'>", VisHelper.CreateChartHtmlTitle(Title));
            html += GetTableHeader();
            html += "<tbody style='overflow:hidden;'>";
            foreach (var prog in programUsePerDay)
            {
                html += "<tr>";
                html += "<td>" + prog.Key + "</td>";
                for (int i = 1; i < 7; i++)
                {
                    html += GetTableRow(GetPercentage(prog.Value.Days[i], totalHoursPerDay[i]));
                }
                html += GetTableRow(GetPercentage(prog.Value.Days[0], totalHoursPerDay[0])); // special case: to have Sunday last (TODO: make better, as it isn't the same in every culture)
                html += "</tr>";
            }
            html += "</tbody>";
            html += "</table>";


            /////////////////////
            // create & add javascript
            ////////////////////
            var js = "<script type='text/javascript'>"
                     + "var tf = new TableFilter('" + VisHelper.CreateChartHtmlTitle(Title) + "', { base_path: '/', "
                     + "col_widths:[ '9.6875em', '2.1875em', '2.1875em', '2.1875em', '2.1875em', '2.1875em', '2.1875em', '2.1875em'], "                                     // fixed columns sizes
                     + "col_0: 'none', col_1: 'none', col_2: 'none', col_3: 'none', col_4: 'none', col_5: 'none', col_6: 'none', col_7: 'none', "
                     + "alternate_rows: true, "                                                                                                                             // styling options
                     + "grid_layout: true, grid_width: '25.6em', grid_height: '18em', grid_cont_css_class: 'grd-main-cont', grid_tblHead_cont_css_class: 'grd-head-cont', " // styling & behavior of the table
                     + "}); "                                                                                                                                               // no content options
                     + "tf.init(); "
                     + "</script>";

            html += " " + js;

            return(html);
        }
Esempio n. 8
0
        private static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Arguments:");
                Console.WriteLine("\t-c : Compile Main File");
                Console.WriteLine("\t-clean : Clean Build Directory");
                Console.WriteLine("\t-r : Run Dynamic Commandline");
                Console.WriteLine("\t-o : Optimize Assembly");
                Console.WriteLine("\t-d : Debug(Make all labels and data sections visible)");

                return;
            }

            bool compile   = args.Any(x => x == "-c");
            bool clean     = args.Any(x => x == "-clean");
            bool run       = args.Any(x => x == "-r");
            bool optimized = args.Any(x => x == "-o");
            bool debug     = args.Any(x => x == "-d");

            FirstSetup.Start();

            LinkerSettings linkerSettings = SettingsManager.GetSettings <LinkerSettings>();

            linkerSettings.NoHiddenItems = debug;
            SettingsManager.SaveSettings(linkerSettings);

            AssemblyGeneratorSettings gsettings = SettingsManager.GetSettings <AssemblyGeneratorSettings>();

            gsettings.Format = "v1"; //Set Raw Assembly Mode
            SettingsManager.SaveSettings(gsettings);

            HlCompilerSettings settings = SettingsManager.GetSettings <HlCompilerSettings>();

            settings.OptimizeAll = optimized;
            SettingsManager.SaveSettings(settings);

            string output = null;

            output = compile ? VisHelper.Compile(clean) : FirstSetup.DefaultFile;

            if (run)
            {
                if (output == null)
                {
                    Console.WriteLine($"Output file error.");

                    FirstSetup.End(EndOptions.Default);

                    return;
                }

                ConsoleLoop(output);
            }

            FirstSetup.End(EndOptions.Default);
        }
Esempio n. 9
0
    /// <summary>
    /// This function is called when this trigger is started.
    /// Should be override by sub classes to initialize.
    /// </summary>
    public virtual void Start()
    {
        //make sure to restore the targets if needed
        VisManager.RestoreVisManagerTarget(this);
        VisBaseController.RestoreVisBaseControllerTarget(this);

        //validate trigger variables.
        triggerThreshold       = VisHelper.Validate(triggerThreshold, 0.0001f, 10000.0f, Defaults.triggerThreshold, this, "triggerThreshold", false);
        triggerReactivateDelay = VisHelper.Validate(triggerReactivateDelay, 0.0f, 10000.0f, Defaults.triggerReactivateDelay, this, "triggerReactivateDelay", false);
    }
Esempio n. 10
0
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var chartQueryResultsLocal = Queries.GetUserProductivityTimelineData(_date, VisType.Day);

            if (chartQueryResultsLocal.Count < 3) // 3 is the minimum number of input-data-items
            {
                html += VisHelper.NotEnoughData("It is not possible to give you insights into your productivity as you didn't fill out the pop-up often enough. Try to fill it out at least 3 times per day.");
                return(html);
            }


            /////////////////////
            // CSS
            /////////////////////
            html += "<style type='text/css'>";
            html += ".c3-line { stroke-width: 2px; }";
            html += ".c3-grid text, c3.grid line { fill: gray; }";
            html += "</style>";


            /////////////////////
            // HTML
            /////////////////////
            html += "<div id='" + VisHelper.CreateChartHtmlTitle(Title) + "' style='height:75%;' align='center'></div>";
            html += "<p style='text-align: center; font-size: 0.66em;'>Hint: Interpolates your perceived productivity, based on your pop-up responses.</p>";


            /////////////////////
            // JS
            /////////////////////
            var ticks    = CalculateLineChartAxisTicks(_date);
            var timeAxis = chartQueryResultsLocal.Aggregate("", (current, a) => current + (DateTimeHelper.JavascriptTimestampFromDateTime(a.Item1) + ", ")).Trim().TrimEnd(',');
            var productivityFormattedData = chartQueryResultsLocal.Aggregate("", (current, p) => current + (p.Item2 + ", ")).Trim().TrimEnd(',');

            const string colors     = "'User_Input_Level' : '" + Shared.Settings.RetrospectionColorHex + "'";
            var          data       = "x: 'timeAxis', columns: [['timeAxis', " + timeAxis + "], ['Productivity', " + productivityFormattedData + " ] ], type: 'line', colors: { " + colors + " }, axis: { 'PerceivedProductivity': 'y' } "; // type options: spline, step, line
            var          grid       = "y: { lines: [ { value: 1, text: 'not at all productive' }, { value: 4, text: 'moderately productive' }, { value: 7, text: 'very productive' } ] } ";
            var          axis       = "x: { localtime: true, type: 'timeseries', tick: { values: [ " + ticks + "], format: function(x) { return formatDate(x.getHours()); }}  }, y: { min: 1, max: 7 }";                                    // show: false,
            var          tooltip    = "show: true, format: { title: function(d) { return 'Pop-Up answered: ' + formatTime(d.getHours(),d.getMinutes()); }}";
            var          parameters = " bindto: '#" + VisHelper.CreateChartHtmlTitle(Title) + "', data: { " + data + " }, padding: { left: 15, right: 0, bottom: -10, top: 0}, legend: { show: false }, axis: { " + axis + " }, grid: { " + grid + " }, tooltip: { " + tooltip + " }, point: { show: true }";


            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 formatTime = function(hours, minutes) { var minFormatted = minutes; if (minFormatted < 10) minFormatted = '0' + minFormatted; var suffix = 'AM'; if (hours >= 12) { suffix = 'PM'; hours = hours - 12; } if (hours == 0) { hours = 12; } if (hours < 10) return '0' + hours + ':' + minFormatted + ' ' + suffix; else return hours + ':' + minFormatted + ' ' + suffix; };";
            html += "var " + VisHelper.CreateChartHtmlTitle(Title) + " = c3.generate({ " + parameters + " });"; // return x.getHours() + ':' + x.getMinutes();
            html += "</script>";

            return(html);
        }
Esempio n. 11
0
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var orderedTimelineList = Queries.GetDayWindowTitleData(_date);

            /////////////////////
            // data cleaning
            /////////////////////

            // show message if not enough data
            var sum = orderedTimelineList.Sum(i => i.DurationInSeconds);

            if (orderedTimelineList.Count <= 3 || sum < 5 * 60) // 3 is the minimum number of input-data-items & 5 minutes of data
            {
                _sb.Append(VisHelper.NotEnoughData(Dict.NotEnoughData));
                return(_sb.ToString());
            }

            // remove first + last items if IDLE
            if (orderedTimelineList.First().ActivityCategory == ActivityCategory.Idle)
            {
                orderedTimelineList.Remove(orderedTimelineList.First());
            }
            if (orderedTimelineList.Last().ActivityCategory == ActivityCategory.Idle)
            {
                orderedTimelineList.Remove(orderedTimelineList.Last());
            }

            /////////////////////
            // Create HTML
            /////////////////////

            _sb.Append(GetActivityVisualizationContent(orderedTimelineList));
            return(_sb.ToString());

            //var data = Queries.GetWindowTitles(30, _date);

            //foreach(List<string> list in data)
            //{
            //    foreach(string title in list)
            //    {
            //        html += title + " ";
            //    }
            //}
            //return html;
        }
Esempio n. 12
0
    /// <summary>
    /// This function is called by the trigger whenever
    /// this trigger has been TRIGGERED.
    /// </summary>
    /// <param name="current">
    /// The current value of the targeted controller.
    /// </param>
    /// <param name="previous">
    /// The previous value of the targeted controller.
    /// </param>
    /// <param name="difference">
    /// The value difference of the targeted controller.
    /// </param>
    /// <param name="adjustedDifference">
    /// The adjusted value difference of the targeted controller.
    /// This value is the difference value as if it took place over a
    /// certain time period, controlled by VisBaseController.mc_fTargetAdjustedDifferenceTime.  The
    /// default of this essientially indicates a frame rate of 60 fps to determine
    /// the adjusted difference.  This should be used for almost all difference
    /// calculations, as it is NOT frame rate dependent.
    /// </param>
    public override void OnTriggered(float current, float previous, float difference, float adjustedDifference)
    {
        //check if this should be a random value
        if (randomValue)
        {//get random value
            m_fTargetPropertyValue = UnityEngine.Random.Range(minPropertyValue, maxPropertyValue);
        }
        else
        {//get value from ranges
            //get the source value
            float value = current;
            if (controllerSourceValue == ControllerSourceValue.Previous)
            {
                value = previous;
            }
            else if (controllerSourceValue == ControllerSourceValue.Difference)
            {
                value = adjustedDifference;
            }

            //calc the property value
            m_fTargetPropertyValue = VisHelper.ConvertBetweenRanges(value,
                                                                    minControllerValue,
                                                                    maxControllerValue,
                                                                    minPropertyValue,
                                                                    maxPropertyValue,
                                                                    invertValue);
        }

        //check if the value needs to be limited
        if (float.IsPositiveInfinity(m_fCurrentPropertyValue))
        {//the current value is infinity, set instantly no matter what
            m_fCurrentPropertyValue = m_fTargetPropertyValue;
            SetProperty(m_fCurrentPropertyValue);
        }
        else if (limitIncreaseRate && m_fCurrentPropertyValue < m_fTargetPropertyValue)
        {//limit increase
            SetProperty(m_fCurrentPropertyValue);
        }
        else if (limitDecreaseRate && m_fCurrentPropertyValue > m_fTargetPropertyValue)
        {//limit decrease
            SetProperty(m_fCurrentPropertyValue);
        }
        else
        {//no limiting, set instantly
            m_fCurrentPropertyValue = m_fTargetPropertyValue;
            SetProperty(m_fCurrentPropertyValue);
        }
    }
Esempio n. 13
0
 private void Lbshapes_SelectionChanged(object _, SelectionChangedEventArgs scea)
 {
     spProperties.Children.Clear();
     if (scea.AddedItems.Count == 0)
     {
         spProperties.Children.Add(new TextBlock()
         {
             Foreground   = white,
             TextWrapping = TextWrapping.Wrap,
             Text         = "Kein Element ausgewählt"
         });
         return;
     }
     UIHelpers.VisualizationHelper.AddToSP(spProperties, VisHelper.VisualizeObject(scea.AddedItems[0]));
 }
    /// <summary>
    /// This is called when this data group is started.
    /// </summary>
    public void Start()
    {
        //validate the boost and cutoff for this data group.
        boost  = VisHelper.Validate(boost, 0.001f, 10000.0f, Defaults.boost, this, "boost", false);
        cutoff = VisHelper.Validate(cutoff, 0.001f, 10000.0f, Defaults.cutoff, this, "cutoff", false);

        //create all data containers for all data value types
        for (int i = 0; i < m_aoDataContainers.Length; i++)
        {
            m_aoDataContainers[i] = new VisDataContainer();
        }

        //make sure there is a vis manager assigned to this data group
        if (m_oVisManager != null)
        {
            //validate the frequency values and number of sub data groups.
            frequencyRangeEndIndex   = VisHelper.Validate(frequencyRangeEndIndex, 0, (int)m_oVisManager.windowSize, 0, this, "frequencyRangeEndIndex", true);
            frequencyRangeStartIndex = VisHelper.Validate(frequencyRangeStartIndex, 0, frequencyRangeEndIndex, 0, this, "frequencyRangeStartIndex", true);
            numberSubDataGroups      = VisHelper.Validate(numberSubDataGroups, 1, (frequencyRangeEndIndex - frequencyRangeStartIndex) + 1, 1, this, "numberSubDataGroups", true);

            //create sub groups
            int range     = (frequencyRangeEndIndex - frequencyRangeStartIndex) + 1;
            int increment = Mathf.RoundToInt(((float)range) / ((float)numberSubDataGroups));
            if (increment <= 0)
            {
                increment = 1;
            }
            int remainder = range - (increment * (range / increment));
            for (int i = frequencyRangeStartIndex; i <= frequencyRangeEndIndex - increment; i += increment)
            {
                //get the start and end index and create the sub group
                int startIndex = i;
                int endIndex   = i;
                m_oSubDataGroups.Add(new VisSubDataGroup(startIndex, endIndex));
            }

            //add the remainder onto the last sub group
            if (remainder > 0 && m_oSubDataGroups.Count > 0)
            {
                m_oSubDataGroups[m_oSubDataGroups.Count - 1].frequencyRangeEndIndex += remainder;
            }
        }
        else
        {
            //send warning that there is no vis manager.
            Debug.LogError("This data group must have an assigned VisManager.");
        }
    }
Esempio n. 15
0
        /// <summary>
        /// Creates a nice title depending on the setting
        /// </summary>
        /// <param name="visType"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        private static string GetRetrospectionTitle(VisType visType, DateTimeOffset date)
        {
            switch (visType)
            {
            case VisType.Day:
                return("Your Retrospection for the " + date.Date.ToShortDateString());

            case VisType.Week:
                return(string.Format(CultureInfo.InvariantCulture, "Your Retrospection for Week {0} ({1} - {2})",
                                     DateTimeHelper.GetWeekOfYear_Iso8601(date.Date),
                                     DateTimeHelper.GetFirstDayOfWeek_Iso8801(date.Date).Date.ToShortDateString(),
                                     DateTimeHelper.GetLastDayOfWeek_Iso8801(date.Date).Date.ToShortDateString()));
            }

            return(VisHelper.Error("Retrospection not supported!"));
        }
Esempio n. 16
0
        private string CreateDashboardItem(IVisualization vis, DateTimeOffset date)
        {
            try
            {
                var feedbackButtons = FeedbackThumbs.GetInstance().GetFeedbackThumbsUpDown(vis, date);
                var chartTitle      = VisHelper.FormatChartTitle(vis.Title);
                var html            = vis.GetHtml();

                var itemTemplate = "<div class='item {3}'>{0}{1}{2}</div>";
                return(string.Format(CultureInfo.InvariantCulture, itemTemplate, feedbackButtons, chartTitle, html, vis.Size));
            }
            catch (Exception e)
            {
                Logger.WriteToLogFile(e);
                return(VisHelper.Error(string.Format(CultureInfo.InvariantCulture, "<div id='item {2}'>An error occurred when creating the visualization: '{0}'.</div>", vis.Title, vis.Size)));
            }
        }
Esempio n. 17
0
        /// <summary>
        /// Returns a dictionary with an input-level like data set for each interval (Settings.UserInputVisMinutesInterval)
        /// (new version, 2.0)
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        internal static Dictionary <DateTime, int> GetUserInputTimelineData_v2(DateTimeOffset date)
        {
            var dto = new Dictionary <DateTime, int>();

            // prepare Dictionary
            VisHelper.PrepareTimeAxis(date, dto, Settings.UserInputVisMinutesInterval);

            // get user input data (aggregate)
            try
            {
                var query = "SELECT tsStart, tsEnd, keyTotal, clickTotal, scrollDelta, movedDistance FROM " + Settings.DbTableUserInput_v2 + " WHERE STRFTIME('%s', DATE(time))==STRFTIME('%s', DATE('" + date.Date.ToString("u", CultureInfo.InvariantCulture) + "'));";
                var table = Database.GetInstance().ExecuteReadQuery(query);

                foreach (DataRow row in table.Rows)
                {
                    try
                    {
                        var time = DateTime.Parse((string)row["tsStart"], CultureInfo.InvariantCulture);
                        time = time.AddSeconds(-time.Second); // nice seconds

                        // find 10 minutes interval
                        time = DateTimeHelper.RoundUp(time, TimeSpan.FromMinutes(Settings.UserInputVisMinutesInterval));

                        // add values
                        if (dto.ContainsKey(time))
                        {
                            var keystrokes          = (long)row["keyTotal"];
                            var mouseClicks         = (long)row["clickTotal"];
                            var mouseScrollDistance = (long)row["scrollDelta"];
                            var mouseMoves          = (long)row["movedDistance"];

                            dto[time] += CalculateUserInputLevel(keystrokes, mouseClicks, mouseScrollDistance, mouseMoves);
                        }
                    }
                    catch { }
                }
                table.Dispose();
            }
            catch (Exception e)
            {
                Logger.WriteToLogFile(e);
            }

            return(dto);
        }
Esempio n. 18
0
        public override string GetHtml()
        {
            var html = string.Empty;

            List <Tuple <DateTime, int> > values = DatabaseConnector.GetStepsPerTimeFraction(DateTimeHelper.GetFirstDayOfWeek_Iso8801(_date), DateTimeHelper.GetLastDayOfWeek_Iso8801(_date), 24 * 60);

            if (values.Count <= 1)
            {
                html += VisHelper.NotEnoughData();
                return(html);
            }

            //HTML
            html += "<div id='chart' height=20em, width=50em, style='align: center'></div>";
            html += "<p style='text-align: center; font-size: 0.66em;'>Hint: Visualizes your steps per day. For more detailed information, visit: <a href='http://fitbit.com' target=_blank>fitbit.com</a>. (Last synced: " + DatabaseConnector.GetLastTimeSynced() + ").</p>";

            return(html);
        }
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var workTimeData = GetWorkTimeData();

            if (workTimeData.Where(i => i.Value.Item1 > 0).Count() < 1)
            {
                return(VisHelper.NotEnoughData());
            }

            /////////////////////
            // HTML
            /////////////////////
            html += "<div id='" + VisHelper.CreateChartHtmlTitle(Title) + "' style='height:85%;' align='center'></div>";


            /////////////////////
            // JS
            /////////////////////
            var totalTimespentData  = workTimeData.Aggregate("", (current, p) => current + (Math.Round(p.Value.Item1, 1) + ", ")).Trim().TrimEnd(',');
            var timeSpentActiveData = workTimeData.Aggregate("", (current, p) => current + (Math.Round(p.Value.Item2, 1) + ", ")).Trim().TrimEnd(',');
            var formattedXAxis      = workTimeData.Aggregate("", (current, p) => current + ("'" + DateTimeHelper.GetShortestDayName(p.Key) + "', ")).Trim().TrimEnd(',');

            var totalTimespentName  = "at work in total (hours)";
            var timeSpentActiveName = "active at the computer (hours)";

            var data       = "columns: [ ['" + totalTimespentName + "', " + totalTimespentData + "], ['" + timeSpentActiveName + "', " + timeSpentActiveData + "] ], type: 'bar' ";
            var bar        = "width: { ratio: 0.5 }";
            var colors     = "'" + totalTimespentName + "' : '" + Shared.Settings.RetrospectionColorHex + "', '" + timeSpentActiveName + "' : '" + Shared.Settings.DarkGrayColorHex + "'";
            var axis       = "x: { type: 'category', categories: [ " + formattedXAxis + " ] }, y: { max: " + workTimeData.Max(i => i.Value.Item1) + " }";
            var parameters = " bindto: '#" + VisHelper.CreateChartHtmlTitle(Title) + "', data: { " + data + " }, bar: { " + bar + " }, colors: { " + colors + " }, axis: { " + axis + " }, padding: { left: 20, right: 0, bottom: 0, top: 0}, grid: { y: { show: true } }, legend: { show: true } ";

            html += "<script type='text/javascript'>";
            html += "var " + VisHelper.CreateChartHtmlTitle(Title) + " = c3.generate({ " + parameters + " });";
            html += "</script>";

            return(html);
        }
    /// <summary>
    /// This function sets up this VisManager.
    /// </summary>
    public void Start()
    {
        //validate debug variables
        debugSpectrumBarWidth    = VisHelper.Validate(debugSpectrumBarWidth, 1, 1000, Defaults.debugSpectrumBarWidth, this, "debugSpectrumBarWidth", false);
        debugSpectrumBarHeight   = VisHelper.Validate(debugSpectrumBarHeight, 1, 1000, Defaults.debugSpectrumBarHeight, this, "debugSpectrumBarHeight", false);
        debugRawAudioBarHeight   = VisHelper.Validate(debugRawAudioBarHeight, 1, 1000, Defaults.debugRawAudioBarHeight, this, "debugRawAudioBarHeight", false);
        debugDataGroupBarWidth   = VisHelper.Validate(debugDataGroupBarWidth, 1, 1000, Defaults.debugDataGroupBarWidth, this, "debugDataGroupBarWidth", false);
        debugDataGroupBarHeight  = VisHelper.Validate(debugDataGroupBarHeight, 1, 1000, Defaults.debugDataGroupBarHeight, this, "debugDataGroupBarHeight", false);
        debugControllerBarWidth  = VisHelper.Validate(debugControllerBarWidth, 1, 1000, Defaults.debugControllerBarWidth, this, "debugControllerBarWidth", false);
        debugControllerBarHeight = VisHelper.Validate(debugControllerBarHeight, 1, 1000, Defaults.debugControllerBarHeight, this, "debugControllerBarHeight", false);
        debugSeparation          = VisHelper.Validate(debugSeparation, 0, 1000, Defaults.debugSeparation, this, "debugSeparation", false);

        //Create the array to hold the audio data and initialize them
        m_afSpectrumData  = new float[(int)windowSize];
        m_afRawAudioData  = new float[(int)windowSize];
        m_afAuxiliaryData = new float[(int)windowSize];
        for (int i = 0; i < (int)windowSize; i++)
        {
            m_afSpectrumData[i]  = 0.0f;
            m_afRawAudioData[i]  = 0.0f;
            m_afAuxiliaryData[i] = 0.0f;
        }

        //try to load 1x1white texture
        if (debugTexture == null)
        {
            debugTexture = (Texture)Resources.Load("1x1White");
        }

        //Display a warning if no audio source was found.
        if (audioSource == null)
        {
            Debug.LogWarning("A VisManager should have an Audio Source assigned to it so it only listens to the specified music. " +
                             "This manager will now default to using the static Audio Listener, which contains ALL audio playing " +
                             "in the game.  This Audio Listener does not work near as well as listening directly to an Audio Source, " +
                             "so it is NOT recommended.");
            m_bUseAudioListener = true;
        }

        CalculateFrequencyResolution();
    }
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var averageProductivityPerDay = GetAverageProductivityPerDay();

            if (NotEnoughDataSets(averageProductivityPerDay))
            {
                html += VisHelper.NotEnoughData("It is not possible to give you insights into your productivity as you didn't fill out the pop-up often enough or didn't work. Try to fill it out at least 3 times per day.");
                return(html);
            }

            /////////////////////
            // HTML
            /////////////////////
            html += "<div id='" + VisHelper.CreateChartHtmlTitle(Title) + "' style='height:80%;' align='center'></div>";


            /////////////////////
            // JS
            /////////////////////
            var productivityFormattedData = averageProductivityPerDay.Aggregate("", (current, p) => current + (Math.Round(p.Value, 1) + ", ")).Trim().TrimEnd(',');
            var formattedXAxis            = averageProductivityPerDay.Aggregate("", (current, p) => current + ("'" + DateTimeHelper.GetShortestDayName(p.Key) + "', ")).Trim().TrimEnd(',');

            var data       = "columns: [ ['Average Productivity', " + productivityFormattedData + "] ], type: 'bar' ";
            var bar        = "width: { ratio: 0.5 }";
            var colors     = "'Average Productivity' : '" + Shared.Settings.RetrospectionColorHex + "'";
            var axis       = "x: { type: 'category', categories: [ " + formattedXAxis + " ] }, y: { max: 7, min: 1, tick: { values: [ 1, 2, 3, 4, 5, 6, 7 ] } }";
            var parameters = " bindto: '#" + VisHelper.CreateChartHtmlTitle(Title) + "', data: { " + data + " }, bar: { " + bar + " }, colors: { " + colors + " }, axis: { " + axis + " }, padding: { left: 20, right: 0, bottom: 0, top: 0}, grid: { y: { show: true } }, legend: { show: false } ";


            html += "<script type='text/javascript'>";
            html += "var " + VisHelper.CreateChartHtmlTitle(Title) + " = c3.generate({ " + parameters + " });";
            html += "</script>";

            return(html);
        }
Esempio n. 22
0
    /// <summary>
    /// This is called when this component is started.
    /// </summary>
    public override void Start()
    {
        base.Start();

        maxControllerValue = VisHelper.Validate(maxControllerValue, -1000000.0f, 1000000.0f, Defaults.maxControllerValue, this, "maxControllerValue", false);
        minControllerValue = VisHelper.Validate(minControllerValue, -1000000.0f, maxControllerValue, Mathf.Min(Defaults.minControllerValue, maxControllerValue), this, "minControllerValue", false);
        maxPropertyValue   = VisHelper.Validate(maxPropertyValue, -1000000.0f, 1000000.0f, Defaults.maxPropertyValue, this, "maxPropertyValue", false);
        minPropertyValue   = VisHelper.Validate(minPropertyValue, -1000000.0f, maxPropertyValue, Mathf.Min(Defaults.minPropertyValue, maxPropertyValue), this, "minPropertyValue", false);
        increaseRate       = VisHelper.Validate(increaseRate, 0.00001f, 10000.0f, Defaults.increaseRate, this, "increaseRate", false);
        decreaseRate       = VisHelper.Validate(decreaseRate, 0.00001f, 10000.0f, Defaults.decreaseRate, this, "decreaseRate", false);

        //check if return to rest is set
        if (returnToRest)
        {
            //make sure either limitting flag is checked
            if (!limitIncreaseRate && !limitDecreaseRate)
            {//warn and set to false
                Debug.LogWarning("If \"Return to Rest\" is true, you must have \"Limit Increase Rate\" or \"Limit Decrease Rate\" set to true. Resetting it to false!");
                returnToRest = false;
            }
        }
    }
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var orderedTimelineList = Queries.GetDayTimelineData(_date);

            /////////////////////
            // data cleaning
            /////////////////////

            // show message if not enough data
            if (orderedTimelineList.Count <= 3) // 3 is the minimum number of input-data-items
            {
                html += VisHelper.NotEnoughData(Dict.NotEnoughData);
                return(html);
            }

            // remove first + last items if IDLE
            if (orderedTimelineList.First().ActivityCategory == ActivityCategory.Idle)
            {
                orderedTimelineList.Remove(orderedTimelineList.First());
            }
            if (orderedTimelineList.Last().ActivityCategory == ActivityCategory.Idle)
            {
                orderedTimelineList.Remove(orderedTimelineList.Last());
            }

            /////////////////////
            // Create HTML
            /////////////////////

            html += GetActivityVisualizationContent(orderedTimelineList);

            return(html);
        }
Esempio n. 24
0
        private static void Main(string[] args)
        {
            bool compile = args.Any(x => x == "-c");
            bool clean   = args.Any(x => x == "-clean");
            bool run     = args.Any(x => x == "-r");

            FirstSetup.Start();

            string output = null;

            output = compile ? VisHelper.Compile(clean) : FirstSetup.DefaultFile;

            if (run)
            {
                if (output == null)
                {
                    Console.WriteLine($"Output file '{output}' not found.");
                }

                VisHelper.Default(output).Run();
            }

            FirstSetup.End(EndOptions.Default);
        }
        public override string GetHtml()
        {
            var html = string.Empty;

            SleepVisualizationEntry value = DatabaseConnector.GetSleepDataForDay(DateTimeHelper.GetStartOfDay(_date), DateTimeHelper.GetEndOfDay(_date));

            if (value == null)
            {
                html += VisHelper.NotEnoughData();
                return(html);
            }

            //HTML
            html += "<div id='chart' style='align: center; font-size: 1.15em;'>";
            html += "<p><b>Start:</b> " + value.StartTime.ToString(Settings.FORMAT_TIME) + "<span style='padding-left: 2em;'><b>End:</b> " + value.StartTime.AddMinutes(value.SleepDuration + value.AwakeDuration + value.RestlessDuration + value.AwakeAfterWakeUp).ToString(Settings.FORMAT_TIME) + "</span><span style='padding-left: 2em;'><b>Efficiency:</b> " + value.Efficiency + "%</span></p>";
            html += "<p><b>Slept for:</b> " + DurationToTime(value.SleepDuration) + "</p>";
            html += "<p><b>Time in bed after wakeup:</b> " + value.AwakeAfterWakeUp + " minutes</p>";
            html += "<p><b>Awake:</b> " + value.AwakeCount + " time(s). (Total duration: " + value.AwakeDuration + " minutes" + ")</p>";
            html += "<p><b>Restless:</b> " + value.RestlessCount + " time(s). (Total duration: " + value.RestlessDuration + " minutes" + ")</p>";
            html += "</div>";
            html += "<p style='text-align: center; font-size: 0.66em;'>Hint: Visualizes your sleep stats for the chosen day. For more detailed information,<br>visit: <a href='http://fitbit.com' target=_blank>fitbit.com</a>. (Last synced: " + DatabaseConnector.GetLastTimeSynced() + ").</p>";

            return(html);
        }
Esempio n. 26
0
 public virtual string GetHtml()
 {
     return(VisHelper.Error("Not yet implemented"));
 }
Esempio n. 27
0
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////

            // get the latest stored email entry
            var emailsSnapshotResult = Queries.GetEmailsSnapshot(_date.Date);
            var inbox          = emailsSnapshotResult.Item2;
            var inboxUnread    = emailsSnapshotResult.Item3;
            var sent           = emailsSnapshotResult.Item4;
            var received       = emailsSnapshotResult.Item5;
            var receivedUnread = emailsSnapshotResult.Item6;

            var isToday            = (_date.Date == DateTime.Now.Date);
            var lastUpdatedMinsAgo = Math.Abs((DateTime.Now - emailsSnapshotResult.Item1).TotalMinutes);

            // if database entry is outdated or not there, create a live API call and override entries
            if (emailsSnapshotResult.Item1 == DateTime.MinValue ||                           // no emails stored yet
                (isToday && lastUpdatedMinsAgo > Settings.SaveEmailCountsIntervalInMinutes)) // request is for today and saved results are too old // could not fetch sent emails
            {
                // create and save a new email snapshot (inbox, sent, received)
                var res = Queries.CreateEmailsSnapshot(_date.Date, false);
                inbox          = res.Item1;
                inboxUnread    = res.Item2;
                sent           = res.Item3;
                received       = res.Item4;
                receivedUnread = res.Item5;
            }

            // error (only if no data at all)
            if (sent < 0 && (received < 0 || receivedUnread < 0) && inbox < 0 && inboxUnread < 0)
            {
                return(VisHelper.NotEnoughData(Dict.NotEnoughData));
            }

            // get averages over last 2 months
            var averagesSnapshot = Queries.GetEmailsSnapshotAverages(60);


            /////////////////////
            // HTML
            /////////////////////

            html += "<table>";
            if (sent > -1)
            {
                html += "<tr><td><strong style='font-size:2.5em; color:#007acc;'>" + sent + "</strong></td><td>emails sent" + FormatAverage(sent, averagesSnapshot.Item3) + "</td></tr>";
            }
            if (received > -1 && receivedUnread > -1)
            {
                html += "<tr><td><strong style='font-size:2.5em; color:#007acc;'>" + (received - receivedUnread) + "</strong></td><td>emails received that are read" + FormatAverage((received - receivedUnread), averagesSnapshot.Item4 - averagesSnapshot.Item5) + "</td></tr>";
            }
            if (received > -1 && receivedUnread > -1)
            {
                html += "<tr><td><strong style='font-size:2.5em; color:#007acc;'>" + receivedUnread + "</strong></td><td>emails received that are unread" + FormatAverage(receivedUnread, averagesSnapshot.Item5) + "</td></tr>";
            }
            if (inbox > -1)
            {
                html += "<tr><td><strong style='font-size:2.5em; color:#007acc;'>" + inbox + "</strong></td><td>emails in your inbox" + FormatAverage(inbox, averagesSnapshot.Item1) + "</td></tr>";
            }
            if (inboxUnread > -1)
            {
                html += "<tr><td><strong style='font-size:2.5em; color:#007acc;'>" + inboxUnread + "</strong></td><td>unread emails in your inbox" + FormatAverage(inboxUnread, averagesSnapshot.Item2) + "</td></tr>";
            }
            html += "</table>";

            return(html);
        }
Esempio n. 28
0
        public override string GetHtml()
        {
            var html = string.Empty;

            //Get Data
            List <Tuple <DateTime, double, double> > values = DatabaseConnector.GetPolarValuesForDay(_date);

            if (values.Count <= 3)
            {
                html += VisHelper.NotEnoughData("It is not possible to give you insights because there is not enough biometric data available.");
                return(html);
            }

            // CSS
            html += "<style type='text/css'>";
            html += ".c3-line { stroke-width: 2px; }";
            html += ".c3-grid text, c3.grid line { fill: black; }";
            html += ".axis path, .axis line {fill: none; stroke: black; stroke-width: 1; shape-rendering: crispEdges;}";
            html += "</style>";

            //HTML
            html += "<div id='chart' style='align: center'></div>";
            html += "<p style='text-align: center; font-size: 0.66em;'>Hint: Visualizes your heart rate (HR) and your interbeat interval (RMSSD). (Last time synced with BLE device: " + DatabaseConnector.GetLastTimeSynced().ToString(CultureInfo.InstalledUICulture) + ")</p>";

            //JS
            html += "<script>";
            html += "var actualHeight = document.getElementsByClassName('item Wide')[0].offsetHeight;";
            html += "var actualWidth = document.getElementsByClassName('item Wide')[0].offsetWidth;";
            html += "var margin = {top: 30, right: 30, bottom: 30, left: 30}, width = (actualWidth * 0.97)- margin.left - margin.right, height = (actualHeight * 0.73) - margin.top - margin.bottom;";
            html += "var parseDate = d3.time.format('%Y-%m-%d %H:%M').parse;";

            html += GetDataAsJSString(values);

            html += "var x = d3.time.scale().range([0, width]);";
            html += "var y0 = d3.scale.linear().range([height, 0]);";
            html += "var y1 = d3.scale.linear().range([height, 0]);";

            if (GetDurationInHours(values) >= 12)
            {
                html += "var xAxis = d3.svg.axis().scale(x).orient('bottom').ticks(d3.time.hours, 2).tickFormat(d3.time.format('%H:%M'));";
            }
            else if (GetDurationInHours(values) > 3)
            {
                html += "var xAxis = d3.svg.axis().scale(x).orient('bottom').ticks(d3.time.hours, 1).tickFormat(d3.time.format('%H:%M'));";
            }
            else
            {
                html += "var xAxis = d3.svg.axis().scale(x).orient('bottom').ticks(d3.time.minutes, 15).tickFormat(d3.time.format('%H:%M'));";
            }

            html += "var yAxisLeft = d3.svg.axis().scale(y0).orient('left').ticks(5);";
            html += "var yAxisRight = d3.svg.axis().scale(y1).orient('right').ticks(5);";

            html += "var valueLine1 = d3.svg.line().interpolate('basis').defined(function(d) {return d.hr != null; }).x(function(d) {return x(d.ts); }).y(function(d) { return y0(d.hr); });";
            html += "var valueLine2 = d3.svg.line().interpolate('basis').defined(function(d) {return d.rmssd != null; }).x(function(d) {return x(d.ts); }).y(function(d) { return y1(d.rmssd); });";

            html += "var svg = d3.select('#chart').append('svg').attr('width', width + margin.left + margin.righ).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');";

            html += "x.domain(d3.extent(data, function(d) { return d.ts}));";
            html += "var hrValues = data.map(function(o){return o.hr;}).filter(function(val) {return val !== null});";
            html += "var rmssdValues = data.map(function(o){return o.rmssd;}).filter(function(val) {return val !== null});";

            html += "y0.domain([d3.min(hrValues) * 0.95, d3.max(data, function(d) {return Math.max(d.hr);}) * 1.01]);";
            html += "y1.domain([d3.min(rmssdValues) * 0.95, d3.max(data, function(d) {return Math.max(d.rmssd);}) * 1.01]);";

            html += "svg.append('path').style('stroke', '" + Shared.Settings.RetrospectionColorHex + "').attr('d', valueLine1(data)).attr('fill', 'none');";
            html += "svg.append('path').style('stroke', '#ff7f0e').attr('d', valueLine2(data)).attr('fill', 'none');";

            if (HasAtLeastOneValidHRValue(values))
            {
                html += "svg.append('svg:line').style('stroke', '" + Shared.Settings.RetrospectionColorHex + "').attr('x1', 0).attr('x2', width).attr('y1', y0(" + GetAverageHeartrate(values) + ")).attr('y2', y0(" + GetAverageHeartrate(values) + ")).style('stroke-dasharray', ('12, 9')).style('opacity', 0.4);";
            }

            if (HasAtLeastOneValidRMSSDValue(values))
            {
                html += "svg.append('svg:line').style('stroke', '#ff7f0e').attr('x1', 0).attr('x2', width).attr('y1', y1(" + GetAverageRMSSD(values) + ")).attr('y2', y1(" + GetAverageRMSSD(values) + ")).style('stroke-dasharray', ('12, 9')).style('opacity', 0.4);";
            }

            html += "svg.append('g').attr('class', 'x axis').attr('transform', 'translate(0,' + height + ')').call(xAxis);";
            html += "svg.append('g').attr('class', 'y axis').style('fill', '" + Shared.Settings.RetrospectionColorHex + "').call(yAxisLeft);";
            html += "svg.append('g').attr('class', 'y axis').attr('transform', 'translate(' + width + ' ,0)').style('fill', '#ff7f0e').call(yAxisRight);";

            html += "svg.append('text').attr('x', 0).attr('y', -10).style('text-anchor', 'middle').text('HR');";
            html += "svg.append('text').attr('x', width).attr('y', -10).style('text-anchor', 'middle').text('RMSSD');";

            html += "</script>";

            return(html);
        }
Esempio n. 29
0
        public override string GetHtml()
        {
            var html = string.Empty;

            //Get Data
            var hrValues    = DatabaseConnector.GetHRValuesForWeek(_date);
            var rmssdValues = DatabaseConnector.GetRMSSDValuesForWeek(_date);

            if (hrValues.Count < Settings.NUMBER_OF_BUCKETS || rmssdValues.Count < Settings.NUMBER_OF_BUCKETS)
            {
                html += VisHelper.NotEnoughData("It is not possible to give you insights because there is not enough biometric data available.");
                return(html);
            }

            string[] dayNames = CultureInfo.InstalledUICulture.DateTimeFormat.AbbreviatedDayNames;

            //CSS
            html += "<style type='text/css'>";
            html += ".c3-line { stroke-width: 2px; }";
            html += ".c3-grid text, c3.grid line { fill: black; }";
            html += "rect.bordered { stroke: #E6E6E6; stroke-width:2px; }";
            html += "text.mono { font-size: 7.5pt; fill: #888; }";
            html += "text.axis-workweek { fill: #000; }";
            html += "text.axis-worktime { fill: #000; }";
            html += ".tooltip {background-color: white; box-shadow: 4px 4px 4px #888888; -webkit-box-shadow:2px 3px 4px #888888;padding:2px;position:absolute;top:0px;left:0px;visibility:hidden;border: solid 1px black;border-radius:5px;}";
            html += ".dataset-button { padding:0.3125em; background-color:white; border:1px solid " + Shared.Settings.RetrospectionColorHex + "; color:" + Shared.Settings.RetrospectionColorHex + "; text-decoration:none; margin:5px auto; }";
            html += ".dataset-button-active { padding:0.3125em; background-color:" + Shared.Settings.RetrospectionColorHex + "; border:1px solid " + Shared.Settings.RetrospectionColorHex + "; color: white; text-decoration:none; margin:5px auto; }";
            html += ".dataset-button:hover { background-color:" + Shared.Settings.RetrospectionColorHex + "; border:1px solid " + Shared.Settings.RetrospectionColorHex + "; color:white; cursor: pointer; cursor: hand; }";
            html += "</style>";

            //HTML
            html += "<div id='chart'></div>";
            html += "<div id='dataset-picker' style='float: right;'></div>";
            html += "<p style='text-align: center; font-size: 0.66em;'>Hint: Visualizes your heart rate (HR) and your interbeat interval (RMSSD). (Last time synced with BLE device: " + DatabaseConnector.GetLastTimeSynced().ToString(CultureInfo.InstalledUICulture) + ")</p>";
            html += "<div id='dataDiv' class='tooltip'></div>";

            //JS
            html += "<script type='text/javascript'>";
            html += "var actualHeight = document.getElementsByClassName('item Wide')[0].offsetHeight;";
            html += "var actualWidth = document.getElementsByClassName('item Wide')[0].offsetWidth;";
            html += "var margin = { top: 20, right: 0, bottom: 0, left: 40 },";
            html += "width = (actualWidth * 0.95) - margin.left - margin.right,";
            html += "height = (actualHeight * 0.73) - margin.top - margin.bottom,";

            html += "gridSize = Math.floor(width / 24), legendElementWidth = gridSize * 2,";
            html += "buckets = " + Settings.NUMBER_OF_BUCKETS + ",";
            html += GetColorRangeAsJSString(Settings.NUMBER_OF_BUCKETS, Shared.Settings.RetrospectionColorHex);
            html += "days = ['" + dayNames[(int)DayOfWeek.Monday] + "', '" + dayNames[(int)DayOfWeek.Tuesday] + "', '" + dayNames[(int)DayOfWeek.Wednesday] + "', '" + dayNames[(int)DayOfWeek.Thursday] + "', '" + dayNames[(int)DayOfWeek.Friday] + "', '" + dayNames[(int)DayOfWeek.Saturday] + "', '" + dayNames[(int)DayOfWeek.Sunday] + "'],";
            html += "times = ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'];";

            html += "var svg = d3.select('#chart').append('svg')";
            html += ".attr('width', width + margin.left + margin.right)";
            html += ".attr('height', height + margin.top + margin.bottom)";
            html += ".append('g')";
            html += ".attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');";

            html += "var dayLabels = svg.selectAll('.dayLabel')";
            html += ".data(days)";
            html += ".enter().append('text')";
            html += ".text(function(d) { return d; })";
            html += ".attr('x', 0)";
            html += ".attr('y', function(d, i) { return i * gridSize; })";
            html += ".style('text-anchor', 'end')";
            html += ".attr('transform', 'translate(-6,' + gridSize / 1.5 + ')')";
            html += ".attr('class', function(d, i) { return ((i >= 0 && i <= 4) ? 'dayLabel mono axis axis-workweek' : 'dayLabel mono axis'); });";

            html += "var timeLabels = svg.selectAll('.timeLabel')";
            html += ".data(times)";
            html += ".enter().append('text')";
            html += ".text(function(d) { return d; })";
            html += ".attr('x', function(d, i) { return i * gridSize; })";
            html += ".attr('y', 0)";
            html += ".style('text-anchor', 'middle')";
            html += ".attr('transform', 'translate(' + gridSize / 2 + ', -6)')";
            html += ".attr('class', function(d, i) { return ((i >= 7 && i <= 16) ? 'timeLabel mono axis axis-worktime' : 'timeLabel mono axis'); });";

            html += GetDataAsJSString(hrValues, "hrdata");
            html += GetDataAsJSString(rmssdValues, "rmssddata");

            html += "var heatmapChart = function(data) {";

            html += "var colorScale = d3.scale.quantize().domain([d3.min(data, function(d) { return d.value; }), buckets - 1, d3.max(data, function(d) { return d.value; })]).range(colors);";

            html += "svg.selectAll('.hour').remove();";
            html += "var cards = svg.selectAll('.hour').data(data, function(d) { return d.day + ':' + d.hour; });";
            html += "cards.enter().append('rect').attr('x', function(d) { return (d.hour - 1) * gridSize; }).attr('y', function(d) { return (d.day - 1) * gridSize; }).attr('rx', 4).attr('ry', 4).attr('class', 'hour bordered').attr('width', gridSize).attr('height', gridSize).style('fill', colors[0]).attr('data', function(d) { return d.value}).attr('onmouseover', 'showData(evt)').attr('onmouseout', 'hideData(evt)');";
            html += "cards.transition().duration(1000).style('fill', function(d) { return colorScale(d.value); });";
            html += "cards.exit().remove();";

            html += "svg.selectAll('.legend').remove();";
            html += "var legend = svg.selectAll('.legend').data(colorScale.range(), function(d) { return d; });";
            html += "legend.enter().append('g').attr('class', 'legend');";
            html += "legend.append('rect').attr('x', function(d, i) { return legendElementWidth * i; }).attr('y', height-15).attr('width', legendElementWidth).attr('height', gridSize / 2).style('fill', function(d, i) { return colors[i]; });";
            html += "legend.append('text').attr('class', 'mono').text(function(d) { var r = colorScale.invertExtent(d); return '≥ ' + d3.format('.2f')(r[0]); }).attr('x', function(d, i) { return legendElementWidth * i; }).attr('y', height - (0.5 * gridSize));";
            html += "legend.exit().remove();";
            html += "};";

            html += "heatmapChart(hrdata);";

            html += "d3.select('#dataset-picker').append('input').attr('type', 'button').attr('value', 'HR').attr('class', 'dataset-button-active').attr('id', 'hrbutton').on('click', function() {document.getElementById('rmssdbutton');document.getElementById('rmssdbutton').style.backgroundColor='White';document.getElementById('rmssdbutton').style.color='black';this.style.backgroundColor = '" + Shared.Settings.RetrospectionColorHex + "';this.style.color='white';heatmapChart(hrdata);});";
            html += "d3.select('#dataset-picker').append('input').attr('type', 'button').attr('value', 'RMSSD').attr('class', 'dataset-button').attr('id', 'rmssdbutton').on('click', function() {document.getElementById('hrbutton');document.getElementById('hrbutton').style.backgroundColor='White';document.getElementById('hrbutton').style.color='black';this.style.backgroundColor = '" + Shared.Settings.RetrospectionColorHex + "';this.style.color='white';heatmapChart(rmssddata);});";

            html += "function showData(evt) { var target = evt.target;  target.setAttribute('opacity', '.8');";
            html += "var x = evt.clientX;";
            html += "var y = evt.clientY;";
            html += "var offsetX = window.pageXOffset;";
            html += "var offsetY = window.pageYOffset;";
            html += "dataDiv.style.left = 10 + x + offsetX + 'px';";
            html += "dataDiv.style.top = 20 + y + offsetY + 'px';";
            html += "var data = target.getAttribute('data');";
            html += "var html = data;";
            html += "dataDiv.innerHTML = html;";
            html += "dataDiv.style.visibility = 'visible';";
            html += "}";

            html += "function hideData(evt) {";
            html += "dataDiv.style.visibility = 'hidden';";
            html += "var target = evt.target;";
            html += "target.removeAttribute('opacity');";
            html += "}";

            html += "</script>";
            return(html);
        }
Esempio n. 30
0
        public override string GetHtml()
        {
            var html = string.Empty;

            /////////////////////
            // fetch data sets
            /////////////////////
            var chartQueryResultsLocal = Queries.GetUserInputTimelineData_v2(_date);

            // if no user input data available, try to get it from the old data (V1 user input tracker)
            // TODO: remove at some point (when no one is using the old user-input tracker anymore)
            //if (chartQueryResultsLocal.Sum(i => i.Value) == 0)
            //{
            //    chartQueryResultsLocal = Queries.GetUserInputTimelineData_v1(_date);
            //}

            // 3 is the minimum number of input-data-items - else, it makes no sense to show a visualization
            if (chartQueryResultsLocal.Count < 3)
            {
                html += VisHelper.NotEnoughData(Dict.NotEnoughData);
                return(html);
            }

            /////////////////////
            // CSS
            /////////////////////
            html += "<style type='text/css'>";
            html += ".c3-line { stroke-width: 2px; }";
            html += ".c3-grid text, c3.grid line { fill: gray; }";
            html += "</style>";


            /////////////////////
            // HTML
            /////////////////////
            html += "<div id='" + VisHelper.CreateChartHtmlTitle(Title) + "' style='height:75%;' align='center'></div>";
            html += "<p style='text-align: center; font-size: 0.66em;'>Hint: Visualizes your active times, based on your keyboard and mouse input.</p>";


            /////////////////////
            // JS
            /////////////////////
            var ticks    = CalculateLineChartAxisTicks(_date);
            var timeAxis = chartQueryResultsLocal.Aggregate("", (current, a) => current + (DateTimeHelper.JavascriptTimestampFromDateTime(a.Key) + ", ")).Trim().TrimEnd(',');
            var userInputFormattedData = chartQueryResultsLocal.Aggregate("", (current, p) => current + (p.Value + ", ")).Trim().TrimEnd(',');
            var maxUserInput           = chartQueryResultsLocal.Max(i => i.Value);
            var avgUserInput           = chartQueryResultsLocal.Average(i => i.Value);

            const string colors     = "'User_Input_Level' : '" + Shared.Settings.RetrospectionColorHex + "'";
            var          data       = "x: 'timeAxis', columns: [['timeAxis', " + timeAxis + "], ['User_Input_Level', " + userInputFormattedData + " ] ], type: 'area', colors: { " + colors + " }, axis: { 'PerceivedProductivity': 'y' }";
            var          grid       = "y: { lines: [ { value: 0, text: 'not active' }, { value: " + avgUserInput + ", text: 'average activity today' }, { value: " + maxUserInput + ", text: 'max activity today' } ] } ";
            var          axis       = "x: { localtime: true, type: 'timeseries', tick: { values: [ " + ticks + "], format: function(x) { return formatDate(x.getHours()); }}  }, y: { show: false, min: 0 }";
            var          parameters = " bindto: '#" + VisHelper.CreateChartHtmlTitle(Title) + "', data: { " + data + " }, padding: { left: 0, right: 0, bottom: -10, top: 0}, legend: { show: false }, axis: { " + axis + " }, grid: { " + grid + " }, tooltip: { show: false }, point: { show: false }";

            // padding: { left: 0, right: 0 },

            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 " + VisHelper.CreateChartHtmlTitle(Title) + " = c3.generate({ " + parameters + " });"; // return x.getHours() + ':' + x.getMinutes();
            html += "</script>";

            return(html);
        }