Integrate supplier piechart
--- a/about.php
+++ b/about.php
@@ -19,13 +19,12 @@
orem ipsum dolor sit amet, consectetuer adipiscing elit orem ipsum dolor sit amet, consectetuer adipiscing elit
</div>
</div>
+<?php CNDistributionGraph(); ?>
+sourced from austender
-sourced from austender
Government Agency Information (2009-07-10): National Archives of Australia, http://www.naa.gov.au under Creative Commons - Attribution 2.5 Australia (CC-BY)
-jpgraph for php
+
ABR
-Redhat Liberation fonts
-
<?php
include_once("./lib/common.inc.php");
--- a/admin/displayUNSPSC.php
+++ /dev/null
@@ -1,24 +1,1 @@
-<?php
-error_reporting(E_ALL);
- include_once("../lib/common.inc.php");
-
-
-$unspscresult= $conn->prepare('select * from "UNSPSCcategories";');
-$unspscresult->execute();
-foreach ($unspscresult->fetchAll() as $row) {
- $unspsc[$row['UNSPSC']] = $row['Title'];
-
-}
-$catsresult = $conn->prepare('SELECT substr( "categoryUNSPSC"::text, 0, 2 ) as cat , SUM( "value" ) as value
-FROM contractnotice
-GROUP BY cat ;');
-echo "<table>";
-$catsresult->execute();
-foreach ($catsresult->fetchAll() as $row) {
- $catName = $unspsc[$row['cat']."0000000"].$row['cat'];
- if ($row['cat'] == "") $catName = "null";
-
- echo "<tr><td>$catName</td><td>".$row['value']."</td></tr>";
-}
-?>
--- a/admin/import.php
+++ b/admin/import.php
@@ -60,6 +60,7 @@
if (($datamapping0711[$headers[$c]]) == "parentCN" || ($datamapping0711[$headers[$c]]) == "CNID") {
$data[$c] = substr($data[$c], 2); // take off the "CN" prefix
$data[$c] = str_replace("-A","00",$data[$c]); // make amendments really big numbers
+ if (!is_numeric($data[$c])) die ($data[$c]." is not numeric");
if ($data[$c] > 0) {
$contractNoticeInsert[] = $data[$c];
} else {
@@ -166,5 +167,13 @@
echo "<br> $success records successfully created";
flush();
}
+ // run post import data processing
+ // cn
+ include("linkAmendments.php");
+ include("updateUNSPSC.php");
+// agency
+ include("setAgencyStatus.php");
+ include("setAgencyURLABN.php");
+
?>
--- a/admin/importUNSPSC.php
+++ b/admin/importUNSPSC.php
@@ -1,5 +1,26 @@
<?php
include_once("../lib/common.inc.php");
+
+ // display existing
+
+$unspscresult= $conn->prepare('select * from "UNSPSCcategories";');
+$unspscresult->execute();
+foreach ($unspscresult->fetchAll() as $row) {
+ $unspsc[$row['UNSPSC']] = $row['Title'];
+
+}
+$catsresult = $conn->prepare('SELECT substr( "categoryUNSPSC"::text, 0, 2 ) as cat , SUM( "value" ) as value
+FROM contractnotice
+GROUP BY cat ;');
+echo "<table>";
+$catsresult->execute();
+foreach ($catsresult->fetchAll() as $row) {
+ $catName = $unspsc[$row['cat']."0000000"].$row['cat'];
+ if ($row['cat'] == "") $catName = "null";
+
+ echo "<tr><td>$catName</td><td>".$row['value']."</td></tr>";
+}
+// import new from file
$success = 0;
$fname = "UNSPSC_ECCMA_V13.2_UNDP_V7.csv";
echo " ============== $fname ============== <br>";
--- a/admin/linkAmendments.php
+++ b/admin/linkAmendments.php
@@ -1,17 +1,22 @@
<?php
include_once ("../lib/common.inc.php");
-$query = 'SELECT "CNID","parentCN","amendmentReason" FROM contractnotice WHERE
-"parentCN" > 0 ';
+$query = 'SELECT c."CNID",c."parentCN",c."amendmentReason",p."childCN" FROM contractnotice as c LEFT OUTER JOIN contractnotice as p on c."parentCN" = p."CNID"
+WHERE
+c."parentCN" > 0 AND p."childCN" IS NULL ';
$query = $conn->prepare($query);
$query->execute();
if (!$query) {
databaseError($conn->errorInfo());
}
foreach ($query->fetchAll() as $row) {
- $conn->exec('UPDATE contractnotice SET childCN = "' .
- $row['CNID'] . '", amendmentReason = "' .
- $row['amendmentReason'] . '" where "CNID" = "' .
- $row['parentCN'] . '";');
+ $conn->exec('UPDATE contractnotice SET "childCN" = \'' .
+ $row['CNID'] . '\', "amendmentReason" = \'' .
+ $row['amendmentReason'] . '\' where "CNID" = \'' .
+ $row['parentCN'] . '\';');
+ echo 'UPDATE contractnotice SET "childCN" = \'' .
+ $row['CNID'] . '\', "amendmentReason" = \'' .
+ $row['amendmentReason'] . '\' where "CNID" = \'' .
+ $row['parentCN'] . '\';';
$errors = $conn->errorInfo();
if ($errors[1] == 7 || $errors[1] ==0)
@@ -20,4 +25,5 @@
else print_r($errors);
}
+// also need to eliminate CN 100528/100529 - check for double parent CNs with no childCN, latest sequent CN id wins childCN = 0
?>
--- a/displayAgency.php
+++ b/displayAgency.php
@@ -4,9 +4,9 @@
include_header("Agency");
$agency = htmlentities(strip_tags($_REQUEST['agency']));
- echo '<img src="graphs/displayMethodCountGraph.php?agency=' . stripslashes($agency) . '">';
- echo '<img src="graphs/displayCnCGraph.php?agency=' . stripslashes($agency) . '">';
- echo '<img src="graphs/displayMethodValueGraph.php?agency=' . stripslashes($agency) . '">';
+ MethodCountGraph($agency);
+ CnCGraph($agency);
+ MethodValueGraph($agency);
/*biggest contracts
spending by year
spending by industry/category
@@ -63,6 +63,7 @@
split by portfolio
*/
include_header("Agencies");
+agenciesGraph();
$query = 'SELECT SUM("value"), "agencyName"
FROM contractnotice
WHERE "childCN" = 0
--- a/displayCalendar.php
+++ b/displayCalendar.php
@@ -6,15 +6,23 @@
if ($_REQUEST['month']) {
echo "<center><h1>".$_REQUEST['month']."</h1></center>";
$monthParts = explode("-",$_REQUEST['month']);
- $query = "SELECT CNID, description, value, agencyName, category, contractStart, supplierName
- FROM `contractnotice`
- WHERE childCN = 0
- AND YEAR(contractStart) = {$monthParts[1]}
- AND MONTH(contractStart) = {$monthParts[0]}
- ORDER BY value DESC";
- $result = mysql_query($query);
-echo '<img src="graphs/displayMethodCountGraph.php?month=' . stripslashes($supplier) . '">';
- echo '<img src="graphs/displayCnCGraph.php?month=' . stripslashes($supplier) . '">';
+ $query = 'SELECT "CNID", "description", "value", "agencyName", "category", "contractStart", "supplierName"
+ FROM contractnotice
+ WHERE "childCN" = 0
+ AND extract(year from "contractStart") = :year
+ AND extract(month from "contractStart") = :month
+ ORDER BY value DESC';
+$query = $conn->prepare($query);
+$query->bindParam(":month", $monthParts[0]);
+
+$query->bindParam(":year", $monthParts[1]);
+ $query->execute();
+ if (!$query) {
+ databaseError($conn->errorInfo());
+ }
+
+MethodCountGraph($supplier);
+CnCGraph($supplier);
echo "<table> <thead>
<tr>
@@ -26,7 +34,7 @@
<th>Supplier</th>
</tr>
</thead>";
- while ($row = mysql_fetch_array($result, MYSQL_BOTH)) {
+ foreach ($query->fetchAll() as $row) {
setlocale(LC_MONETARY, 'en_US');
$value = number_format(doubleval($row['value']) , 2);
echo ("<tr>
@@ -52,10 +60,14 @@
echo '<img src="graphs/displayContractPublishedGraph.php">';
-$query = "SELECT YEAR(contractStart), MONTH(contractStart),
-SUM(value) as val, count(1) as count FROM `contractnotice` WHERE childCN = 0 GROUP BY MONTH(contractStart), YEAR(contractStart) ORDER BY YEAR(contractStart), MONTH(contractStart) ";
+$query = 'SELECT extract(year from "contractStart"), extract(month from "contractStart"),
+SUM(value) as val, count(1) as count FROM contractnotice WHERE "childCN" = 0 GROUP BY extract(year from "contractStart"), extract(month from "contractStart") ORDER BY extract(year from "contractStart"), extract(month from "contractStart") ';
+$query = $conn->prepare($query);
+ $query->execute();
+ if (!$query) {
+ databaseError($conn->errorInfo());
+ }
-$result = mysql_query($query);
echo "<table> <thead>
<tr>
<th>Month/Year</th>
@@ -63,7 +75,7 @@
<th>Number of Contracts</th>
</tr>
</thead>";
-while ($row = mysql_fetch_array($result, MYSQL_BOTH)) {
+ foreach ($query->fetchAll() as $row) {
setlocale(LC_MONETARY, 'en_US');
$value = number_format(doubleval($row["val"]),2);
$month_name = date( 'F', mktime(0, 0, 0, $row[1]) );
--- a/displayHeatmap.php
+++ b/displayHeatmap.php
@@ -1,7 +1,7 @@
<?php
-include('../lib/common.inc.php');
+include('lib/common.inc.php');
$year = 2006;
$ZeroX = 112.5;
@@ -22,12 +22,17 @@
$height = 457;
//echo "http://dev.openstreetmap.org/~pafciu17/?module=map&bbox=".$ZeroX.",".$ZeroY.",".$MaxX.",".$MaxY."&width=".$width."&height=".$height;
//$handle = ImageCreate ($width, $height) or die ("Cannot Create image");
-$handle = imagecreatefrompng('../images/australia.png');
+$handle = imagecreatefrompng('images/australia.png');
$white = imagecolorallocate($handle, 0, 0, 0);
imagecolortransparent($handle, $white);
-$query = "SELECT supplierPostcode, sum(value) as value, lat, lon FROM `contractnotice`,`postcodes` where childCN = 0 AND supplierCountry = 'Australia' AND YEAR(contractStart) >= '$year' AND supplierPostcode = postcode GROUP BY supplierPostcode";
-$result = mysql_query($query);
+$query = 'SELECT "supplierPostcode", sum("value") as value, max(lat) as lat, max(lon) as lon FROM contractnotice inner join postcodes on "supplierPostcode" = postcode::text where "childCN" = 0 AND "supplierCountry" = \'Australia\' GROUP BY "supplierPostcode"';
+$query = $conn->prepare($query);
+ $query->execute();
+ if (!$query) {
+ databaseError($conn->errorInfo());
+ }
+
$left = "FFFF50";
$right= "EF0050";
@@ -41,8 +46,7 @@
$colorset[$i] = imagecolorallocatealpha($handle, $leftR + ($i*(($rightR-$leftR)/250)), $leftG + ($i*(($rightG-$leftG)/250)), $leftB + ($i*(($rightB-$leftB)/250)),117 - ($i/250)*40);
}
-while ($row = mysql_fetch_array($result, MYSQL_BOTH))
-{
+ foreach ($query->fetchAll() as $row) {
$xpage = round((($XRange - ($MaxX - $row['lon'])) / $xdivlength));
if ($row['lat'] < -40.25) $row['lat']-= 0.75;
$ypage = round(($YRange - (abs($MaxY) - abs($row['lat']))) / $ydivheight);
--- a/displaySupplier.php
+++ b/displaySupplier.php
@@ -4,9 +4,9 @@
include_header("Supplier");
$supplierS = htmlentities(strip_tags($_REQUEST['supplier']));
- echo '<img src="graphs/displayMethodCountGraph.php?supplier=' . stripslashes($supplierS) . '">';
- echo '<img src="graphs/displayCnCGraph.php?supplier=' . stripslashes($supplierS) . '">';
- echo '<img src="graphs/displayMethodValueGraph.php?supplier=' . stripslashes($supplierS) . '">';
+ MethodCountGraph($supplierS);
+ CnCGraph($supplierS);
+ MethodValueGraph($supplierS);
/*lobbyist ties
links to ABR/ASIC/Google News/ASX/Court records
@@ -62,6 +62,7 @@
histograph of supplier size/value
*/
include_header("Suppliers");
+suppliersGraph();
$query = 'SELECT SUM("value") as val, MAX("supplierName") as supplierName, "supplierABN",(
case when "supplierABN" != 0 THEN "supplierABN"::text ELSE "supplierName" END) as supplierID
FROM contractnotice
--- a/lib/common.inc.php
+++ b/lib/common.inc.php
@@ -207,5 +207,6 @@
echo '<div id="ft"><p>'."Processing time: ". sprintf("%.4f", ($end-$start))." seconds".'</p></div>';
echo '</div> </body> </html>';
}
+include ("graphs.inc.php");
?>
--- /dev/null
+++ b/lib/flot/excanvas.js
@@ -1,1 +1,1428 @@
-
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// Known Issues:
+//
+// * Patterns only support repeat.
+// * Radial gradient are not implemented. The VML version of these look very
+// different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+// width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+// Quirks mode will draw the canvas using border-box. Either change your
+// doctype to HTML5
+// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+// or use Box Sizing Behavior from WebFX
+// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Non uniform scaling does not correctly scale strokes.
+// * Filling very large shapes (above 5000 points) is buggy.
+// * Optimize. There is always room for speed improvements.
+
+// Only add this code if we do not already have a canvas implementation
+if (!document.createElement('canvas').getContext) {
+
+(function() {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+ var abs = m.abs;
+ var sqrt = m.sqrt;
+
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
+
+ /**
+ * This funtion is assigned to the <canvas> elements as element.getContext().
+ * @this {HTMLElement}
+ * @return {CanvasRenderingContext2D_}
+ */
+ function getContext() {
+ return this.context_ ||
+ (this.context_ = new CanvasRenderingContext2D_(this));
+ }
+
+ var slice = Array.prototype.slice;
+
+ /**
+ * Binds a function to an object. The returned function will always use the
+ * passed in {@code obj} as {@code this}.
+ *
+ * Example:
+ *
+ * g = bind(f, obj, a, b)
+ * g(c, d) // will do f.call(obj, a, b, c, d)
+ *
+ * @param {Function} f The function to bind the object to
+ * @param {Object} obj The object that should act as this when the function
+ * is called
+ * @param {*} var_args Rest arguments that will be used as the initial
+ * arguments when the function is called
+ * @return {Function} A new function that has bound this
+ */
+ function bind(f, obj, var_args) {
+ var a = slice.call(arguments, 2);
+ return function() {
+ return f.apply(obj, a.concat(slice.call(arguments)));
+ };
+ }
+
+ function encodeHtmlAttribute(s) {
+ return String(s).replace(/&/g, '&').replace(/"/g, '"');
+ }
+
+ function addNamespacesAndStylesheet(doc) {
+ // create xmlns
+ if (!doc.namespaces['g_vml_']) {
+ doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
+ '#default#VML');
+
+ }
+ if (!doc.namespaces['g_o_']) {
+ doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
+ '#default#VML');
+ }
+
+ // Setup default CSS. Only add one style sheet per document
+ if (!doc.styleSheets['ex_canvas_']) {
+ var ss = doc.createStyleSheet();
+ ss.owningElement.id = 'ex_canvas_';
+ ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
+ // default size is 300x150 in Gecko and Opera
+ 'text-align:left;width:300px;height:150px}';
+ }
+ }
+
+ // Add namespaces and stylesheet at startup.
+ addNamespacesAndStylesheet(document);
+
+ var G_vmlCanvasManager_ = {
+ init: function(opt_doc) {
+ if (/MSIE/.test(navigator.userAgent) && !window.opera) {
+ var doc = opt_doc || document;
+ // Create a dummy element so that IE will allow canvas elements to be
+ // recognized.
+ doc.createElement('canvas');
+ doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
+ }
+ },
+
+ init_: function(doc) {
+ // find all canvas elements
+ var els = doc.getElementsByTagName('canvas');
+ for (var i = 0; i < els.length; i++) {
+ this.initElement(els[i]);
+ }
+ },
+
+ /**
+ * Public initializes a canvas element so that it can be used as canvas
+ * element from now on. This is called automatically before the page is
+ * loaded but if you are creating elements using createElement you need to
+ * make sure this is called on the element.
+ * @param {HTMLElement} el The canvas element to initialize.
+ * @return {HTMLElement} the element that was created.
+ */
+ initElement: function(el) {
+ if (!el.getContext) {
+ el.getContext = getContext;
+
+ // Add namespaces and stylesheet to document of the element.
+ addNamespacesAndStylesheet(el.ownerDocument);
+
+ // Remove fallback content. There is no way to hide text nodes so we
+ // just remove all childNodes. We could hide all elements and remove
+ // text nodes but who really cares about the fallback content.
+ el.innerHTML = '';
+
+ // do not use inline function because that will leak memory
+ el.attachEvent('onpropertychange', onPropertyChange);
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + 'px';
+ } else {
+ el.width = el.clientWidth;
+ }
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + 'px';
+ } else {
+ el.height = el.clientHeight;
+ }
+ //el.getContext().setCoordsize_()
+ }
+ return el;
+ }
+ };
+
+ function onPropertyChange(e) {
+ var el = e.srcElement;
+
+ switch (e.propertyName) {
+ case 'width':
+ el.getContext().clearRect();
+ el.style.width = el.attributes.width.nodeValue + 'px';
+ // In IE8 this does not trigger onresize.
+ el.firstChild.style.width = el.clientWidth + 'px';
+ break;
+ case 'height':
+ el.getContext().clearRect();
+ el.style.height = el.attributes.height.nodeValue + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ break;
+ }
+ }
+
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
+ G_vmlCanvasManager_.init();
+
+ // precompute "00" to "FF"
+ var decToHex = [];
+ for (var i = 0; i < 16; i++) {
+ for (var j = 0; j < 16; j++) {
+ decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
+ }
+ }
+
+ function createMatrixIdentity() {
+ return [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ];
+ }
+
+ function matrixMultiply(m1, m2) {
+ var result = createMatrixIdentity();
+
+ for (var x = 0; x < 3; x++) {
+ for (var y = 0; y < 3; y++) {
+ var sum = 0;
+
+ for (var z = 0; z < 3; z++) {
+ sum += m1[x][z] * m2[z][y];
+ }
+
+ result[x][y] = sum;
+ }
+ }
+ return result;
+ }
+
+ function copyState(o1, o2) {
+ o2.fillStyle = o1.fillStyle;
+ o2.lineCap = o1.lineCap;
+ o2.lineJoin = o1.lineJoin;
+ o2.lineWidth = o1.lineWidth;
+ o2.miterLimit = o1.miterLimit;
+ o2.shadowBlur = o1.shadowBlur;
+ o2.shadowColor = o1.shadowColor;
+ o2.shadowOffsetX = o1.shadowOffsetX;
+ o2.shadowOffsetY = o1.shadowOffsetY;
+ o2.strokeStyle = o1.strokeStyle;
+ o2.globalAlpha = o1.globalAlpha;
+ o2.font = o1.font;
+ o2.textAlign = o1.textAlign;
+ o2.textBaseline = o1.textBaseline;
+ o2.arcScaleX_ = o1.arcScaleX_;
+ o2.arcScaleY_ = o1.arcScaleY_;
+ o2.lineScale_ = o1.lineScale_;
+ }
+
+ var colorData = {
+ aliceblue: '#F0F8FF',
+ antiquewhite: '#FAEBD7',
+ aquamarine: '#7FFFD4',
+ azure: '#F0FFFF',
+ beige: '#F5F5DC',
+ bisque: '#FFE4C4',
+ black: '#000000',
+ blanchedalmond: '#FFEBCD',
+ blueviolet: '#8A2BE2',
+ brown: '#A52A2A',
+ burlywood: '#DEB887',
+ cadetblue: '#5F9EA0',
+ chartreuse: '#7FFF00',
+ chocolate: '#D2691E',
+ coral: '#FF7F50',
+ cornflowerblue: '#6495ED',
+ cornsilk: '#FFF8DC',
+ crimson: '#DC143C',
+ cyan: '#00FFFF',
+ darkblue: '#00008B',
+ darkcyan: '#008B8B',
+ darkgoldenrod: '#B8860B',
+ darkgray: '#A9A9A9',
+ darkgreen: '#006400',
+ darkgrey: '#A9A9A9',
+ darkkhaki: '#BDB76B',
+ darkmagenta: '#8B008B',
+ darkolivegreen: '#556B2F',
+ darkorange: '#FF8C00',
+ darkorchid: '#9932CC',
+ darkred: '#8B0000',
+ darksalmon: '#E9967A',
+ darkseagreen: '#8FBC8F',
+ darkslateblue: '#483D8B',
+ darkslategray: '#2F4F4F',
+ darkslategrey: '#2F4F4F',
+ darkturquoise: '#00CED1',
+ darkviolet: '#9400D3',
+ deeppink: '#FF1493',
+ deepskyblue: '#00BFFF',
+ dimgray: '#696969',
+ dimgrey: '#696969',
+ dodgerblue: '#1E90FF',
+ firebrick: '#B22222',
+ floralwhite: '#FFFAF0',
+ forestgreen: '#228B22',
+ gainsboro: '#DCDCDC',
+ ghostwhite: '#F8F8FF',
+ gold: '#FFD700',
+ goldenrod: '#DAA520',
+ grey: '#808080',
+ greenyellow: '#ADFF2F',
+ honeydew: '#F0FFF0',
+ hotpink: '#FF69B4',
+ indianred: '#CD5C5C',
+ indigo: '#4B0082',
+ ivory: '#FFFFF0',
+ khaki: '#F0E68C',
+ lavender: '#E6E6FA',
+ lavenderblush: '#FFF0F5',
+ lawngreen: '#7CFC00',
+ lemonchiffon: '#FFFACD',
+ lightblue: '#ADD8E6',
+ lightcoral: '#F08080',
+ lightcyan: '#E0FFFF',
+ lightgoldenrodyellow: '#FAFAD2',
+ lightgreen: '#90EE90',
+ lightgrey: '#D3D3D3',
+ lightpink: '#FFB6C1',
+ lightsalmon: '#FFA07A',
+ lightseagreen: '#20B2AA',
+ lightskyblue: '#87CEFA',
+ lightslategray: '#778899',
+ lightslategrey: '#778899',
+ lightsteelblue: '#B0C4DE',
+ lightyellow: '#FFFFE0',
+ limegreen: '#32CD32',
+ linen: '#FAF0E6',
+ magenta: '#FF00FF',
+ mediumaquamarine: '#66CDAA',
+ mediumblue: '#0000CD',
+ mediumorchid: '#BA55D3',
+ mediumpurple: '#9370DB',
+ mediumseagreen: '#3CB371',
+ mediumslateblue: '#7B68EE',
+ mediumspringgreen: '#00FA9A',
+ mediumturquoise: '#48D1CC',
+ mediumvioletred: '#C71585',
+ midnightblue: '#191970',
+ mintcream: '#F5FFFA',
+ mistyrose: '#FFE4E1',
+ moccasin: '#FFE4B5',
+ navajowhite: '#FFDEAD',
+ oldlace: '#FDF5E6',
+ olivedrab: '#6B8E23',
+ orange: '#FFA500',
+ orangered: '#FF4500',
+ orchid: '#DA70D6',
+ palegoldenrod: '#EEE8AA',
+ palegreen: '#98FB98',
+ paleturquoise: '#AFEEEE',
+ palevioletred: '#DB7093',
+ papayawhip: '#FFEFD5',
+ peachpuff: '#FFDAB9',
+ peru: '#CD853F',
+ pink: '#FFC0CB',
+ plum: '#DDA0DD',
+ powderblue: '#B0E0E6',
+ rosybrown: '#BC8F8F',
+ royalblue: '#4169E1',
+ saddlebrown: '#8B4513',
+ salmon: '#FA8072',
+ sandybrown: '#F4A460',
+ seagreen: '#2E8B57',
+ seashell: '#FFF5EE',
+ sienna: '#A0522D',
+ skyblue: '#87CEEB',
+ slateblue: '#6A5ACD',
+ slategray: '#708090',
+ slategrey: '#708090',
+ snow: '#FFFAFA',
+ springgreen: '#00FF7F',
+ steelblue: '#4682B4',
+ tan: '#D2B48C',
+ thistle: '#D8BFD8',
+ tomato: '#FF6347',
+ turquoise: '#40E0D0',
+ violet: '#EE82EE',
+ wheat: '#F5DEB3',
+ whitesmoke: '#F5F5F5',
+ yellowgreen: '#9ACD32'
+ };
+
+
+ function getRgbHslContent(styleString) {
+ var start = styleString.indexOf('(', 3);
+ var end = styleString.indexOf(')', start + 1);
+ var parts = styleString.substring(start + 1, end).split(',');
+ // add alpha if needed
+ if (parts.length == 4 && styleString.substr(3, 1) == 'a') {
+ alpha = Number(parts[3]);
+ } else {
+ parts[3] = 1;
+ }
+ return parts;
+ }
+
+ function percent(s) {
+ return parseFloat(s) / 100;
+ }
+
+ function clamp(v, min, max) {
+ return Math.min(max, Math.max(min, v));
+ }
+
+ function hslToRgb(parts){
+ var r, g, b;
+ h = parseFloat(parts[0]) / 360 % 360;
+ if (h < 0)
+ h++;
+ s = clamp(percent(parts[1]), 0, 1);
+ l = clamp(percent(parts[2]), 0, 1);
+ if (s == 0) {
+ r = g = b = l; // achromatic
+ } else {
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hueToRgb(p, q, h + 1 / 3);
+ g = hueToRgb(p, q, h);
+ b = hueToRgb(p, q, h - 1 / 3);
+ }
+
+ return '#' + decToHex[Math.floor(r * 255)] +
+ decToHex[Math.floor(g * 255)] +
+ decToHex[Math.floor(b * 255)];
+ }
+
+ function hueToRgb(m1, m2, h) {
+ if (h < 0)
+ h++;
+ if (h > 1)
+ h--;
+
+ if (6 * h < 1)
+ return m1 + (m2 - m1) * 6 * h;
+ else if (2 * h < 1)
+ return m2;
+ else if (3 * h < 2)
+ return m1 + (m2 - m1) * (2 / 3 - h) * 6;
+ else
+ return m1;
+ }
+
+ function processStyle(styleString) {
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.charAt(0) == '#') {
+ str = styleString;
+ } else if (/^rgb/.test(styleString)) {
+ var parts = getRgbHslContent(styleString);
+ var str = '#', n;
+ for (var i = 0; i < 3; i++) {
+ if (parts[i].indexOf('%') != -1) {
+ n = Math.floor(percent(parts[i]) * 255);
+ } else {
+ n = Number(parts[i]);
+ }
+ str += decToHex[clamp(n, 0, 255)];
+ }
+ alpha = parts[3];
+ } else if (/^hsl/.test(styleString)) {
+ var parts = getRgbHslContent(styleString);
+ str = hslToRgb(parts);
+ alpha = parts[3];
+ } else {
+ str = colorData[styleString] || styleString;
+ }
+ return {color: str, alpha: alpha};
+ }
+
+ var DEFAULT_STYLE = {
+ style: 'normal',
+ variant: 'normal',
+ weight: 'normal',
+ size: 10,
+ family: 'sans-serif'
+ };
+
+ // Internal text style cache
+ var fontStyleCache = {};