Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I draw a nice graph like the HTC 'Stocks' app

With my HTC Mozart, I downloaded an app called 'Stocks' which basically looks after stocks (nasdaq etc...).

The charts/graphs look very nice and I'm wonder how I can do something similar. Here's a picture of the graph:

Stocks App Picture

I see 3 colors: - above the curve (the background) - the curve itself - below the curve

Are there any free/open resources that can help me draw graphs like this? Any blog posts or links are welcome!

like image 984
terry Avatar asked Feb 10 '11 13:02

terry


2 Answers

Basically, if you chose to write code to do this yourself, you need to create three graphical elements:

  1. The background, e.g. the dark blue area, which could just be the canvas or grid itself
  2. The spark line (what you refer to as the curve), which is a bunch of line segments built out of a points collection
  3. A polygon which consists of an identical set of points to that of the spark line, plus line segment drawn from the last X2, Y2 coordinates to the bottom of the graph, another line segment back to from the bottom righthand corner to the bottom left, and a final segment from bottom left up to the very first X1,Y1 coordinates. This polygon would be added to the canvas before the spark line and would be given a fill different from the background.

Updating this with some sample code. Assuming you have a List of raw Y values (and I apologize for not having time to post a more complete example):

// Declare a Polyline for the spark line
Polyline sparkLine = new Polyline();

// Get style from the XAML user control resources
sparkLine.Style = (Style)TryFindResource("graphLine");

// Declare a polygon for the background
Polygon backgroundPolygon = new Polygon();

// Get its style
backgroundPolygon.Style = (Style)TryFindResource("graphBackground");

// PointCollection for the graph
PointCollection graphPointsCollection = new PointCollection();

// The X value for each point just gets advanced by a uniform amount for each
// Y value on the graph, in this case by an int called gridUnit, which was defined elsewhere
int currentX = 0;

// Get the range covering the min and max graph bounds
decimal graphValRange = maxGraphVal - minGraphVal;

// Traverse the numeric values in a list, create points and add them to the PointCollection
foreach (decimal graphVal in graphValues)
{
    // Calculate the Y2 value as a percentage
    decimal graphY2Val = (graphVal - minGraphVal) / graphValRange;

    // Then apply that percentage to the overall graph height and that will be our Y2 value.
    // NOTE: Since Y values are inverse, we subtract it from the graph height to render it correctly
    double graphY2ValDouble = Convert.ToDouble(graphHeight - (graphY2Val * graphHeight));

    // Create a point from the X and Y values
    Point currentPoint = new Point(currentX, graphY2ValDouble);

    // Add it to the collection
    graphPointsCollection.Add(currentPoint);

    // Advance the X value each time (as a multiple of the grid unit)
    currentX += gridUnit;
}

// For the background we'll use all the same points but need to clone. Otherwise,
// when some additional points are added they would also end up in the spark line
PointCollection backgroundPointsCollection = graphPointsCollection.Clone();

// Now add additional points to collection to create background polygon.
// These will allow the polygon to be drawn to bottom right
// and back to bottom left, completing the polygon.
Point bottomRightPoint = new Point(currentX - gridUnit, graphHeight);
Point bottomLeftPoint = new Point(0, graphHeight);

backgroundPointsCollection.Add(bottomRightPoint);
backgroundPointsCollection.Add(bottomLeftPoint);

// Now assign the points to the background polygon
backgroundPolygon.Points = backgroundPointsCollection;

// Add the background to the graph first so it doesn't cover the spark line
Graph.Children.Add(backgroundPolygon);

// Finally, assign the graph points to the spark line
sparkLine.Points = graphPointsCollection;

// Add the spark line to the graph
Graph.Children.Add(sparkLine);

Here is XAML for the styles:

<Style TargetType="Polyline" x:Key="graphLine">
    <Setter Property="Stroke" Value="#96EF4223" />
    <Setter Property="StrokeThickness" Value="2" />
</Style>

<Style TargetType="Polygon" x:Key="graphBackground">
    <Setter Property="Fill">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,0.003" StartPoint="0.5,0.994">
                <GradientStop Color="#24FAF8CA" Offset="0"/>
                <GradientStop Color="#246EBDE9" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
</Style>

I used code like this to generate graphs like this:

sample graph

like image 141
Stonetip Avatar answered Sep 26 '22 23:09

Stonetip


You can use the Chart controls from the Silverlight Toolkit, as described in this blog post.

Visifire also offer a chart control.

like image 23
Derek Lakin Avatar answered Sep 22 '22 23:09

Derek Lakin