Exemple #1
0
 private void DrawCache(IGraphValueList graph, ref GraphCache cache)
 {
     Effect.Parameters["Color"].SetValue(
         new Vector4(
             graph.Color.R / 255.0f,
             graph.Color.G / 255.0f,
             graph.Color.B / 255.0f,
             (float)graph.PlaneAlpha));
     GraphicsDevice.Indices = cache.IndexAreaBuffer;
     GraphicsDevice.SetVertexBuffer(cache.VertexAreaBuffer);
     foreach (EffectPass pass in Effect.CurrentTechnique.Passes)
     {
         pass.Apply();
         GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, cache.VertexAreaBuffer.VertexCount, 0, cache.IndexAreaBuffer.IndexCount / 3);
     }
     Effect.Parameters["Color"].SetValue(
         new Vector4(
             graph.Color.R / 255.0f,
             graph.Color.G / 255.0f,
             graph.Color.B / 255.0f,
             (float)graph.GraphAlpha));
     GraphicsDevice.SetVertexBuffer(cache.VertexLineBuffer);
     foreach (EffectPass pass in Effect.CurrentTechnique.Passes)
     {
         pass.Apply();
         GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, cache.VertexLineBuffer.VertexCount, 0, cache.IndexAreaBuffer.IndexCount / 3);
     }
 }
Exemple #2
0
        private void DrawGraph(IGraphValueList graph)
        {
            if (graph.Count <= 1)
            {
                return;
            }

            GraphCache cache;

            bool needsRedraw = true;

            //if (graphCaches.TryGetValue(graph, out cache))
            //{
            //    if (cache.NumElements == graph.Count)
            //    {
            //        needsRedraw = false;
            //    }
            //}


            if (needsRedraw)
            {
                WaitCallback worker = (state) =>
                {
                    try
                    {
                        CreateCache(graph);
                    }
                    catch (Exception)
                    {
                    }
                };
                ThreadPool.QueueUserWorkItem(worker);
            }
            lock (this)
            {
                if (graphCaches.TryGetValue(graph, out cache))
                {
                    DrawCache(graph, ref cache);
                }
            }
        }
Exemple #3
0
 public void Add(string name, IGraphValueList list)
 {
     graphs.Add(name, list);
 }
Exemple #4
0
        private void CreateCache(IGraphValueList graph)
        {
            GraphCache cache;
            int        CurrentVertexIndex = 0;
            int        graphCount         = graph.Count;
            int        startIndex         = 0;
            int        elementCount       = graphCount - startIndex;

            if (elementCount <= 0)
            {
                return;
            }
            Func <IGraphValue, decimal> GetY = (value) => { return(value.DisplayValue); };
            Func <IGraphValue, decimal> GetX = (value) => { return(value.DisplayPosition); };
            decimal maxY = graph[startIndex].DisplayValue;
            decimal minY = graph[startIndex].DisplayValue;
            decimal maxX = graph[startIndex].DisplayPosition;
            decimal minX = graph[startIndex].DisplayPosition;

            for (int elementIndex = startIndex; elementIndex < graphCount; elementIndex++)
            {
                maxY = Math.Max(maxY, graph[elementIndex].DisplayValue);
                minY = Math.Min(minY, graph[elementIndex].DisplayValue);
                maxX = Math.Max(maxX, graph[elementIndex].DisplayPosition);
                minX = Math.Min(minX, graph[elementIndex].DisplayPosition);
            }

            Func <decimal, float> GetRelativeY = (decimal alpha) =>
            {
                if (minY == maxY)
                {
                    return(0.0f);
                }
                return(((float)((alpha - minY) / (maxY - minY)) - 0.5f) * 2.0f);
            };

            Func <decimal, float> GetRelativeX = (decimal alpha) =>
            {
                return(((float)((alpha - minX) / (maxX - minX)) - 0.5f) * 2.0f);
            };

            VertexPosition2 upperPoint = new VertexPosition2();
            VertexPosition2 lowerPoint = new VertexPosition2();

            upperPoint.Position = new Vector2(-1, GetRelativeY(graph.ElementAt(0).DisplayValue));
            lowerPoint.Position = new Vector2(-1, -1);

            VertexPosition2[] vertexAreaBufferData = new VertexPosition2[((graphCount - startIndex) + 1) * 2];
            VertexPosition2[] vertexLineBufferData = new VertexPosition2[((graphCount - startIndex) + 1) * 2];
            int[]             indexBufferData      = new int[((graphCount - startIndex)) * 6];
            int CurrentIndexBufferIndex            = 0;

            vertexAreaBufferData[CurrentVertexIndex]     = upperPoint;
            vertexAreaBufferData[CurrentVertexIndex + 1] = lowerPoint;

            float   lineWidth       = (5.0f / Height) / 2.0f;
            Vector2 lineWidthOffset = new Vector2(0.0f, lineWidth / 2.0f);

            vertexLineBufferData[CurrentVertexIndex]     = new VertexPosition2(upperPoint.Position + lineWidthOffset);
            vertexLineBufferData[CurrentVertexIndex + 1] = new VertexPosition2(upperPoint.Position - lineWidthOffset);

            CurrentVertexIndex = 2;

            Vector2 lastUpperPoint;

            for (int GraphIndex = startIndex; GraphIndex < graphCount; GraphIndex++)
            {
                float x = GetRelativeX(graph.ElementAt(GraphIndex).DisplayPosition);
                float y = GetRelativeY(graph.ElementAt(GraphIndex).DisplayValue);

                lastUpperPoint = upperPoint.Position;

                upperPoint.Position = new Vector2(x, y);
                lowerPoint.Position = new Vector2(x, -1);
                vertexAreaBufferData[CurrentVertexIndex]     = upperPoint;
                vertexAreaBufferData[CurrentVertexIndex + 1] = lowerPoint;

                // Calculate orthogonal vector of direction from last point to this one,
                // so the line keeps its thickness along slopes
                // Without this sloped graphs would get very thin
                Vector2 dirFromLastPoint = upperPoint.Position - lastUpperPoint;
                if (GraphIndex + 1 < graphCount)
                {
                    dirFromLastPoint += new Vector2(
                        GetRelativeX(graph.ElementAt(GraphIndex + 1).DisplayPosition),
                        GetRelativeY(graph.ElementAt(GraphIndex + 1).DisplayValue)) - upperPoint.Position;
                    dirFromLastPoint /= 2;
                }
                dirFromLastPoint.Normalize();
                Vector2 orthogonalDir = new Vector2(-dirFromLastPoint.Y, dirFromLastPoint.X);

                vertexLineBufferData[CurrentVertexIndex]     = (new VertexPosition2(upperPoint.Position + orthogonalDir * lineWidth));
                vertexLineBufferData[CurrentVertexIndex + 1] = (new VertexPosition2(upperPoint.Position - orthogonalDir * lineWidth));

                // Counter Clockwise Tris get culled in our current setting
                // So draw 2 triangles in clockwise order
                // -2---+0
                //  |   /|
                //  |  / |
                //  | /  |
                //  |/   |
                // -1---+1
                int LastUpperPoint    = CurrentVertexIndex - 2;
                int LastLowerPoint    = CurrentVertexIndex - 1;
                int CurrentUpperPoint = CurrentVertexIndex;
                int CurrentLowerPoint = CurrentVertexIndex + 1;
                indexBufferData[CurrentIndexBufferIndex]     = LastUpperPoint;
                indexBufferData[CurrentIndexBufferIndex + 1] = CurrentUpperPoint;
                indexBufferData[CurrentIndexBufferIndex + 2] = LastLowerPoint;
                indexBufferData[CurrentIndexBufferIndex + 3] = LastLowerPoint;
                indexBufferData[CurrentIndexBufferIndex + 4] = CurrentUpperPoint;
                indexBufferData[CurrentIndexBufferIndex + 5] = CurrentLowerPoint;

                CurrentIndexBufferIndex += 6;
                CurrentVertexIndex      += 2;
            }
            cache.VertexLineBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPosition2), CurrentVertexIndex, BufferUsage.WriteOnly);
            cache.VertexLineBuffer.SetData(vertexLineBufferData);

            cache.VertexAreaBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPosition2), CurrentVertexIndex, BufferUsage.WriteOnly);
            cache.VertexAreaBuffer.SetData(vertexAreaBufferData);
            cache.IndexAreaBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, indexBufferData.Length, BufferUsage.WriteOnly);
            cache.IndexAreaBuffer.SetData(indexBufferData);

            cache.NumElements = graphCount;
            GraphCache oldCache;

            lock (this)
            {
                if (graphCaches.TryGetValue(graph, out oldCache))
                {
                    graphCaches.Remove(graph);
                    oldCache.IndexAreaBuffer?.Dispose();
                    oldCache.VertexAreaBuffer?.Dispose();
                    oldCache.VertexLineBuffer?.Dispose();
                }
                graphCaches[graph] = cache;
            }
        }