New version of Flot is out. See the changes.
The big news is support for mouse tracking and highlighting points. So you can make the plots much more interactive. Also included is support for dual axes and improved background markings, and a long list of bug fixes, the most noticeable probably being that timestamps are now interpreted according to UTC instead of the local time zone of the client.
Thursday, September 25, 2008
Saturday, September 20, 2008
Consensus decision making
Is that crazy? Maybe not. Is a good manager the person who makes the decisions or the person who makes sure he doesn't?
The abysmal state of web layout technology - or not?
This post is about CSS and HTML.
Coming from a desktop application programming background, the web platform is actually pretty flexible and concise. Customized layouts can be done with remarkably simple markup and a bit of separate style information.
The big problem with the web is that HTML and CSS is designed for pages with a single stream of information, like a manual or a scientific article about an experiment in physics. Or a Wikipedia article. To layout another stream of information, like say something as exotic as a navigation bar, you basically have to use a hack which requires you to understand some pretty complicated concepts about HTML box layout or turn the markup into an unmanageable table hell.
I've been integrating a design for an internal web application for a customer the last couple of days. The thing about CSS is that apart from the problem with multiple streams of information, it's usually quite straightforward to work with. As long as you stick to the HTML mindset of how the world looks like.
The basic building block in this design is boxes (fine, HTML layout is about boxes) with shadows (urgh, no support for that) and rounded edges (double urgh, no support for that either) and shiny buttons (no built-in support for shininess). Clean markup out of the window, table soup and images to the rescue. Matters is made worse by unstable rendering by a certain browser which is a disaster for a box where the visual effect depends of getting the edges exactly right.
The most annoying thing about this is perhaps that if just someone had put multiple background image support into CSS, then I could have my clean markup back and get over this in no time. I was thinking about this earlier today, and even got so far as to have a simple draft proposal for fixing this case. I was determined to submit it to whoever is in charge of CSS and push for its inclusion.
But upon investigation, it turns out that a solution has already been proposed and written into the CSS draft specification years ago as
Apparently, the situation with respect to adoption has been dead-locked for a long time. The spec can't be made final until at least two different renderings engines have implemented it. And the rendering engines can't implement them for real before the spec is final. So it's going to take some determination to get going with proprietary attributes to begin with. Luckily it appears that 2008 is the year that the push is finally happening.
So there you are. It will change someday. I think this is typical of the web. There's some really good stuff in it, and a whole slew of annoyances. But they're going away, slowly.
Coming from a desktop application programming background, the web platform is actually pretty flexible and concise. Customized layouts can be done with remarkably simple markup and a bit of separate style information.
The big problem with the web is that HTML and CSS is designed for pages with a single stream of information, like a manual or a scientific article about an experiment in physics. Or a Wikipedia article. To layout another stream of information, like say something as exotic as a navigation bar, you basically have to use a hack which requires you to understand some pretty complicated concepts about HTML box layout or turn the markup into an unmanageable table hell.
I've been integrating a design for an internal web application for a customer the last couple of days. The thing about CSS is that apart from the problem with multiple streams of information, it's usually quite straightforward to work with. As long as you stick to the HTML mindset of how the world looks like.
The basic building block in this design is boxes (fine, HTML layout is about boxes) with shadows (urgh, no support for that) and rounded edges (double urgh, no support for that either) and shiny buttons (no built-in support for shininess). Clean markup out of the window, table soup and images to the rescue. Matters is made worse by unstable rendering by a certain browser which is a disaster for a box where the visual effect depends of getting the edges exactly right.
The most annoying thing about this is perhaps that if just someone had put multiple background image support into CSS, then I could have my clean markup back and get over this in no time. I was thinking about this earlier today, and even got so far as to have a simple draft proposal for fixing this case. I was determined to submit it to whoever is in charge of CSS and push for its inclusion.
But upon investigation, it turns out that a solution has already been proposed and written into the CSS draft specification years ago as
border-image
. There's a nice overview on css3.info.Apparently, the situation with respect to adoption has been dead-locked for a long time. The spec can't be made final until at least two different renderings engines have implemented it. And the rendering engines can't implement them for real before the spec is final. So it's going to take some determination to get going with proprietary attributes to begin with. Luckily it appears that 2008 is the year that the push is finally happening.
So there you are. It will change someday. I think this is typical of the web. There's some really good stuff in it, and a whole slew of annoyances. But they're going away, slowly.
Friday, September 19, 2008
Listening to music and last.fm
Some time ago Anders created a last.fm group for YayArt. Anders showed me how Rhythmbox can integrate with last.fm, reporting in what I'm listening to. So I ended up creating a profile.
At first I find last.fm pretty confusing and leave it at that. A couple of days pass where I play music from my personal collection with Rhythmbox. Then I visit last.fm again. Behold, now it has lots of interesting suggestions. I just click "Play your recommendations" and I get a pretty varied assortment of music. You can control the stream to some degree by either hitting love or ban to what you're listening to.
There are some minor glitches, e.g. I yesterday loved too many film music pieces so it was getting a bit stuck on that kind of music until I started banning some of the pieces, but overall it's working incredibly well.
An interesting side effect is that you can listen to people's music taste. Now if I only knew someone on last.fm whose music taste I would like to listen to... My profile is here in case you want to listen to mine.
At first I find last.fm pretty confusing and leave it at that. A couple of days pass where I play music from my personal collection with Rhythmbox. Then I visit last.fm again. Behold, now it has lots of interesting suggestions. I just click "Play your recommendations" and I get a pretty varied assortment of music. You can control the stream to some degree by either hitting love or ban to what you're listening to.
There are some minor glitches, e.g. I yesterday loved too many film music pieces so it was getting a bit stuck on that kind of music until I started banning some of the pieces, but overall it's working incredibly well.
An interesting side effect is that you can listen to people's music taste. Now if I only knew someone on last.fm whose music taste I would like to listen to... My profile is here in case you want to listen to mine.
Tuesday, September 16, 2008
The role of culture - and what's an object?
I had an interesting thought today. Why do you eat of plates? Our dining table is covered by a fine oilcloth, why don't we eat of that?
The plain answer, I think, is that we've been taught when we were young to use plates, to the point that it even seems unhygienic not to do so. Imagine a dinner with meat, potatoes and a batch of sticky sauce on your dining table.
Image by ayalan
If you're looking for deeper reasons for why one eats of plates it's probably easy to find out. Just have a dinner directly on your table. I suspect the reasons have something to do with the difficulty of cleaning up afterwards and sharp knives and scratches in the surface.
Pottery is a pretty old technology. The point is that it's part of our culture, we never think about it, we just do it. But it's one of the million of things that make up the great technological advancements civilisation has made over the past centuries. If we weren't able to absorb them, if we had to think about all of them, we would never have gotten anywhere.
A similar thing goes on in software. With a programming language you can build anything you can think of, provided you have the hardware to run it on. But still it takes time to invent new things. Old things have to be absorbed into our culture before we can move on, otherwise the leap is too great.
Of course behaviours that once have been embedded might stop making sense as the environment changes, unnoticed. When you dig into it the reasons stop being reasonable. I think you'll find that traditions and rituals provide a rich source of examples of this phenomenon - it made sense to those who concocted it, but 50 years later it's really silly when you think about it. Of course, that might not stop you from enjoying it.
Image by Thomas Hawk
In any case, I think it's sometimes interesting to turn things we take for granted upside-down. Today I've been thinking about the corner stone of object-oriented programming. Let's be pragmatic. What's an object?
You might think of attributes and methods. My take on it is that it depends.
In some types of code, it's a very useful modeling utility.
For instance, just think of the string class in your favourite programming language. It encapsulates most of the stuff you'd want to do with a string in a neat little package you can easily instantiate as many of as you like. If you've ever tried the horror that is the built-in string handling in the C standard library (not to pick on it, it was probably fine for its time), you'll really appreciate that. You might miss the occasional method or two, but still, it's very useful and easy to understand.
Library code is full of neat little packages like this. Dynamic arrays, linked lists, HTTP handling, database connections, widgets in a graphical toolkit.
As you go to application code, the answer is in many cases less clear cut. To a certain extent, this is perhaps because the concepts are less understood or perhaps just less well-defined.
In my applications I find that I have objects that are more or less just data (plain old data, PODs as they call them in C++ lingo) and objects that aren't really objects that I instantiate, let do a well-defined job and then throw away, but more of the sort of puppeteers or glue. These are all objects that give me head-aches. I also find some objects that are like the library objects, neat little packages. These are usually a great relief.
The first type of objects, typical application objects, are troublesome because they go against the culture of object-oriented programming. Which says that you shall divide your code into neat little interacting packages with methods and encapsulated attributes, instantiated and used dynamically.
But if we step back, then what's the purpose of objects? As I see it, it's a way of organising code. Think of it as a hierarchy. At the lowest level, you have the individual lines of code. We organise them into functions which let us deal with perhaps 10-100 times the amount of code, still maintaining an overview, like the headlines in a newspaper that groups the thousands of lines of text into articles.
Image by jurvetson
As a program grows, you need another level, one that will give you 10-100 more code without losing the grip of the program. This is plain hierarchy theory. Look at the folders on your computer for a prime example. An object is one such next level, one that is more flexible out of the box than traditional function library modules because it has state.
However, just because you need another level, it doesn't mean that the code will fit well into the object-oriented thinking of a neat little package where the data is encapsulated inside. I personally think it's impossible in many applications; otherwise it's going to take a lot of hard thinking, and I mean really a lot, because I have often wasted hours trying to find a way out of my crippled semi-objects.
It is true for the plain old data structures. In many cases, you just need to group a set of attributes under a name without the functionality making use of the attributes logically or even illogically belonging to the grouping. So just put them in, recognising this as a case where the object thinking is useful but not a 100% fit.
If you're writing getters and setters for this kind of stuff, you're wasting your time serving the culture of object-oriented programming as it was taught to you.
The same goes for glue code. It may organise the code better to put it inside an object. If so, go for it even if you're never going to do typical object stuff with it.
In any case, as I see it the goal here is a well-organised program. A well-organised program is obviously easier to understand, and thus easier to work with, extend, fix bugs in, etc. Think about that and forget culture next time your wrestle with program design and nothing seems right.
The plain answer, I think, is that we've been taught when we were young to use plates, to the point that it even seems unhygienic not to do so. Imagine a dinner with meat, potatoes and a batch of sticky sauce on your dining table.
Image by ayalan
If you're looking for deeper reasons for why one eats of plates it's probably easy to find out. Just have a dinner directly on your table. I suspect the reasons have something to do with the difficulty of cleaning up afterwards and sharp knives and scratches in the surface.
Pottery is a pretty old technology. The point is that it's part of our culture, we never think about it, we just do it. But it's one of the million of things that make up the great technological advancements civilisation has made over the past centuries. If we weren't able to absorb them, if we had to think about all of them, we would never have gotten anywhere.
A similar thing goes on in software. With a programming language you can build anything you can think of, provided you have the hardware to run it on. But still it takes time to invent new things. Old things have to be absorbed into our culture before we can move on, otherwise the leap is too great.
Of course behaviours that once have been embedded might stop making sense as the environment changes, unnoticed. When you dig into it the reasons stop being reasonable. I think you'll find that traditions and rituals provide a rich source of examples of this phenomenon - it made sense to those who concocted it, but 50 years later it's really silly when you think about it. Of course, that might not stop you from enjoying it.
Image by Thomas Hawk
In any case, I think it's sometimes interesting to turn things we take for granted upside-down. Today I've been thinking about the corner stone of object-oriented programming. Let's be pragmatic. What's an object?
You might think of attributes and methods. My take on it is that it depends.
In some types of code, it's a very useful modeling utility.
For instance, just think of the string class in your favourite programming language. It encapsulates most of the stuff you'd want to do with a string in a neat little package you can easily instantiate as many of as you like. If you've ever tried the horror that is the built-in string handling in the C standard library (not to pick on it, it was probably fine for its time), you'll really appreciate that. You might miss the occasional method or two, but still, it's very useful and easy to understand.
Library code is full of neat little packages like this. Dynamic arrays, linked lists, HTTP handling, database connections, widgets in a graphical toolkit.
As you go to application code, the answer is in many cases less clear cut. To a certain extent, this is perhaps because the concepts are less understood or perhaps just less well-defined.
In my applications I find that I have objects that are more or less just data (plain old data, PODs as they call them in C++ lingo) and objects that aren't really objects that I instantiate, let do a well-defined job and then throw away, but more of the sort of puppeteers or glue. These are all objects that give me head-aches. I also find some objects that are like the library objects, neat little packages. These are usually a great relief.
The first type of objects, typical application objects, are troublesome because they go against the culture of object-oriented programming. Which says that you shall divide your code into neat little interacting packages with methods and encapsulated attributes, instantiated and used dynamically.
But if we step back, then what's the purpose of objects? As I see it, it's a way of organising code. Think of it as a hierarchy. At the lowest level, you have the individual lines of code. We organise them into functions which let us deal with perhaps 10-100 times the amount of code, still maintaining an overview, like the headlines in a newspaper that groups the thousands of lines of text into articles.
Image by jurvetson
As a program grows, you need another level, one that will give you 10-100 more code without losing the grip of the program. This is plain hierarchy theory. Look at the folders on your computer for a prime example. An object is one such next level, one that is more flexible out of the box than traditional function library modules because it has state.
However, just because you need another level, it doesn't mean that the code will fit well into the object-oriented thinking of a neat little package where the data is encapsulated inside. I personally think it's impossible in many applications; otherwise it's going to take a lot of hard thinking, and I mean really a lot, because I have often wasted hours trying to find a way out of my crippled semi-objects.
It is true for the plain old data structures. In many cases, you just need to group a set of attributes under a name without the functionality making use of the attributes logically or even illogically belonging to the grouping. So just put them in, recognising this as a case where the object thinking is useful but not a 100% fit.
If you're writing getters and setters for this kind of stuff, you're wasting your time serving the culture of object-oriented programming as it was taught to you.
The same goes for glue code. It may organise the code better to put it inside an object. If so, go for it even if you're never going to do typical object stuff with it.
In any case, as I see it the goal here is a well-organised program. A well-organised program is obviously easier to understand, and thus easier to work with, extend, fix bugs in, etc. Think about that and forget culture next time your wrestle with program design and nothing seems right.
Sunday, September 14, 2008
Weird web troubles
No, I'm not dead yet. I have even been doing some of the maintainer tasks for Flot I have neglected the past months.
One of the new things in Flot is support for hovering/clicking with the mouse on the points. I was spending some time yesterday adding highlights so that Flot can show which point you're pointing the mouse at.
I got to the point that I was ready to performance test it, on my trusty old Pentium 3 950 MHz laptop. It felt a bit slow. Surprisingly, the profile from Firebug indicated that the slow function was the jQuery function
I use it to compute where a mouse event is inside the plotting canvas - for some reason computing this offset separately is the only reliable way to know where the mouse is inside the element where the event happened because you only get the global coordinates reliably in the event. You would have thought local coordinates was a natural thing to standardize and every browser support, but no.
Anyway,
The funny thing is that I was meanwhile updating my system, apparently also updating Firefox from 2.x to 3.0.1. So when I boot up today with a couple of ideas for working around the slow offset function, it's now 4 ms on average. That's still far too much for querying a simple DOM tree, but it's not a show stopper anymore.
I think the lesson here is that as soon as you do exotic things in the browser, things that are not really about browsing HTML pages, you get bitten by weird bugs. But the state of affairs is improving.
Pssst. We're having a sale on YayArt. I have it from a reliable source that it's going to end soon.
One of the new things in Flot is support for hovering/clicking with the mouse on the points. I was spending some time yesterday adding highlights so that Flot can show which point you're pointing the mouse at.
I got to the point that I was ready to performance test it, on my trusty old Pentium 3 950 MHz laptop. It felt a bit slow. Surprisingly, the profile from Firebug indicated that the slow function was the jQuery function
offset()
.I use it to compute where a mouse event is inside the plotting canvas - for some reason computing this offset separately is the only reliable way to know where the mouse is inside the element where the event happened because you only get the global coordinates reliably in the event. You would have thought local coordinates was a natural thing to standardize and every browser support, but no.
Anyway,
offset()
walks up the DOM tree, computing offsets along the way. And it was taking 25 ms per invocation on average! That's just ridiculous.The funny thing is that I was meanwhile updating my system, apparently also updating Firefox from 2.x to 3.0.1. So when I boot up today with a couple of ideas for working around the slow offset function, it's now 4 ms on average. That's still far too much for querying a simple DOM tree, but it's not a show stopper anymore.
I think the lesson here is that as soon as you do exotic things in the browser, things that are not really about browsing HTML pages, you get bitten by weird bugs. But the state of affairs is improving.
Pssst. We're having a sale on YayArt. I have it from a reliable source that it's going to end soon.
Subscribe to:
Posts (Atom)