Summary: In this post, I walk through the basics of using Silverlight to query the New York Times Article API and display the results of the query. You can see the final result below.
You can also download source code for this project here.
This project is somewhat code-intensive (and kind of long, expect 30-60 minutes), so if you just want the utility provided here without any of the work, you can skip over to my post on displaying the results, which is strictly a Blend tutorial.
However, I recommend walking through this one since it will help get you to a point of pulling real data from an API, which I’ve found to be a wonderful help as I practice putting together data-based designs. One of the things I’ve been wanting to be able to do as a designer is to explore a data set easily and quickly so that I can have data to play with in my interfaces. I found exactly what I wanted in the New York Times API, but then I found out I had to learn JSON.
“Oh great,” I said to myself, “another technology for me to learn.” But it turned out that I didn’t actually have to learn that much, because Visual Studio does nearly all the work for me.
Super Quick Introduction to JSON
If you’re not interested and you want to get to the business of grabbing New York Times data, you can skip it . It is helpful, but not strictly necessary.
JSON stands for JavaScript Object Notation and is basically just a really handy way to pass data along in a web service. It is very simple… within a set of curly brackets, you will have name/value pairs separated by a colon with each piece of data.
Example:
{
FirstName : “Matthias”,
LastName : “Shapiro”,
Blog : “Designer WPF”
}
This is a JSON object. Arrays are created by using square brackets and JSON obejcts can be placed into a Javascript var. These things are not really related in anyway, but putting them in the same sentence allows me to only write one more example instead of two
What is so awesome about JSON and Silverlight is that Visual Studio 2008 has a set of JSON-friendly classes that make working with JSON a breeze. Which is really handy because the New York Times, which is a dream come true for the new data-gatherer, delivers JSON results. So let’s walk through making a call to the New York Times Article API, handling the data we get back, and putting it into a Listbox for viewing.
Next, start a new Silverlight project in Visual Studio 2008. I named mine “JSONNewYorkTimesTutorial”.
Open your new project in Blend, pull up Page.xaml and add a TextBlock, ListBox, a TextBox and a Button. Name the ListBox “ResultsDisplay” and the TextBox “SearchText”.
Now, my Page.xaml looks like this.
OK… now let’s go to the code-behind for our project go to the event section of the button in Blend and type “PerformQuery” into the “Click” event.
This will automatically insert the necessary code into the code-behind, so pull up Visual Studio. Before we implement a call to the NYT API, lets add some useful stuff. If you have not yet gone to get your Developer key, do so now.
public Page()
{
InitializeComponent();
myApiKey = “&api-key=(put your api key here. No, you may not have mine)”;
callNYT = new WebClient();
callNYT.OpenReadCompleted += new OpenReadCompletedEventHandler(callNYT_OpenReadCompleted);
}
In the code above, we’ve created a string that we can use to apply our unique NYT API key and we’ve created an instance of WebClient to call and receive information from the NYT API. When an object from the NYT API has been received , it will call the OpenReadCompleted event, which will be handled by our callNYT_OpenReadCompleted method.
(By the way, if you’re not getting the proper intellisense for the “Web Client” part, add “using System.Net;” to the top of your file.)
Now on to our button method. There are tons of things we can add to our query to find the exact information we want. But in the interest of simplicity, this post will deal only with a simple text search. To that end, let’s go to our PerformQuery method and turn it into this:
We’ve done two things here. The first is that we built our search query using the query base, the query string and our API key. That was simple enough.
Next, we’ve going to use the WebClient we created to call our new query. When the query has been completed, our program will run the callNYT_OpenReadCompleted method with its result, which will be a JSON object constructed by the NYT servers. We will get back a JSON object with the following:
offset – We will get 10 results per page. The offset tells us which page of the results we’re on. The default is 0, which gives us results 0 – 9.
tokens – this is a array of our search terms.
total – this is an integer indicating of how many results there were for our search.
results – this is an array of results with the following format
body – a portion of the beginning of the article
byline – the article byline, usually including the author name
date – the date the article appeared, in a “yyyymmdd” format. For example, today would be “20090225”.
title – the article title
url – a url link to the article
A quick note: The NYT API is extremely flexible and we can actually define how we want our results to come back. This is just the default result format for the purposes of demonstration.
Before we handle this object, we want to create a class for the results. Right click on your project and go to “Add –> Class…”. Name your new class “NYTResult.cs” and make sure it looks like this:
public class NYTResult { public string Body { get; set; } public string Byline { get; set; } public DateTime Date { get; set; } public string Title { get; set; } public Uri Url { get; set; }
}
I added the following method to the class to handle the date conversion from the NYT format to a .NET DateTime object.
public DateTime formattedDateTime(string NYT_Time)
{ int year = Convert.ToInt32(NYT_Time.Substring(0, 4)); int month = Convert.ToInt32(NYT_Time.Substring(4, 2)); int day = Convert.ToInt32(NYT_Time.Substring(6, 2)); DateTime finalDateTime = new DateTime(year, month, day); return finalDateTime;
}
OK… now we’re really ready to handle the JSON object. Right click on the references in your project and select “Add Reference…”
In your “Add References” box, select “System.Json” and click “OK”.
Add “using System.Json;” to the references in your Page.xaml.cs file. And, just for good measure, add “using System.Collections.ObjectModel;” as well.
Go to the callNYT_OpenReadCompleted method and enter the following. I’ve tried to comment the code so that I don’t need to further explain it. Side note: I’m not always the best at understanding what is self-explanatory and what I need to elaborate on. If there are any additional questions, post them in the comments and I’ll answer as quickly as I can.
void callNYT_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{ //grab our result and make a JSON Object out of it // then extract the results array from that object JsonObject completeResult = (JsonObject)JsonObject.Load(e.Result); JsonArray resultsArray = (JsonArray)completeResult["results"];
//an observable collection to hold the data and attach it to our ListBox
ObservableCollection<NYTResult> resultCollection = new ObservableCollection<NYTResult>();
//iterate through the results and transfer the data from a // JSON object into our nice pretty .NET object foreach (JsonObject NYTRawResult in resultsArray)
{ NYTResult singleResult = new NYTResult();
//don’t forget to check your results… an article might not have a // byline or a link if (NYTRawResult.Keys.Contains(“body”))
singleResult.Body = NYTRawResult["body"]; if(NYTRawResult.Keys.Contains(“byline”))
singleResult.Byline = NYTRawResult["byline"]; if (NYTRawResult.Keys.Contains(“date”))
singleResult.Date = singleResult.formattedDateTime(NYTRawResult["date"]); if (NYTRawResult.Keys.Contains(“title”))
singleResult.Title = NYTRawResult["title"]; if (NYTRawResult.Keys.Contains(“url”))
singleResult.Url = new Uri(NYTRawResult["url"]);
//add our new result to the collection resultCollection.Add(singleResult);
}
//assign the result as the source for our ListBox ResultsDisplay.ItemsSource = resultCollection;
//take the overall article count and display it resultCount.Text = “Number of articles: ” + completeResult["total"].ToString();
}
Now, we can run our project. Type something into the TextBox and hit the button and we get this:
Not exactly the most readable thing ever. So let’s add the following to the ListBox XAML:
DisplayMemberPath=”Title”
Now we get something a little more like this (go ahead and give it a whirl):
Much better. Remember, this is a simple query, so it’s only looking for items that have that word in the article… it might not be in the title.
My next post builds on this one and I walk through building a more useful display for our results. It will be far less code intensive and far more designer centric.
I’ve made the source available for this project. I’ve taken out my NYT API key, so it will not run unless you get your own and put it in.
Yeah, yeah… I know it’s long past the time when anyone want to revisit the wonders of the 2008 presidential campaign, but the stars aligned for me to build this thing.
Star #1: I’m been meaning to learn JSON forever because everyone is talking about it.
Star #2: I’ve been meaning to get into pulling data from a publicly available API using a Silverlight application.
And so, due to several late nights and the infinite patience of my wonderful wife, I’ve finished my first data driven Silverlight information visualization. An explanation follows below the app.
The application visually displays how many stories in the New York Times in a given week mentioned one of the presidential candidates. If your favorite candidate does not appear, I apologize. I chose the seven most frequently mentioned candidates in each party.
My journey of exploration began at the New York Times developer site where I got my developer key and started exploring the data from their brand new Article Search API, with which you can search articles in the New York Times as far back as 1981.
Because the NYT API returns a JSON result, that meant I had to learn JSON. I highly recommend it. Super easy. I ended up scraping the data I needed and parsing it into a custom JSON file of my own so I wasn’t making a couple hundred calls to their servers every time I wanted to run my application.
From there, it was actually a simple matter to pull the idealized data into my application and start visualizing it. In case you’re wondering, the placement on the map doesn’t represent anything at all… I was just looking for a good way to show the data and I liked this one.
A special thanks to my wife, the math genius, for reminding me to take the square root my data so that my circles ended up with proportional areas (instead of exponential ones).
There are, of course, several things I would change about this if I had the time. The slider can be flaky, the fonts could use some more work and the code in general is a bit of a disaster. But this is all the time I had and I think it works pretty well.
I’d been holding out on this post in the interest of getting it just right. I think with more time I would add more stuff, but I stumbled across Scott Barnes’ post “I hate it when a designer touches XAML” and I knew that I need to get this posted. Here we have these fantastic tools for integrating the designer more deeply into the workflow and so few people are using it. That’s got to change.
Confession time… I am not, by trade, a designer in the sense that most people use the word… a graphic designer. I try to keep my focus much more on the Usability/UX/Human Computer Interactions/Whatever-The-Cool-Kids-Call-It-These-Days. I do some graphic design if I must, but the fact of the matter is that I’m not really that good at graphic design.
However, I often step in as a go-between for the designer’s comps and the developers code. And one thing that I’m good at is translating comps from Photoshop or Illustrator into XAML for the actual application.
To all designers… I can see why you are disappointed when you see your beautiful designs slaughtered in the translation process… because your designs are beautiful! And with Silverlight and WPF there is absolutely no reason why your designs should not be under your control pretty much all the way through the process. These tips are designed to help ease the transition from comp to user interface.
Pre-Tip: Work in Blend
All of these tips are assuming that designers are building comps with another design tool like Illustrator or Photoshop and then moving the comps into Blend. If you’re not using Blend, you should be. I am not suggesting that you change your design tools or that you design differently. These are just tips for the translation process.
Tip 1: Two layers of semi-transparent gradients is fine. Twelve layers of semi-transparent gradients is not
Whenever you add a transparency layer, you add another run of rendering to all the pixels in that layer. Doing that once or twice is fine… most machines can handle that. But when you have a bunch of them, you’re begging to bring the machine to a crawl. Look at the two gradients below…
The one on the right is a solid background with two transparent gradients (a light one at the top and a dark one on the bottom). The one on the left is a single gradient. The one on the right required three passes to render. The one on the left requires one.
This does not mean that you can never have transparency in your application. But if you can figure out an economy of layers when using transparency, you’ll save yourself from from developers who are willing to make the design trade off to speed up the application.
Tip 2: The Grid layout is your new best friend. Understand it. Use it. Love it.
I once worked with a designer who used Blend and made the most beautiful screens with it. But when it came to implement his designs, the developers ended up ditching most of his work because every element was inside a layout inside a layout inside a layout… etc. This ends up being a huge performance killer because every layout means another set of layout calculations for the layout manager.
Instead, make creative use of the Grid layout. Within the Grid layout, you can create columns and rows with the following options:
Auto (with Min/Max options) – This column will ask the items inside it how much room they need and will expand or contract to give them exactly the room they need and no more (within the min/max limits).
Fixed Width/Height (“80″) – A fixed height or width will take exactly that many pixels of space. Easy enough.
Star (“*”) (with Min/Max options ) – this can be used as a decimal or a percentage… “.8*” or “80*”. It asks the container holding it how much room it has. After the Auto and Fixed columns or rows allocate their needed space, the “*” ones take up all the remaining available space unless hindered by the min/max limits.
A single grid can use any number of rows and columns using any combination of Auto, Fixed and Star. You would be shocked at how flexible this is. You can build whole screens using a single grid. I don’t recommend that, but keep the idea of fewer layouts in mind when you are translating designs. Not every element in the project needs to be inside its own layout.
Tip 3: Use Borders, not Rectangles
Borders play nice with pretty much anything you want to do with the added benefit of being able to put stuff in it. Additionally, they are really simple layouts, so they don’t use much overhead. Take a border and put a Grid into it and you have a visually compelling and flexible combination.
Tip 4: Draw simple vector art inside Blend.
Mike Swanson has a fantastic Adobe Illustrator-to-XAML plug-in. I’ve heard that some people can use Expression Design quite well. But unless your project is extremely visual in an artsy kind of way, you should just draw simple vector art inside Blend. Not only will you save yourself the exporting-importing trouble, your XAML will look nicer and be easier to change later on.
I usually draw with the pen tool inside a Grid layout and then use the direct selection tool to make the tweaks I need.
Tip 5: (Silverlight Only) Plan on using only a few fonts
Most of my experience with fonts in Silverlight have been somewhat painful. Hopefully we’ll see that change in Silverlight 3, but in the meantime it is something that I’ve seen even experienced developers fight with. Watch this video by Tim Heuer… it will help. () And put this blog on your RSS feed… I’m working on a step-by-step tutorial for this geared at non-developers.
Tip 6: Work in “Split” mode in Blend and goof around with the XAML every now and again
Blend as a drag-and-drop design tool is absurdly powerful. Using Blend, you could build an interactive wireframe prototype in 15 minutes and never touch a line of code.
But as awesome as it is, it will be necessary from time to time to go into the XAML and tweak this or that or comment something out or copy-paste something else. Simply put, understanding XAML will make transitioning your designs a breeze and having Blend in “Split” mode will let you know just what your work in the design space is doing to the XAML. It’s a pretty painless way to start the XAML learning process.
If you’re interested in getting into the XAML a little more, I would recommend using Visual Studio 2008 in tandem with Blend. It offers intellisense (auto-complete for code) and integrates extremely well with Blend.
Hope that helps… If anyone has any questions, feel free to post them here. If you need more in-depth help, ping me at matthias dot shapiro (at) gmail dot com.
I finally got my MIX 10K Challenge submission up! For those of you who don’t know, the MIX 10K Challenge is a contest realted to the Microsoft MIX conference to create an application is 10K of code or less. There are all sorts of great prizes and I would really like one of them.
It’s called Zombie Zapper and I think it’s pretty cool. Sadly, I submitted it and then, while I waited for it to get accepted I made some tweaks that made it much better, so the older, not-as-good version is online there. You can play the refined version here.
The way this works is like so: The white boxes are like trampolines that you can control. When the zombies are walking on the trampoline, drag down on the white box and when you release it will propell the zombie into space.
Last night I submitted my MIX 10K Challenge piece, so I’m just killing time while I wait for it to get accepted. Please keep me in mind if you plan on voting.
OK… I’ve been excited about this for some time now. I found out (almost completely by accident) that you can animate a mask (also known as a clipping path) in Silverlight without writing code or even typing (much). This is exciting because I think it’s something that might interest our Flash friends who, late at night and in the privacy of their own homes, take a peek to see if Silverlight is worth looking into. When I worked with Flash, mask animations were my bread and butter and they seemed so hard to do in Silverlight.
But they’re not.
First open up your project in Blend. (I always create my project in Visual Studio and then open it in Blend because visual Studio has so much better project debugging and makes testing a breeze.)
Find the item you want to clip (in my case this is an image) and select the pen tool from the toolbar.
And start drawing.I’m a poor artist, so the star I drew looks pretty bad. If you need to change any of the points, use the direct selection tool (the light arrow, second from the top).
OK… now the fun part. Add a storyboard to your project
and you can animate the clipping mask using all the normal animation tools. Use the direct selection tool above to animate the vertices. You’ll get something like this:
Now… if you’re not interested in the details, just skip ahead a little bit. Something important happened the moment we started animating the path. Normally, path data is kept in a single string format that looks something like this:
This is actually a “powerful and complex mini-language that that you can use to describe geometric paths in XAML.” Microsoft uses it by default to handle path data. But it doesn’t work very well for animating paths, so the second you animate a single vertex in your path, it changes the format you see above to the format you see below:
Same data, but only this latter format is appropriate for animation. Remember this, it will come in handy in a second.
OK… now right click on your path and go to “Path –> Make Clipping Path”
You’ll get a dialog pop-up that will ask you which item in the visual tree you would like to clip. I chose my image, but it will work with anything.
And… poof! You have clipping animation.
LIMITATIONS: Here are the limitations to this method:
You need to animate before you make your path into a clipping path. – Remember that little bit above about the data string format vs. path geometry? If you don’t animate before hand, Blend will convert all your beautiful line segments into the un-animate-able data string. Animating the path tells Blend to leave your formatting alone.
Once you make your path a clipping path, animation gets a lot harder – Basically, you can change the time by dragging the key frames around and change the easing. Any other alterations require entering values by hand. So do all your animation first before setting the path. The easiest work around to this is to copy and paste your path out of the Control.Clip section and back into your main XAML and tweak animation from there. But your best option is to just take the time to make your clipping animation perfect before you make it a clipping path.
Seeing as how I’ve already spent far too much time on this little project, barring major problems with this control (please point them out!) this will probably be my last version of the control. My ADD is kicking in and I need to work on something else.
If you’re interested in having the compact version of this control as a gadget, you can find it here.
To add this to your application, just add the DLL above to your application by right clicking on the References folder in your Silverlight app.
Find the DLL and bring it into the application.
Open up the asset library (the bottom of the tool bar on the far left) and go to “Custom Controls”. You should find the ColorPicker in there.
Now you can just draw the whole thing right into your application.
Easy as pie.
You can swap between an extended view and a compact view by changing the “IsCompact” property. Compact view is basically gadget sized and expanded view can be as big as the screen if you want it to be.
Whenever you change the color, the control fires off a “ColorChanged” event. I thought that would be valuable for dynamic interactions. Hopefully you can find some fun uses for it.
Ha, fooled you! This is actutally how to write a custom event (with event handlers and everything!) in C#, but it turns out that you don’t need to change a damn thing about it to get it to work in Silverlight. (It’s always the “what do I have to change?” question that stumps me.)
I know that this is old hat for you seasoned developers out there, but it was news to me… and vitally important for updating my color picker project.
Anyway, it unsurprisingly comes from O’Reilly. If you are so inclined, you can go check it out.
Warning: This is a poor solution if your gadget has any level of dragging interaction in it. The “windowless=true” step will make it so that any dragging interaction will be interrupted by the gadget, which will interpret such a move as an attempt to drag the gadget off the side bar.
Giving your Silverlight gadget a transparent background is actually quite simple. First, follow the directions from Chris Szurgot’s post on Silverlight gadgets. No point in duplicating his work.
Take note: If you plan on using any level of dragging in your gadget (like I use), I would recommend against planning on having anything transparent. The only way I can get it to work is if you make the Silverlight object windowless. An unfortunate side effect is that it looks like this also intercepts any sort of MouseDrag event and interprets it as “the user wants to move the gadget off the sidebar”. For me, this meant that I couldn’t commit to any action on my color picker since the whole thing was interacted via dragging.
Next, if you want to see a handle for your gadget (pictured below), you need to do one of two things.
The first is that if you host your application online and add the silverlight app via an <iframe />. For reasons that boggle my mind at 11PM, this works. The downside is that if your user is not connected to the internet when they boot their machine, they will be unable to use your gadget.
The other solution is to give your application some room to breathe in the html page. Basically, make the body size in your gadget larger than your silverlight app. When the user hovers over something that isn’t Silverlight, the handle will appear. But if you fill the whole gadget space with Silverlight, your app will block any indication that the mouse is hovering over it.
For a working sample, download my Color Picker Gadget as an example. Just download it, rename it from *.gadget to *.zip and extract all the files I used.
I’ve finally updated my Silverlight color picker and it was none too soon, if you ask me. I’ve been missing this thing ever since the last compatibility break. Here you can download the source.
As you can see, I’ve updated a number of things, not the least of which was the fact that I was using a slider for the hue to the right in the old version. The new one uses an interface of my own because the slider wasn’t flexible enough for what I needed.
I also added functionality so that clicking on the color boxes selects all the text. I have a blog post on how to do that if you’re so inclined.
I’ve made some discoveries regarding creating Silverlight gadgets, but that is a post in and of itself. It’s coming.