protected static ProfilerFrame[] GenerateSampleData()
        {
            var sampleCount = 200;

            var data = new ProfilerFrame[sampleCount];

            for (var i = 0; i < sampleCount; i++)
            {
                var frame = new ProfilerFrame();

                for (var j = 0; j < 3; j++)
                {
                    var v = 0d;

                    if (j == 0)
                    {
                        v = Mathf.PerlinNoise(i/200f, 0);
                    }
                    else if (j == 1)
                    {
                        v = Mathf.PerlinNoise(0, i/200f);
                    }
                    else
                    {
                        v = Random.Range(0, 1f);
                    }

                    v *= (1f/60f)*0.333f;

                    // Simulate spikes
                    if (Random.value > 0.8f)
                    {
                        v *= Random.Range(1.2f, 1.8f);
                    }

                    if (j == 2)
                    {
                        v *= 0.1f;
                    }

                    if (j == 0)
                    {
                        frame.UpdateTime = v;
                    }
                    else if (j == 1)
                    {
                        frame.RenderTime = v;
                    }
                    else if (j == 2)
                    {
                        frame.FrameTime = frame.RenderTime + frame.UpdateTime + v;
                    }
                }

                data[i] = frame;
            }

            data[0] = new ProfilerFrame
            {
                FrameTime = 0.005,
                RenderTime = 0.005,
                UpdateTime = 0.005
            };

            data[sampleCount - 1] = new ProfilerFrame
            {
                FrameTime = 1d/60d,
                RenderTime = 0.007,
                UpdateTime = 0.007
            };

            return data;
        }
        protected void DrawDataPoint(float xPosition, float verticalScale, ProfilerFrame frame)
        {
            // Right-hand x-coord
            var rx = Mathf.Min(_clipBounds.width/2f, xPosition + DataPointWidth - DataPointMargin);

            var currentLineHeight = 0f;

            for (var j = 0; j < LineCount; j++)
            {
                var lineIndex = j;

                var value = 0f;

                if (j == 0)
                {
                    value = (float) frame.UpdateTime;
                }
                else if (j == 1)
                {
                    value = (float) frame.RenderTime;
                }
                else if (j == 2)
                {
                    value = (float) frame.OtherTime;
                }

                value *= verticalScale;

                if (value.ApproxZero() || value - DataPointVerticalMargin*2f < 0f)
                {
                    continue;
                }

                // Lower y-coord
                var ly = currentLineHeight + DataPointVerticalMargin - rectTransform.rect.height/2f;

                if (VerticalAlignment == VerticalAlignments.Top)
                {
                    ly = rectTransform.rect.height/2f - currentLineHeight - DataPointVerticalMargin;
                }

                // Upper y-coord
                var uy = ly + value - DataPointVerticalMargin;

                if (VerticalAlignment == VerticalAlignments.Top)
                {
                    uy = ly - value + DataPointVerticalMargin;
                }

                var c = LineColours[lineIndex];

                AddRect(new Vector3(Mathf.Max(-_clipBounds.width/2f, xPosition), ly),
                    new Vector3(Mathf.Max(-_clipBounds.width/2f, xPosition), uy), new Vector3(rx, uy),
                    new Vector3(rx, ly), c);

                currentLineHeight += value;
            }
        }