Пример #1
0
        public static DenseVector Normalize0to1(this DenseVector data)
        {
            var d      = new DenseVector(data);
            var result = new DenseVector(d.Count);

            d.CopyTo(result);
            return((DenseVector)(result - d.Min()) / (d.Max() - d.Min()));
        }
Пример #2
0
        public static double[] NormalizeNeg1to1(this double[] data)
        {
            var d      = new DenseVector(data);
            var result = new DenseVector(d.Count);

            d.CopyTo(result);
            result = (DenseVector)(result - ((d.Max() + d.Min()) / 2)) / ((d.Max() - d.Min()) / 2);
            return(result.ToArray());
        }
Пример #3
0
        public static double[] Normalize0to1(this double[] data)
        {
            var returnData = new double[data.Length];
            var d          = new DenseVector(data);
            var result     = new DenseVector(d.Count);

            d.CopyTo(result);
            result = (DenseVector)(result - d.Min()) / (d.Max() - d.Min());
            return(result.ToArray());
        }
Пример #4
0
        private void CheckIfIsExtremum(DenseVector vector)
        {
            double actualMin = vector.Min();

            if (actualMin < MinValue)
            {
                MinValue = actualMin;
            }

            double actualMax = vector.Max();

            if (actualMax > MaxValue)
            {
                MaxValue = actualMax;
            }
        }
        public void Represent()
        {
            if ((dvScatterXSpace != null) && (dvScatterFuncValues != null))
            {
                if (theRepresentingFunctions.Count > 0)
                {
                    if (ForceFuncLimits)
                    {
                        double ySpaceGap = 0.2d * (ForcedFuncMaxValue - ForcedFuncMinValue);

                        overallFuncMax = ForcedFuncMaxValue + ySpaceGap;
                        overallFuncMin = ForcedFuncMinValue - ySpaceGap;
                    }
                    else
                    {
                        double ySpaceGap = 0.2d * (dvScatterFuncValues.Max() - dvScatterFuncValues.Min());

                        overallFuncMax = ((dvScatterFuncValues.Max() + ySpaceGap) > overallFuncMax)
                            ? (dvScatterFuncValues.Max() + ySpaceGap)
                            : (overallFuncMax);
                        overallFuncMin = ((dvScatterFuncValues.Min() - ySpaceGap) < overallFuncMin)
                            ? (dvScatterFuncValues.Min() - ySpaceGap)
                            : (overallFuncMin);
                    }

                    //double xSpaceGap = 0.2d * (dvScatterXSpace.Max() - dvScatterXSpace.Min());

                    //xSpaceMin = ((dvScatterXSpace.Min() - xSpaceGap) < xSpaceMin)
                    //    ? (dvScatterXSpace.Min() - xSpaceGap)
                    //    : (xSpaceMin);
                    //xSpaceMax = ((dvScatterXSpace.Max() + xSpaceGap) > xSpaceMax)
                    //    ? (dvScatterXSpace.Max() + xSpaceGap)
                    //    : (xSpaceMax);
                    xSpaceMin = ((dvScatterXSpace.Min()) < xSpaceMin)
                        ? (dvScatterXSpace.Min())
                        : (xSpaceMin);
                    xSpaceMax = ((dvScatterXSpace.Max()) > xSpaceMax)
                        ? (dvScatterXSpace.Max())
                        : (xSpaceMax);
                }
                else
                {
                    if (ForceFuncLimits)
                    {
                        double ySpaceGap = 0.2d * (ForcedFuncMaxValue - ForcedFuncMinValue);
                        overallFuncMax = ForcedFuncMaxValue + ySpaceGap;
                        overallFuncMin = ForcedFuncMinValue - ySpaceGap;
                    }
                    else
                    {
                        double ySpaceGap = 0.2d * (dvScatterFuncValues.Max() - dvScatterFuncValues.Min());
                        overallFuncMax = dvScatterFuncValues.Max() + ySpaceGap;
                        overallFuncMin = dvScatterFuncValues.Min() - ySpaceGap;
                    }

                    //double xSpaceGap = 0.2d * (dvScatterXSpace.Max() - dvScatterXSpace.Min());

                    //xSpaceMin = ((dvScatterXSpace.Min() - xSpaceGap) < xSpaceMin)
                    //    ? (dvScatterXSpace.Min() - xSpaceGap)
                    //    : (xSpaceMin);
                    //xSpaceMax = ((dvScatterXSpace.Max() + xSpaceGap) > xSpaceMax)
                    //    ? (dvScatterXSpace.Max() + xSpaceGap)
                    //    : (xSpaceMax);
                    xSpaceMin = ((dvScatterXSpace.Min()) < xSpaceMin)
                        ? (dvScatterXSpace.Min())
                        : (xSpaceMin);
                    xSpaceMax = ((dvScatterXSpace.Max()) > xSpaceMax)
                        ? (dvScatterXSpace.Max())
                        : (xSpaceMax);
                }
            }

            pictureWidth    = pbFunctionRepresentation.Width;
            pictureHeight   = pbFunctionRepresentation.Height;
            serviceSpaceGap = Convert.ToInt32(0.05d * Math.Min(pictureHeight, pictureWidth));
            theImage        = new Image <Bgr, Byte>(pictureWidth, pictureHeight, new Bgr(255, 255, 255));



            RepresentScatter();
            RepresentAnalytic();
        }
        private void RepresentAnalytic()
        {
            int xValuesCount = pictureWidth - (2 * serviceSpaceGap);// оставляем место на шкалу Y

            List <Point> rulerVertices = new List <Point>();

            rulerVertices.Add(new Point(serviceSpaceGap, pictureHeight - serviceSpaceGap));
            rulerVertices.Add(new Point(pictureWidth - serviceSpaceGap, pictureHeight - serviceSpaceGap));
            rulerVertices.Add(new Point(pictureWidth - serviceSpaceGap, serviceSpaceGap));
            rulerVertices.Add(new Point(serviceSpaceGap, serviceSpaceGap));
            theImage.DrawPolyline(rulerVertices.ToArray(), true, colorBlack, 2);

            DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func <int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin)));
            DenseVector parametersList = null;

            for (int i = 0; i < theRepresentingFunctions.Count; i++)
            {
                Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i];
                DenseVector currentParametersList = parameters[i];

                DenseVector dvFuncValues = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j])));
                double      funcMax      = dvFuncValues.Max();
                double      funcMin      = dvFuncValues.Min();
                if (!ForceFuncLimits)
                {
                    overallFuncMax = (funcMax > overallFuncMax) ? (funcMax) : (overallFuncMax);
                    overallFuncMin = (funcMin < overallFuncMin) ? (funcMin) : (overallFuncMin);
                }
            }



            #region Прописываем текстовые маркеры
            MCvFont theFont = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 1.0d, 1.0d);
            theFont.thickness = 1;
            double dMarkersCount = (double)(pictureHeight - (2 * serviceSpaceGap)) / 30.0d;
            dMarkersCount = (dMarkersCount > 10.0d) ? (10.0d) : (dMarkersCount);
            double dRulerValueGap = (overallFuncMax - overallFuncMin) / (double)dMarkersCount;
            //dRulerValueGap = (dRulerValueGap < 1.0d) ? (1.0d) : dRulerValueGap;
            int    deciGap          = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGap, 2.0d)));
            double rulerValueGap    = Math.Pow(2.0, (double)deciGap);
            double lowerMarkerValue = overallFuncMin - Math.IEEERemainder(overallFuncMin, rulerValueGap);
            lowerMarkerValue = (lowerMarkerValue < overallFuncMin) ? (lowerMarkerValue + rulerValueGap) : (lowerMarkerValue);
            double currentMarkerValue  = lowerMarkerValue;
            double nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - 2 * serviceSpaceGap) + serviceSpaceGap;
            while (nextYPositionDouble > serviceSpaceGap)
            {
                double        yPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - 2 * serviceSpaceGap) + serviceSpaceGap;
                int           yPosition       = Convert.ToInt32(Math.Round(yPositionDouble));
                LineSegment2D theLine         = new LineSegment2D(new Point(serviceSpaceGap, yPosition), new Point(serviceSpaceGap - 5, yPosition));
                Bgr           markerColor     = colorBlack;
                theImage.Draw(theLine, markerColor, 2);
                String message = currentMarkerValue.ToString();
                //theImage.Draw(message, new Point(2, yPosition), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1.0d, markerColor);
                theImage.Draw(message, ref theFont, new Point(2, yPosition), markerColor);
                currentMarkerValue += rulerValueGap;
                nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - 2 * serviceSpaceGap) + serviceSpaceGap;
            }

            double dMarkersCountX = (double)(pictureWidth - (2 * serviceSpaceGap)) / 30.0d;
            dMarkersCountX = (dMarkersCountX > 10.0d) ? (10.0d) : (dMarkersCountX);
            double dRulerValueGapX   = (xSpaceMax - xSpaceMin) / (double)dMarkersCountX;
            int    deciGapX          = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGapX, 2.0d)));
            double rulerValueGapX    = Math.Pow(2.0, (double)deciGapX);
            double lowerMarkerValueX = xSpaceMin - Math.IEEERemainder(xSpaceMin, rulerValueGapX);
            lowerMarkerValueX = (lowerMarkerValueX < xSpaceMin) ? (lowerMarkerValueX + rulerValueGapX) : (lowerMarkerValueX);
            double currentMarkerValueX = lowerMarkerValueX;
            double nextXPositionDouble = serviceSpaceGap + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - 2 * serviceSpaceGap);
            while (nextXPositionDouble < pictureWidth - serviceSpaceGap)
            {
                double        xPositionDouble = serviceSpaceGap + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - 2 * serviceSpaceGap);
                int           xPosition       = Convert.ToInt32(Math.Round(xPositionDouble));
                LineSegment2D theLine         = new LineSegment2D(new Point(xPosition, pictureHeight - serviceSpaceGap), new Point(xPosition, pictureHeight - serviceSpaceGap + 5));
                Bgr           markerColor     = colorBlack;
                theImage.Draw(theLine, markerColor, 2);
                String message = currentMarkerValueX.ToString();
                theImage.Draw(message, ref theFont, new Point(xPosition, pictureHeight - 10), markerColor);
                // theImage.Draw(message, new Point(xPosition, pictureHeight - 10), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1.0d, markerColor);
                currentMarkerValueX += rulerValueGapX;
                nextXPositionDouble  = serviceSpaceGap + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - 2 * serviceSpaceGap);
            }

            #endregion Прописываем текстовые маркеры



            double koeff = (pictureHeight - (2 * serviceSpaceGap)) / (overallFuncMax - overallFuncMin);

            for (int i = 0; i < theRepresentingFunctions.Count; i++)
            {
                Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i];
                DenseVector currentParametersList = parameters[i];

                double currFuncKoeff = koeff;
                if (scaleFunctionValuesToMax[i])
                {
                    DenseVector dvCurrFuncValues = DenseVector.Create(xValuesCount, j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j]));
                    double      currFuncMax      = dvCurrFuncValues.Max();
                    double      currFuncMin      = dvCurrFuncValues.Min();

                    currFuncKoeff = (pictureHeight - (2 * serviceSpaceGap)) / (currFuncMax - currFuncMin);
                }



                //DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func<int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin)));
                parametersList = null;
                DenseVector dvFuncValues     = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j])));
                Bgr         currentLineColor = lineColors[i];


                DenseVector xCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j => ((double)serviceSpaceGap + j)));
                DenseVector yCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j =>
                {
                    double pixValue = currFuncKoeff * (dvFuncValues[j] - overallFuncMin);
                    return(pictureHeight - serviceSpaceGap - pixValue);
                }));

                List <Point> funcRepresentationPoints = new List <Point>();
                for (int j = 0; j < xValuesCount; j++)
                {
                    if (double.IsNaN(yCoordinates[j]))
                    {
                        continue;
                    }
                    funcRepresentationPoints.Add(new Point(Convert.ToInt32(xCoordinates[j]), Convert.ToInt32(yCoordinates[j])));
                }
                theImage.DrawPolyline(funcRepresentationPoints.ToArray(), false, currentLineColor, 2);
            }


            ThreadSafeOperations.UpdatePictureBox(pbFunctionRepresentation, theImage.Bitmap, false);
        }
Пример #7
0
        private Image <Bgr, byte> FillGraphImage(Size imgSize)
        {
            string curDirPath = Directory.GetCurrentDirectory() + "\\logs\\";

            DirectoryInfo dirInfo = new DirectoryInfo(curDirPath);

            List <Dictionary <string, object> > lReadData = new List <Dictionary <string, object> >();

            if (defaultGraphsTimeSpan)
            {
                graphsTimeSpan = new Tuple <DateTime, DateTime>(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow);
            }

            GraphVariablesTypes currVarType = GraphVariablesTypes.none;

            if (rbtnPressureGraph.Checked)
            {
                currVarType = GraphVariablesTypes.Pressure;
            }
            if (rbtnAirTempGraph.Checked)
            {
                currVarType = GraphVariablesTypes.AirTemp;
            }
            if (rbtnWaterTempGraph.Checked)
            {
                currVarType = GraphVariablesTypes.WaterTemp;
            }
            if (rbtnWindSpeedGraph.Checked)
            {
                currVarType = GraphVariablesTypes.WindSpeed;
            }


            if ((fRenderer == null) || (!prevGraphsTimeSpan.Equals(graphsTimeSpan) || currVarType != prevGraphVariable))
            {
                fRenderer = new MultipleScatterAndFunctionsRepresentation(imgSize);
                switch (currVarType)
                {
                case GraphVariablesTypes.Pressure:
                {
                    currValueColor = new Bgr(Color.Blue);
                    break;
                }

                case GraphVariablesTypes.AirTemp:
                {
                    currValueColor = new Bgr(Color.Red);
                    break;
                }

                case GraphVariablesTypes.WaterTemp:
                {
                    currValueColor = new Bgr(Color.RoyalBlue);
                    break;
                }

                case GraphVariablesTypes.WindSpeed:
                {
                    currValueColor = new Bgr(Color.Gray);
                    break;
                }

                default:
                {
                    currValueColor = new Bgr(Color.Blue);
                    break;
                }
                }
            }
            else if (fRenderer != null)
            {
                if (fRenderer.TheImage.Size != imgSize)
                {
                    fRenderer.ResizeCanvas(imgSize);
                }
            }



            if (!prevGraphsTimeSpan.Equals(graphsTimeSpan))
            {
                IEnumerable <string> ncFileNames = Directory.EnumerateFiles(curDirPath,
                                                                            "IoffeVesselInfoStream-MeteoDataLog-*.nc",
                                                                            SearchOption.TopDirectoryOnly);
                foreach (string ncFileName in ncFileNames)
                {
                    Tuple <DateTime, DateTime> currFileDateTimeRange = null;
                    try
                    {
                        currFileDateTimeRange = ServiceTools.GetNetCDFfileTimeStampsRange(ncFileName);
                    }
                    catch (Exception ex)
                    {
                        #region report

#if DEBUG
                        ServiceTools.ExecMethodInSeparateThread(this, () =>
                        {
                            theLogWindow = ServiceTools.LogAText(theLogWindow,
                                                                 "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName +
                                                                 Environment.NewLine + "message: " + ex.Message + Environment.NewLine +
                                                                 ServiceTools.CurrentCodeLineDescription());
                        });
#else
                        ServiceTools.ExecMethodInSeparateThread(this, () =>
                        {
                            ServiceTools.logToTextFile(errorLogFilename,
                                                       "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName +
                                                       Environment.NewLine + "message: " + ex.Message + Environment.NewLine +
                                                       ServiceTools.CurrentCodeLineDescription(), true, true);
                        });
#endif

                        #endregion report
                    }

                    if (currFileDateTimeRange == null)
                    {
                        continue;
                    }

                    if ((currFileDateTimeRange.Item1 >= graphsTimeSpan.Item1) &&
                        (currFileDateTimeRange.Item1 <= graphsTimeSpan.Item2) ||
                        (currFileDateTimeRange.Item2 >= graphsTimeSpan.Item1) &&
                        (currFileDateTimeRange.Item2 <= graphsTimeSpan.Item2))
                    {
                        Dictionary <string, object> dictFileData = null;
                        try
                        {
                            dictFileData = NetCDFoperations.ReadDataFromFile(ncFileName);
                        }
                        catch (Exception ex)
                        {
                            #region report

#if DEBUG
                            ServiceTools.ExecMethodInSeparateThread(this, () =>
                            {
                                theLogWindow = ServiceTools.LogAText(theLogWindow,
                                                                     "an exception has been thrown during file reading: " + Environment.NewLine +
                                                                     ncFileName +
                                                                     Environment.NewLine + "message: " + ex.Message + Environment.NewLine +
                                                                     ServiceTools.CurrentCodeLineDescription());
                            });
#else
                            ServiceTools.ExecMethodInSeparateThread(this, () =>
                            {
                                ServiceTools.logToTextFile(errorLogFilename,
                                                           "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName +
                                                           Environment.NewLine + "message: " + ex.Message + Environment.NewLine +
                                                           ServiceTools.CurrentCodeLineDescription(), true, true);
                            });
#endif

                            #endregion report
                        }

                        if (dictFileData != null)
                        {
                            lReadData.Add(dictFileData);
                        }
                    }
                }


                foreach (Dictionary <string, object> currFileDataDict in lReadData)
                {
                    if (currFileDataDict == null)
                    {
                        continue;
                    }

                    string varNameDateTime = "DateTime";

                    List <long> currFileDateTimeLongTicksList =
                        new List <long>((currFileDataDict[varNameDateTime] as long[]));
                    List <DateTime> currFileDateTimeList =
                        currFileDateTimeLongTicksList.ConvertAll(longVal => new DateTime(longVal));

                    string           varNameMeteoData      = "MeteoData";
                    List <MeteoData> currFileMeteoDataList =
                        MeteoData.OfDenseMatrix(currFileDataDict[varNameMeteoData] as DenseMatrix);

                    if (tsMeteoDataForGraphs == null)
                    {
                        try
                        {
                            tsMeteoDataForGraphs = new TimeSeries <MeteoData>(currFileMeteoDataList, currFileDateTimeList,
                                                                              true);
                        }
                        catch (Exception ex)
                        {
                            #region report

#if DEBUG
                            ServiceTools.ExecMethodInSeparateThread(this, () =>
                            {
                                theLogWindow = ServiceTools.LogAText(theLogWindow,
                                                                     "couldn`t create timeseries: exception has been thrown" + Environment.NewLine +
                                                                     ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " +
                                                                     ex.Message);
                            });
#else
                            ServiceTools.ExecMethodInSeparateThread(this, () =>
                            {
                                ServiceTools.logToTextFile(errorLogFilename,
                                                           "couldn`t create timeseries: exception has been thrown" + Environment.NewLine +
                                                           ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " +
                                                           ex.Message, true, true);
                            });
#endif

                            #endregion report
                        }
                    }
                    else
                    {
                        try
                        {
                            tsMeteoDataForGraphs.AddSubseriaData(currFileMeteoDataList, currFileDateTimeList, true);
                        }
                        catch (Exception ex)
                        {
                            #region report

#if DEBUG
                            ServiceTools.ExecMethodInSeparateThread(this, () =>
                            {
                                theLogWindow = ServiceTools.LogAText(theLogWindow,
                                                                     "couldn`t create timeseries: exception has been thrown" + Environment.NewLine +
                                                                     ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " +
                                                                     ex.Message);
                            });
#else
                            ServiceTools.ExecMethodInSeparateThread(this, () =>
                            {
                                ServiceTools.logToTextFile(errorLogFilename,
                                                           "couldn`t create timeseries: exception has been thrown" + Environment.NewLine +
                                                           ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " +
                                                           ex.Message, true, true);
                            });
#endif

                            #endregion report
                        }
                    }
                }



                if (tsMeteoDataForGraphs == null)
                {
                    return(null);
                }

                tsMeteoDataForGraphs.SortByTimeStamps();
                tsMeteoDataForGraphs.RemoveDuplicatedTimeStamps();

                DateTime utcNow = DateTime.UtcNow;
                if (defaultGraphsTimeSpan)
                {
                    tsMeteoDataForGraphs.RemoveValues(dt => (utcNow - dt).TotalSeconds > 86400);
                }
                else
                {
                    tsMeteoDataForGraphs.RemoveValues(
                        dt => !((dt >= graphsTimeSpan.Item1) && (dt <= graphsTimeSpan.Item2)));
                }


                List <TimeSeries <MeteoData> > subSeriesBy1Minute =
                    tsMeteoDataForGraphs.SplitByTimeSpan(new TimeSpan(0, 1, 0));
                List <double>         lSubSeriesEntriesCount = subSeriesBy1Minute.ConvertAll(subs => (double)subs.Count);
                DescriptiveStatistics statsCounts            = new DescriptiveStatistics(lSubSeriesEntriesCount);
                aveMinuteEntriesCount = Convert.ToInt32(statsCounts.Mean);


                // = tsMeteoData.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds);
            }



            List <MeteoData> meteoDataList = tsMeteoDataForGraphs.DataValues;
            DateTime         maxDateTime   = tsMeteoDataForGraphs.TimeStamps.Max();



            if ((currVarType != prevGraphVariable) || !prevGraphsTimeSpan.Equals(graphsTimeSpan))
            {
                double        minVarValue         = 0.0d;
                double        maxVarValue         = 1.0d;
                List <double> currVarToShowValues = new List <double>();
                switch (currVarType)
                {
                case GraphVariablesTypes.Pressure:
                {
                    currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.pressure);

                    TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues,
                                                                            tsMeteoDataForGraphs.TimeStamps);
                    currVarTS.RemoveValues(dVal => dVal <= 900.0d);

                    currVarToShowValues = new List <double>(currVarTS.DataValues);
                    currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds);

                    fRenderer.yAxisValuesConversionToRepresentTicksValues =
                        new Func <double, string>(dVal => dVal.ToString("F1"));
                    break;
                }

                case GraphVariablesTypes.AirTemp:
                {
                    currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.airTemperature);

                    TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues,
                                                                            tsMeteoDataForGraphs.TimeStamps);
                    currVarTS.RemoveValues(dVal => ((dVal < -20.0d) || (dVal > 50.0d)));

                    currVarToShowValues = new List <double>(currVarTS.DataValues);
                    currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds);

                    fRenderer.yAxisValuesConversionToRepresentTicksValues =
                        new Func <double, string>(dVal => dVal.ToString("F2"));
                    break;
                }

                case GraphVariablesTypes.WaterTemp:
                {
                    currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.waterTemperature);

                    TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues,
                                                                            tsMeteoDataForGraphs.TimeStamps);
                    currVarTS.RemoveValues(dVal => ((dVal < -20.0d) || (dVal > 50.0d)));

                    currVarToShowValues = new List <double>(currVarTS.DataValues);
                    currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds);



                    fRenderer.yAxisValuesConversionToRepresentTicksValues =
                        new Func <double, string>(dVal => dVal.ToString("F2"));
                    break;
                }

                case GraphVariablesTypes.WindSpeed:
                {
                    currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.windSpeed);

                    TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues,
                                                                            tsMeteoDataForGraphs.TimeStamps);
                    currVarTS.RemoveValues(dVal => ((dVal < 0.0d) || (dVal > 50.0d)));

                    currVarToShowValues = new List <double>(currVarTS.DataValues);
                    currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds);

                    fRenderer.yAxisValuesConversionToRepresentTicksValues =
                        new Func <double, string>(dVal => dVal.ToString("F1"));
                    break;
                }

                default:
                    return(null);
                }

                dvVarValues = DenseVector.OfEnumerable(currVarToShowValues);
                dvVarValues = dvVarValues.Conv(Extensions.StandardConvolutionKernels.gauss, aveMinuteEntriesCount * 10);
            }



            fRenderer.dvScatterFuncValues.Add(dvVarValues);
            fRenderer.dvScatterXSpace.Add(DenseVector.OfEnumerable(currFileSecondsList));

            fRenderer.xAxisValuesConversionToRepresentTicksValues = (dValSec) =>
            {
                DateTime currDT = tsMeteoDataForGraphs.TimeStamps.Max().AddSeconds(dValSec);
                return(currDT.ToString("yyyy-MM-dd" + Environment.NewLine + "HH:mm"));
            };

            fRenderer.scatterLineColors.Add(currValueColor);
            fRenderer.scatterDrawingVariants.Add(SequencesDrawingVariants.polyline);
            fRenderer.xSpaceMin           = currFileSecondsList.Min();
            fRenderer.xSpaceMax           = currFileSecondsList.Max();
            fRenderer.overallFuncMin      = dvVarValues.Min();
            fRenderer.overallFuncMax      = dvVarValues.Max();
            fRenderer.fixSpecifiedMargins = true;

            fRenderer.Represent();

            Image <Bgr, byte> retImg = fRenderer.TheImage;

            // расположим надпись
            string strSign = "current value: " + dvVarValues.Last().ToString("F2");

            List <TextBarImage> textBarsCases = new List <TextBarImage>();

            TextBarImage tbimTopLeftSign = new TextBarImage(strSign, retImg);
            tbimTopLeftSign.PtSurroundingBarStart =
                new Point(fRenderer.LeftServiceSpaceGapX + tbimTopLeftSign.textHalfHeight,
                          fRenderer.TopServiceSpaceGapY + tbimTopLeftSign.textHalfHeight);
            textBarsCases.Add(tbimTopLeftSign);

            TextBarImage tbimBtmLeftSign = new TextBarImage(strSign, retImg);
            tbimBtmLeftSign.PtSurroundingBarStart = new Point(fRenderer.LeftServiceSpaceGapX + tbimBtmLeftSign.textHalfHeight,
                                                              retImg.Height - fRenderer.BtmServiceSpaceGapY - tbimBtmLeftSign.textHalfHeight - tbimBtmLeftSign.textHeight * 2);
            textBarsCases.Add(tbimBtmLeftSign);

            TextBarImage tbimTopRightSign = new TextBarImage(strSign, retImg);
            tbimTopRightSign.PtSurroundingBarStart =
                new Point(
                    retImg.Width - fRenderer.RightServiceSpaceGapX - tbimTopRightSign.textHalfHeight -
                    tbimTopRightSign.textBarSize.Width, fRenderer.TopServiceSpaceGapY + tbimTopLeftSign.textHalfHeight);
            textBarsCases.Add(tbimTopRightSign);

            TextBarImage tbimBtmRightSign = new TextBarImage(strSign, retImg);
            tbimBtmRightSign.PtSurroundingBarStart =
                new Point(
                    retImg.Width - fRenderer.RightServiceSpaceGapX - tbimBtmRightSign.textHalfHeight -
                    tbimBtmRightSign.textBarSize.Width,
                    retImg.Height - fRenderer.BtmServiceSpaceGapY - tbimBtmRightSign.textHalfHeight -
                    tbimBtmRightSign.textHeight * 2);
            textBarsCases.Add(tbimBtmRightSign);

            textBarsCases.Sort((case1, case2) => (case1.SubImageInTextRect.CountNonzero().Sum() > case2.SubImageInTextRect.CountNonzero().Sum()) ? 1 : -1);

            MCvFont theFont = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 2.0d, 2.0d)
            {
                thickness = 2,
            };
            // retImg.Draw(strSign, textBarsCases[0].ptTextBaselineStart, Emgu.CV.CvEnum.FontFace.HersheyPlain, 2.0d, new Bgr(Color.Green), 2);
            retImg.Draw(strSign, ref theFont, textBarsCases[0].ptTextBaselineStart, new Bgr(Color.Green));
            retImg.Draw(textBarsCases[0].rectSurroundingBar, new Bgr(Color.Green), 2);

            prevGraphsTimeSpan = graphsTimeSpan;
            prevGraphVariable  = currVarType;

            return(retImg);
        }
        private void RepresentAnalytic()
        {
            #region Прописываем текстовые маркеры

            #region Y

            //MCvFont theFont = new MCvFont(FONT.CV_FONT_HERSHEY_PLAIN, 1.0d, 1.0d);
            //theFont.thickness = 1;

            // замерим высоту подписей по X по значению в минимуме

            string       strMinXvalueMarker     = (xAxisValuesConversionToRepresentTicksValues == null)?(xSpaceMin.ToString()) :(xAxisValuesConversionToRepresentTicksValues(xSpaceMin));
            TextBarImage minXvalueMarkerTextBar = new TextBarImage(strMinXvalueMarker,
                                                                   new Image <Bgr, byte>(new Size(pictureWidth, pictureHeight)));
            int barHeight = minXvalueMarkerTextBar.textBarSize.Height;
            if (btmServiceSpaceGapY < 1.5 * barHeight)
            {
                btmServiceSpaceGapY = Convert.ToInt32(1.5 * barHeight);
            }


            double dMarkersCount = (double)(pictureHeight - (btmServiceSpaceGapY + topServiceSpaceGapY)) / 30.0d;
            dMarkersCount = (dMarkersCount > 10.0d) ? (10.0d) : (dMarkersCount);
            double dRulerValueGap = (overallFuncMax - overallFuncMin) / (double)dMarkersCount;
            //dRulerValueGap = (dRulerValueGap < 1.0d) ? (1.0d) : dRulerValueGap;
            int    deciGap          = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGap, 2.0d)));
            double rulerValueGap    = Math.Pow(2.0, (double)deciGap);
            double lowerMarkerValue = overallFuncMin - overallFuncMin % rulerValueGap;// Math.IEEERemainder(overallFuncMin, rulerValueGap);
            lowerMarkerValue = (lowerMarkerValue < overallFuncMin) ? (lowerMarkerValue + rulerValueGap) : (lowerMarkerValue);

            List <double> yMarkersValues = new List <double>();
            yMarkersValues.Add(lowerMarkerValue);
            double currentMarkerValue = lowerMarkerValue;
            while (currentMarkerValue <= overallFuncMax)
            {
                currentMarkerValue += rulerValueGap;
                yMarkersValues.Add(currentMarkerValue);
            }

            List <TextBarImage> lTextBars = new List <TextBarImage>();
            foreach (double markerValue in yMarkersValues)
            {
                string currMarkerPresentation = markerValue.ToString();
                if (yAxisValuesConversionToRepresentTicksValues != null)
                {
                    currMarkerPresentation = yAxisValuesConversionToRepresentTicksValues(markerValue);
                }

                TextBarImage currTextBar = new TextBarImage(currMarkerPresentation,
                                                            new Image <Bgr, byte>(new Size(pictureWidth, pictureHeight)));
                lTextBars.Add(currTextBar);
            }
            int maxYlabelWidth = lTextBars.Max(textBar => textBar.textBarSize.Width);
            if (leftServiceSpaceGapX < maxYlabelWidth)
            {
                leftServiceSpaceGapX = maxYlabelWidth;
            }



            currentMarkerValue = lowerMarkerValue;
            double nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - topServiceSpaceGapY - btmServiceSpaceGapY) + topServiceSpaceGapY;
            while (nextYPositionDouble > topServiceSpaceGapY)
            {
                double        yPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - topServiceSpaceGapY - btmServiceSpaceGapY) + topServiceSpaceGapY;
                int           yPosition       = Convert.ToInt32(Math.Round(yPositionDouble));
                LineSegment2D theLine         = new LineSegment2D(new Point(leftServiceSpaceGapX, yPosition), new Point(leftServiceSpaceGapX - 5, yPosition));
                Bgr           markerColor     = colorGreen;
                theImage.Draw(theLine, markerColor, 2);

                string currMarkerPresentation = currentMarkerValue.ToString();
                if (yAxisValuesConversionToRepresentTicksValues != null)
                {
                    currMarkerPresentation = yAxisValuesConversionToRepresentTicksValues(currentMarkerValue);
                }

                //theImage.Draw(currMarkerPresentation, ref theFont, new Point(2, yPosition), markerColor);

                TextBarImage currSignImage = new TextBarImage(currMarkerPresentation, theImage);
                currSignImage.PtSurroundingBarStart = new Point(0, yPosition - currSignImage.textHeight);
                theImage = theImage.Add(currSignImage.TextSignImageAtOriginalBlank(markerColor));


                currentMarkerValue += rulerValueGap;
                nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - topServiceSpaceGapY - btmServiceSpaceGapY) + topServiceSpaceGapY;
            }

            #endregion Y



            #region X

            double rulerValueGapX    = 0.0d;
            double lowerMarkerValueX = 0.0d;
            bool   markersCountRight = false;
            int    initialDivider    = 30;
            double dMarkersCountX    = (double)(pictureWidth - (leftServiceSpaceGapX + rightServiceSpaceGapX)) / (double)initialDivider;
            while (!markersCountRight)
            {
                dMarkersCountX = (dMarkersCountX > 10.0d) ? (10.0d) : (dMarkersCountX);
                double dRulerValueGapX = (xSpaceMax - xSpaceMin) / (double)dMarkersCountX;
                //int deciGapX = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGapX, 2.0d)));
                //rulerValueGapX = Math.Pow(2.0, (double)deciGapX);
                rulerValueGapX    = dRulerValueGapX;
                lowerMarkerValueX = xSpaceMin - (xSpaceMin % rulerValueGapX); // Math.IEEERemainder(xSpaceMin, rulerValueGapX);
                lowerMarkerValueX = (lowerMarkerValueX < xSpaceMin) ? (lowerMarkerValueX + rulerValueGapX) : (lowerMarkerValueX);

                double        firstMarkerValueX = lowerMarkerValueX;
                List <double> xMarkersValues    = new List <double>();
                xMarkersValues.Add(firstMarkerValueX);
                currentMarkerValue = firstMarkerValueX;
                while (currentMarkerValue <= xSpaceMax)
                {
                    currentMarkerValue += rulerValueGapX;
                    xMarkersValues.Add(currentMarkerValue);
                }

                List <TextBarImage> lTextBarsXaxis = new List <TextBarImage>();
                foreach (double markerValue in xMarkersValues)
                {
                    string currMarkerPresentation = markerValue.ToString();
                    if (xAxisValuesConversionToRepresentTicksValues != null)
                    {
                        currMarkerPresentation = xAxisValuesConversionToRepresentTicksValues(markerValue);
                    }

                    TextBarImage currTextBar = new TextBarImage(currMarkerPresentation,
                                                                new Image <Bgr, byte>(new Size(pictureWidth, pictureHeight)));
                    lTextBarsXaxis.Add(currTextBar);
                }

                int totalTextBarsWidth = lTextBarsXaxis.Sum(textBar => textBar.textBarSize.Width);
                if (totalTextBarsWidth > pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX)
                {
                    dMarkersCountX = dMarkersCountX - 1.0d;
                    if (dMarkersCountX <= 2)
                    {
                        dMarkersCountX    = 2.0d;
                        markersCountRight = true;
                    }
                }
                else
                {
                    markersCountRight = true;
                }
            }


            double currentMarkerValueX = lowerMarkerValueX;

            double nextXPositionDouble = leftServiceSpaceGapX + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX);
            while (nextXPositionDouble <= pictureWidth - rightServiceSpaceGapX)
            {
                double        xPositionDouble = leftServiceSpaceGapX + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX);
                int           xPosition       = Convert.ToInt32(Math.Round(xPositionDouble));
                LineSegment2D theLine         = new LineSegment2D(new Point(xPosition, pictureHeight - btmServiceSpaceGapY), new Point(xPosition, pictureHeight - btmServiceSpaceGapY + 5));
                Bgr           markerColor     = colorGreen;
                theImage.Draw(theLine, markerColor, 2);

                string currMarkerPresentation = currentMarkerValueX.ToString();
                if (xAxisValuesConversionToRepresentTicksValues != null)
                {
                    currMarkerPresentation = xAxisValuesConversionToRepresentTicksValues(currentMarkerValueX);
                }

                TextBarImage currSignImage = new TextBarImage(currMarkerPresentation, theImage);
                currSignImage.PtSurroundingBarStart = new Point(Convert.ToInt32(xPosition - currSignImage.textBarSize.Width / 2), pictureHeight - btmServiceSpaceGapY + 10);
                theImage = theImage.Add(currSignImage.TextSignImageAtOriginalBlank(markerColor));

                currentMarkerValueX += rulerValueGapX;
                nextXPositionDouble  = leftServiceSpaceGapX + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX);
            }

            #endregion X
            #endregion Прописываем текстовые маркеры



            int xValuesCount = pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX;// оставляем место на шкалу Y

            List <Point> rulerVertices = new List <Point>();
            rulerVertices.Add(new Point(leftServiceSpaceGapX, pictureHeight - btmServiceSpaceGapY));
            rulerVertices.Add(new Point(pictureWidth - rightServiceSpaceGapX, pictureHeight - btmServiceSpaceGapY));
            rulerVertices.Add(new Point(pictureWidth - rightServiceSpaceGapX, topServiceSpaceGapY));
            rulerVertices.Add(new Point(leftServiceSpaceGapX, topServiceSpaceGapY));
            theImage.DrawPolyline(rulerVertices.ToArray(), true, colorGreen, 2);

            double koeff = (pictureHeight - btmServiceSpaceGapY - topServiceSpaceGapY) / (overallFuncMax - overallFuncMin);
            koeffY = ((double)pictureHeight - btmServiceSpaceGapY - topServiceSpaceGapY) / (overallFuncMax - overallFuncMin);
            koeffX = ((double)pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX) / (xSpaceMax - xSpaceMin);
            if (equalScale)
            {
                koeff  = Math.Min(koeffY, koeffX);
                koeffY = koeff;
                koeffX = koeff;
            }


            if (drawZeroLines)
            {
                int zeroYcoordinate = Convert.ToInt32(pictureHeight - btmServiceSpaceGapY - (0 - overallFuncMin) * koeffY);
                int zeroXcoordinate = Convert.ToInt32(leftServiceSpaceGapX + (0 - xSpaceMin) * koeffX);

                List <Point> rulerXVertices = new List <Point>();
                rulerXVertices.Add(new Point(leftServiceSpaceGapX, zeroYcoordinate));
                rulerXVertices.Add(new Point(pictureWidth - rightServiceSpaceGapX, zeroYcoordinate));
                theImage.DrawPolyline(rulerXVertices.ToArray(), false, colorGreen, 2);

                List <Point> rulerYVertices = new List <Point>();
                rulerYVertices.Add(new Point(zeroXcoordinate, topServiceSpaceGapY));
                rulerYVertices.Add(new Point(zeroXcoordinate, pictureHeight - btmServiceSpaceGapY));
                theImage.DrawPolyline(rulerYVertices.ToArray(), false, colorGreen, 2);
            }



            DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func <int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin)));
            DenseVector parametersList = null;

            for (int i = 0; i < theRepresentingFunctions.Count; i++)
            {
                Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i];
                DenseVector currentParametersList = parameters[i];

                DenseVector dvFuncValues = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j])));
                double      funcMax      = dvFuncValues.Max();
                double      funcMin      = dvFuncValues.Min();
                overallFuncMax = (funcMax > overallFuncMax) ? (funcMax) : (overallFuncMax);
                overallFuncMin = (funcMin < overallFuncMin) ? (funcMin) : (overallFuncMin);
            }



            for (int i = 0; i < theRepresentingFunctions.Count; i++)
            {
                Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i];
                DenseVector currentParametersList = parameters[i];

                //DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func<int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin)));
                parametersList = null;
                DenseVector dvFuncValues     = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j])));
                Bgr         currentLineColor = lineColors[i];


                DenseVector xCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j => ((double)leftServiceSpaceGapX + j)));
                DenseVector yCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j =>
                {
                    double pixValue = koeff * (dvFuncValues[j] - overallFuncMin);
                    return(pictureHeight - btmServiceSpaceGapY - pixValue);
                }));

                List <Point> funcRepresentationPoints = new List <Point>();
                for (int j = 0; j < xValuesCount; j++)
                {
                    if (double.IsNaN(yCoordinates[j]))
                    {
                        continue;
                    }
                    funcRepresentationPoints.Add(new Point(Convert.ToInt32(xCoordinates[j]), Convert.ToInt32(yCoordinates[j])));
                }
                theImage.DrawPolyline(funcRepresentationPoints.ToArray(), false, currentLineColor, 2);
            }
        }