-1
var mapper = Mappers.Xy<MeasureModel>()
           .X(model => model.DateTime.Ticks)   //use DateTime.Ticks as X
           .Y(model => model.Value);           //use the value property as Y

//The next code simulates data changes every 500 ms
Timer = new Timer
{
    Interval = 1000
};
Timer.Tick += TimerOnTick;
R = new Random();
Timer.Start();

ChartValues.Add(new MeasureModel
{
    DateTime = now,
    Value = R.Next(0, 5)
});

From the above , how do i do about it that instead of having R to random , can i set it to decrements . Like it drops as doubles like 5.0 4.4 3.2 and etc instead of random between 0 to 5

Robert Loh
  • 19
  • 4
  • 1
    and when it drops below zero? – Sergey Berezovskiy Jan 24 '17 at 09:19
  • 1
    instead of `R.Next(0, 5)` use some var like `R.Next(0, x)` where `x` is decreased with some other timer – Nino Jan 24 '17 at 09:22
  • i want to prevent it to drop to 0 . so if i want it to drop , i would like to drop abit like a 5.0 4.9 4.8 and etc – Robert Loh Jan 24 '17 at 09:22
  • @RobertLoh and when it drops below zero? – Sergey Berezovskiy Jan 24 '17 at 09:23
  • @Nino Hmn... do have an example? – Robert Loh Jan 24 '17 at 09:23
  • it wouldnt because its a vriable that i would be monitoring , thus around 3 something , i would have to do some replensihing and increasing it up again – Robert Loh Jan 24 '17 at 09:24
  • The Random class can output doubles as well and you can calculate with that value as you like. Take the random value as the base, calculate the interval and de-/increase the result value – Sir Rufo Jan 24 '17 at 09:26
  • Sorry. Do u have an example for me ? @SirRufo – Robert Loh Jan 24 '17 at 09:28
  • Example for getting double random values or how to calculate with a double value? – Sir Rufo Jan 24 '17 at 09:30
  • double random values shd be easier abit. but am curious if i am able to do it where i do a decrement from a double like 5.0 till around 3.3 with every 0.1 drop or 0.5 drop , anything that works – Robert Loh Jan 24 '17 at 09:37
  • Would initialising Value prior to starting your timer & then subtracting a random value from it's current value each tick do what you want. Or have a separate "Decrement" value if you want to step down in equal steps. – PaulF Jan 24 '17 at 09:38
  • newInterval = (maximumExpectedInterval - minimumExpectedInterval) * randomValue(0..1) + minimumExpectedInterval – Sir Rufo Jan 24 '17 at 09:39

4 Answers4

0

in your method that sets first timer, add another one, like this:

//The next code simulates data changes every 500 ms
Timer = new Timer
{
    Interval = 1000
};
Timer.Tick += TimerOnTick;
R = new Random();
Timer.Start();

//another timer
SecondTimer = new Timer() { Interval = 2000 };
SecondTimer.Enabled = true;
SecondTimer.Tick += SecondTimer_Tick;

Define some min variable

double min = 4.9;

In SecondTimer_Tick method, adjust those vars and generate new value. Random.NextDouble will generate number from 0 to 1 (ie 0.887), add it to your min var. Also, decrease your min value by some value (0.2 in this example)

private void SecondTimer_Tick(object sender, EventArgs e)
{
    min -= 0.2;

    if (min == 0)
        //stop timer or something
        SecondTimer.Stop();

    Random R = new Random();
    var value = R.NextDouble();
    value += min;
}

Hope this helps.

EDIT: Add some checking if value generated by randomizer is too big. In example, if your min is 4.8 and generated value is 0.5 - adding those together will get you 5.3 which is, I suppose, too big value for your case.

Nino
  • 6,931
  • 2
  • 27
  • 42
0

var r = R.NextDouble()*5 will give you decimal number from 0 to 5.

Semantically You can reverse the number like this, var r= 5 - R.NextDouble()*5

Ofcourse 5 can be variable with any number.

Now decrement the value from a random generated number at every timer tick.

private double decrementingValue = 5;

... 

r = R.NextDouble()* 5;
decrementingValue -= r;

if(decrementingValue <= 0) 
       decrementingValue= 0; // you are finished
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
0

You can use abstract measurements source

public interface IMeasurementSource
{
    MeasureModel GetNext();
}

Provide some IMeasurementSource implementation to your class (probably Form) and save it in class field. E.g.

private IMeasurementSource measurementSource = new BouncingMesasurementSource(5, 0.1);

And call it each time your timer ticks:

ChartValues.Add(measurementSource.GetNext());

Implementing abstraction

You can implement this interface by getting measurements from real source. Or you can use random measurements generator:

public class RandomMeasurementSource : IMeasurementSource
{
    private readonly Random random = new Random();
    private readonly int min;
    private readonly int max;

    public RandomMeasurementSource(int min, int max)
    {
        this.min = min;
        this.max = max;
    }

    public MeasureModel GetNext()
    {
        return new MeasureModel { DateTime = DateTime.Now, Value = random.Next(min, max) };
    }
}

Or bouncing which will go back and force between zero and max value:

public class BouncingMeasurementSource : IMeasurementSource
{
    private readonly double max;
    private double step;
    private double current;

    public BouncingMeasurementSource(int max, double step)
    {
        this.max = max;
        this.step = step;
        this.current = max;
    }

    public MeasureModel GetNext()
    {
        var model = new MeasureModel { DateTime = DateTime.Now, Value = current };
        current -= step;

        if (current < 0 || max < current)
        {
            step = -step;
            current = current < 0 ? 0 : max;
        }

        return model;
    }
}
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

Build a generator class that will do all the calculations of the new values for you.

As an example here a very basic implementation which can be a starter for your class

enum Direction
{
    Increase,
    Decrease,
}

class ValueGenerator
{
    private readonly Random _generator;

    public ValueGenerator( Random generator )
    {
        if ( generator == null )
            throw new ArgumentNullException( nameof( generator ) );
        _generator = generator;
    }

    public double MinInterval { get; set; } = 0;
    public double MaxInterval { get; set; } = 1;
    public double MinValue { get; set; } = 0;
    public double MaxValue { get; set; } = 100;
    public double CurrentValue { get; set; } = 0;
    public Direction CurrentDirection { get; set; } = Direction.Increase;
    public int PossibilityToChangeDirection { get; set; } = 10;

    public double NextValue()
    {
        if ( _generator.Next( PossibilityToChangeDirection + 1 ) == PossibilityToChangeDirection / 2 )
        {
            switch ( CurrentDirection )
            {
                case Direction.Increase:
                    CurrentDirection = Direction.Decrease;
                    break;
                case Direction.Decrease:
                    CurrentDirection = Direction.Increase;
                    break;
                default:
                    throw new InvalidOperationException( );
            }
        }

        var newInterval = ( MaxInterval - MinInterval ) * _generator.NextDouble( ) + MinInterval;
        if ( CurrentDirection == Direction.Decrease )
            newInterval = -newInterval;

        if ( CurrentValue + newInterval < MinValue )
            CurrentValue = MinValue;
        else if ( CurrentValue + newInterval > MaxValue )
            CurrentValue = MaxValue;
        else
            CurrentValue += newInterval;

        return CurrentValue;
    }
}

Usage example

//The next code simulates data changes every 500 ms
Timer = new Timer
{
    Interval = 1000
};
Timer.Tick += TimerOnTick;

var vg = new ValueGenerator( new Random( ) )
{
    MinValue = 0,
    MaxValue = 5,
    MinInterval = 0.1,
    MaxInterval = 0.7,
    CurrentValue = 3.0,
    CurrentDirection = Direction.Decrease,
    PossibilityToChangeDirection = 10,
};

Timer.Start();

ChartValues.Add(new MeasureModel
{
    DateTime = now,
    Value = vg.NextValue(),
});
Sir Rufo
  • 18,395
  • 2
  • 39
  • 73