Showing posts with label data presentation. Show all posts
Showing posts with label data presentation. Show all posts

Monday, July 27, 2009

New fclib and dcflash releases

A few days ago I updated my dcflash project on SourceForge. This is an open source (MIT license) actionscript library, with a data visualization emphasis:
http://sourceforge.net/projects/dcflash/

In particular there is now an AS3 version. In fact the AS2 and AS3 releases currently have only a couple of classes in common. The AS3 classes are mostly for loading images, movies, and setting up slideshows; none of the chart classes from the AS2 version (or the only partially ported and unreleased AS1 library) are there yet. As I say in the release notes, I'm open to offers to port them to AS3. (A look at http://dcook.org/work/charts/ will show you the kind of things in the AS1 and AS2 libraries.)

And now today I've put up a new release of fclib. This is an open source (MIT license again) PHP library. Fairly ad hoc, but naturally lots of internationalization-related classes. The new 0.4.19 release contains some arabic classes, but other than that it is mostly just tweaks and small improvements:
http://dcook.org/software/fclib/

Tuesday, April 14, 2009

Excel and PDF from PHP

Been meaning to post this for ages, but PHP Architect magazine for November 2008 had a useful article on libraries and code for alternatives to HTML.

For PDF html2pdf was introduced. Unlike other PHP PDF libraries (e.g. PDFLib, FPDF) this one has you make your content in HTML then it gets converted. For those of us comfortable with HTML, that means no learning curve.

For Excel, PHPExcel is introduced. This has classes to read and write excel files in a variety of formats. I get this request a lot but so far we have always decided outputting good old CSV is best (simple to make, compact, easy to import into Excel). But if complex layout, or built-in functions, are required this looks worth a look. It can also output into PDF.

Also very interesting is in-memory spreadsheets, with lots of mathematical functions supported. I've not tried it, and neither the article or the website mention explicitly if this will work on Linux (or a Windows machine without Excel installed), but it is described as standalone so it should. It might be an interesting way to port someones spreadsheet to a PHP app!

The article also briefly introduces Google charts, and how to include the produced image in your excel file.

Tuesday, November 4, 2008

PHP and outputting floats

I was writing a script in PHP to compare two data sources, and in the report I was outputting using code like this:
echo "A={$vA}, B={$vB}\n";

What was strange is I was getting entries like
A=3.4E+6, B=340000
A=1.4E+6, B=1500000
A=2146666.66667, B=2.3E+6

My first guess was some data was int, so I added asserts for that, but, no, everything is float.

As often happens, the answer was to be found in the user contributed notes in the PHP online manual: http://jp.php.net/manual/en/language.types.float.php#83577

I just have to repeat his final sentence: I have to be honest: this is one of the strangest things I have seen in any language in over 20 years of coding, and it is a colossal pain to work around.

Also in the notes are complaints that output of floating point numbers uses the locale. Using number_format is one solution for that, or using %F in sprintf is also locale-independent apparently. So my code becomes:
echo sprintf("A=%F, B=%F\n",$vA,$vB);

Unfortunately that now gives me entries like:
A=481.000000,B=1150000.000000

I have hit this zero-noise issue using sprintf in C++ too.

So here is my solution (be aware that this adds CPU cycles):

/**
* Format a float, only showing significant decimal places
*
* @param float $v
* @return String
*/
function fmt_float($v){
$s=(string)$v;
if(strpos($s,'E+')===false)return $s;
$s=sprintf("%.9F",$v); //Write with all decimal places
$s=rtrim($s,'0'); //Chop off trailing zeroes
$s=rtrim($s,'.'); //Chop off decimal point if it is left at the end.
return $s;
}
...
echo "A=".fmt_float($vA).", B=".fmt_float($vB)."\n";

I'll throw that into the next fclib release. Can anyone make a better version?

Note: The first two lines mean use PHP's built-in float to string conversion by default and just use our own when it ended up in scientific notation. I found this gave better results (because using %.9F sometimes writes 120.0000000001 instead of simply 120.000000000, whereas the PHP built-in conversion is fine (giving "120") ). However if you also needed a locale-independent solution, then uncomment those first two lines (as PHP's built-in conversion uses locale).