From 81d19f700ffc99b55644310ba208b4ac30552a94 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 07:30:03 -0500 Subject: [PATCH 01/12] Declare a variable that should have been local. --- jquery.flot.fillbetween.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.flot.fillbetween.js b/jquery.flot.fillbetween.js index 66e25ab..12b68eb 100644 --- a/jquery.flot.fillbetween.js +++ b/jquery.flot.fillbetween.js @@ -70,7 +70,7 @@ plugin, possibly some code could be shared. withbottom = ps > 2 && datapoints.format[2].y, withsteps = withlines && s.lines.steps, fromgap = true, - i = 0, j = 0, l; + i = 0, j = 0, l, m; while (true) { if (i >= points.length) From a10206c13ae46edfd2f6071c172b94d96ba91c9d Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 07:30:42 -0500 Subject: [PATCH 02/12] Added a missing semicolon. --- jquery.flot.fillbetween.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.flot.fillbetween.js b/jquery.flot.fillbetween.js index 12b68eb..dc35b6a 100644 --- a/jquery.flot.fillbetween.js +++ b/jquery.flot.fillbetween.js @@ -123,7 +123,7 @@ plugin, possibly some code could be shared. if (withlines && i > 0 && points[i - ps] != null) { intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px); newpoints.push(qx); - newpoints.push(intery) + newpoints.push(intery); for (m = 2; m < ps; ++m) newpoints.push(points[i + m]); bottom = qy; From 78ee3c708108cdf0442f9369b950caf6bb212729 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 07:33:31 -0500 Subject: [PATCH 03/12] Updated code style to match Flot's guidelines. --- jquery.flot.fillbetween.js | 403 ++++++++++++++++++++----------------- 1 file changed, 223 insertions(+), 180 deletions(-) diff --git a/jquery.flot.fillbetween.js b/jquery.flot.fillbetween.js index dc35b6a..cf17cd7 100644 --- a/jquery.flot.fillbetween.js +++ b/jquery.flot.fillbetween.js @@ -1,183 +1,226 @@ -/* -Flot plugin for computing bottoms for filled line and bar charts. - -The case: you've got two series that you want to fill the area -between. In Flot terms, you need to use one as the fill bottom of the -other. You can specify the bottom of each data point as the third -coordinate manually, or you can use this plugin to compute it for you. - -In order to name the other series, you need to give it an id, like this - - var dataset = [ - { data: [ ... ], id: "foo" } , // use default bottom - { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom - ]; - - $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }}); - -As a convenience, if the id given is a number that doesn't appear as -an id in the series, it is interpreted as the index in the array -instead (so fillBetween: 0 can also mean the first series). - -Internally, the plugin modifies the datapoints in each series. For -line series, extra data points might be inserted through -interpolation. Note that at points where the bottom line is not -defined (due to a null point or start/end of line), the current line -will show a gap too. The algorithm comes from the jquery.flot.stack.js -plugin, possibly some code could be shared. +/* Flot plugin for computing bottoms for filled line and bar charts. + +Copyright (c) 2007-2012 IOLA and Ole Laursen. +Licensed under the MIT license. + +The case: you've got two series that you want to fill the area between. In Flot +terms, you need to use one as the fill bottom of the other. You can specify the +bottom of each data point as the third coordinate manually, or you can use this +plugin to compute it for you. + +In order to name the other series, you need to give it an id, like this: + + var dataset = [ + { data: [ ... ], id: "foo" } , // use default bottom + { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom + ]; + + $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }}); + +As a convenience, if the id given is a number that doesn't appear as an id in +the series, it is interpreted as the index in the array instead (so fillBetween: +0 can also mean the first series). + +Internally, the plugin modifies the datapoints in each series. For line series, +extra data points might be inserted through interpolation. Note that at points +where the bottom line is not defined (due to a null point or start/end of line), +the current line will show a gap too. The algorithm comes from the +jquery.flot.stack.js plugin, possibly some code could be shared. + */ -(function ($) { - var options = { - series: { fillBetween: null } // or number - }; - - function init(plot) { - function findBottomSeries(s, allseries) { - var i; - for (i = 0; i < allseries.length; ++i) { - if (allseries[i].id == s.fillBetween) - return allseries[i]; - } - - if (typeof s.fillBetween == "number") { - i = s.fillBetween; - - if (i < 0 || i >= allseries.length) - return null; - - return allseries[i]; - } - - return null; - } - - function computeFillBottoms(plot, s, datapoints) { - if (s.fillBetween == null) - return; - - var other = findBottomSeries(s, plot.getData()); - if (!other) - return; - - var ps = datapoints.pointsize, - points = datapoints.points, - otherps = other.datapoints.pointsize, - otherpoints = other.datapoints.points, - newpoints = [], - px, py, intery, qx, qy, bottom, - withlines = s.lines.show, - withbottom = ps > 2 && datapoints.format[2].y, - withsteps = withlines && s.lines.steps, - fromgap = true, - i = 0, j = 0, l, m; - - while (true) { - if (i >= points.length) - break; - - l = newpoints.length; - - if (points[i] == null) { - // copy gaps - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - i += ps; - } - else if (j >= otherpoints.length) { - // for lines, we can't use the rest of the points - if (!withlines) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - } - i += ps; - } - else if (otherpoints[j] == null) { - // oops, got a gap - for (m = 0; m < ps; ++m) - newpoints.push(null); - fromgap = true; - j += otherps; - } - else { - // cases where we actually got two points - px = points[i]; - py = points[i + 1]; - qx = otherpoints[j]; - qy = otherpoints[j + 1]; - bottom = 0; - - if (px == qx) { - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - - //newpoints[l + 1] += qy; - bottom = qy; - - i += ps; - j += otherps; - } - else if (px > qx) { - // we got past point below, might need to - // insert interpolated extra point - if (withlines && i > 0 && points[i - ps] != null) { - intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px); - newpoints.push(qx); - newpoints.push(intery); - for (m = 2; m < ps; ++m) - newpoints.push(points[i + m]); - bottom = qy; - } - - j += otherps; - } - else { // px < qx - if (fromgap && withlines) { - // if we come from a gap, we just skip this point - i += ps; - continue; - } - - for (m = 0; m < ps; ++m) - newpoints.push(points[i + m]); - - // we might be able to interpolate a point below, - // this can give us a better y - if (withlines && j > 0 && otherpoints[j - otherps] != null) - bottom = qy + (otherpoints[j - otherps + 1] - qy) * (px - qx) / (otherpoints[j - otherps] - qx); - - //newpoints[l + 1] += bottom; - - i += ps; - } - - fromgap = false; - - if (l != newpoints.length && withbottom) - newpoints[l + 2] = bottom; - } - - // maintain the line steps invariant - if (withsteps && l != newpoints.length && l > 0 - && newpoints[l] != null - && newpoints[l] != newpoints[l - ps] - && newpoints[l + 1] != newpoints[l - ps + 1]) { - for (m = 0; m < ps; ++m) - newpoints[l + ps + m] = newpoints[l + m]; - newpoints[l + 1] = newpoints[l - ps + 1]; - } - } - - datapoints.points = newpoints; - } - - plot.hooks.processDatapoints.push(computeFillBottoms); - } - - $.plot.plugins.push({ - init: init, - options: options, - name: 'fillbetween', - version: '1.0' - }); +(function ( $ ) { + + var options = { + series: { + fillBetween: null // or number + } + }; + + function init( plot ) { + + function findBottomSeries( s, allseries ) { + + var i; + + for ( i = 0; i < allseries.length; ++i ) { + if ( allseries[ i ].id === s.fillBetween ) { + return allseries[ i ]; + } + } + + if ( typeof s.fillBetween === "number" ) { + if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) { + return null; + } + return allseries[ s.fillBetween ]; + } + + return null; + } + + function computeFillBottoms( plot, s, datapoints ) { + + if ( s.fillBetween == null ) { + return; + } + + var other = findBottomSeries( s, plot.getData() ); + + if ( !other ) { + return; + } + + var ps = datapoints.pointsize, + points = datapoints.points, + otherps = other.datapoints.pointsize, + otherpoints = other.datapoints.points, + newpoints = [], + px, py, intery, qx, qy, bottom, + withlines = s.lines.show, + withbottom = ps > 2 && datapoints.format[2].y, + withsteps = withlines && s.lines.steps, + fromgap = true, + i = 0, + j = 0, + l, m; + + while ( true ) { + + if ( i >= points.length ) { + break; + } + + l = newpoints.length; + + if ( points[ i ] == null ) { + + // copy gaps + + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + + i += ps; + + } else if ( j >= otherpoints.length ) { + + // for lines, we can't use the rest of the points + + if ( !withlines ) { + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + } + + i += ps; + + } else if ( otherpoints[ j ] == null ) { + + // oops, got a gap + + for ( m = 0; m < ps; ++m ) { + newpoints.push( null ); + } + + fromgap = true; + j += otherps; + + } else { + + // cases where we actually got two points + + px = points[ i ]; + py = points[ i + 1 ]; + qx = otherpoints[ j ]; + qy = otherpoints[ j + 1 ]; + bottom = 0; + + if ( px === qx ) { + + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + + //newpoints[ l + 1 ] += qy; + bottom = qy; + + i += ps; + j += otherps; + + } else if ( px > qx ) { + + // we got past point below, might need to + // insert interpolated extra point + + if ( withlines && i > 0 && points[ i - ps ] != null ) { + intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px ); + newpoints.push( qx ); + newpoints.push( intery ); + for ( m = 2; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + bottom = qy; + } + + j += otherps; + + } else { // px < qx + + // if we come from a gap, we just skip this point + + if ( fromgap && withlines ) { + i += ps; + continue; + } + + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + + // we might be able to interpolate a point below, + // this can give us a better y + + if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) { + bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx ); + } + + //newpoints[l + 1] += bottom; + + i += ps; + } + + fromgap = false; + + if ( l !== newpoints.length && withbottom ) { + newpoints[ l + 2 ] = bottom; + } + } + + // maintain the line steps invariant + + if ( withsteps && l !== newpoints.length && l > 0 && + newpoints[ l ] !== null && + newpoints[ l ] !== newpoints[ l - ps ] && + newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) { + for (m = 0; m < ps; ++m) { + newpoints[ l + ps + m ] = newpoints[ l + m ]; + } + newpoints[ l + 1 ] = newpoints[ l - ps + 1 ]; + } + } + + datapoints.points = newpoints; + } + + plot.hooks.processDatapoints.push( computeFillBottoms ); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: "fillbetween", + version: "1.0" + }); + })(jQuery); From a3df340afb7bec77b9a16b66c711b2a0f8f758d4 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 07:37:51 -0500 Subject: [PATCH 04/12] Added missing semicolons. --- jquery.flot.crosshair.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jquery.flot.crosshair.js b/jquery.flot.crosshair.js index 1d433f0..09a07ac 100644 --- a/jquery.flot.crosshair.js +++ b/jquery.flot.crosshair.js @@ -84,11 +84,11 @@ The plugin also adds four public methods: if (pos) plot.setCrosshair(pos); crosshair.locked = true; - } + }; plot.unlockCrosshair = function unlockCrosshair() { crosshair.locked = false; - } + }; function onMouseOut(e) { if (crosshair.locked) From 6c960a8addc757a873c6da93a13b7122398a7c6a Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 07:40:14 -0500 Subject: [PATCH 05/12] Added a missing semicolon. --- jquery.flot.image.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.flot.image.js b/jquery.flot.image.js index 29ccb12..24753d2 100644 --- a/jquery.flot.image.js +++ b/jquery.flot.image.js @@ -110,7 +110,7 @@ images (like Google Maps). $('').load(handler).error(handler).attr('src', url); }); - } + }; function drawSeries(plot, ctx, series) { var plotOffset = plot.getPlotOffset(); From 8110f0c1d93b775b3bf5db1e05c158e36cd485c9 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 07:43:06 -0500 Subject: [PATCH 06/12] Added missing semicolons. --- jquery.flot.navigate.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jquery.flot.navigate.js b/jquery.flot.navigate.js index 301dddf..8f810a9 100644 --- a/jquery.flot.navigate.js +++ b/jquery.flot.navigate.js @@ -200,11 +200,11 @@ Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-L args = {}; if (!args.amount) - args.amount = plot.getOptions().zoom.amount + args.amount = plot.getOptions().zoom.amount; args.amount = 1 / args.amount; plot.zoom(args); - } + }; plot.zoom = function (args) { if (!args) @@ -274,7 +274,7 @@ Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-L if (!args.preventEvent) plot.getPlaceholder().trigger("plotzoom", [ plot, args ]); - } + }; plot.pan = function (args) { var delta = { @@ -322,7 +322,7 @@ Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-L if (!args.preventEvent) plot.getPlaceholder().trigger("plotpan", [ plot ]); - } + }; function shutdown(plot, eventHolder) { eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick); From 179bed9617037df41f110e32c7ebbe40824c4318 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 08:08:18 -0500 Subject: [PATCH 07/12] Declare variables that should have been local. --- jquery.flot.pie.js | 64 ++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/jquery.flot.pie.js b/jquery.flot.pie.js index 8f20f52..61801ab 100644 --- a/jquery.flot.pie.js +++ b/jquery.flot.pie.js @@ -65,20 +65,21 @@ More detail and specific examples can be found in the included HTML file. function init(plot) { - var canvas = null; - var canvasWidth = 0; - var canvasHeight = 0; - var target = null; - var maxRadius = null; - var centerLeft = null; - var centerTop = null; - var total = 0; - var redraw = true; - var redrawAttempts = 10; - var shrink = 0.95; - var legendWidth = 0; - var processed = false; - var raw = false; + var canvas = null, + canvasWidth = 0, + canvasHeight = 0, + target = null, + maxRadius = null, + centerLeft = null, + centerTop = null, + total = 0, + redraw = true, + redrawAttempts = 10, + shrink = 0.95, + legendWidth = 0, + processed = false, + raw = false, + ctx = null; // interactive variables @@ -528,7 +529,7 @@ More detail and specific examples can be found in the included HTML file. // subtract the center layer.save(); - innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; + var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color layer.beginPath(); layer.fillStyle = options.series.pie.stroke.color; @@ -563,9 +564,10 @@ More detail and specific examples can be found in the included HTML file. function findNearbySlice(mouseX, mouseY) { - var slices = plot.getData(); - var options = plot.getOptions(); - var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; + var slices = plot.getData(), + options = plot.getOptions(), + radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius, + x, y; for (var i = 0; i < slices.length; ++i) { @@ -597,18 +599,18 @@ More detail and specific examples can be found in the included HTML file. // excanvas for IE doesn;t support isPointInPath, this is a workaround. - p1X = radius * Math.cos(s.startAngle); - p1Y = radius * Math.sin(s.startAngle); - p2X = radius * Math.cos(s.startAngle + s.angle / 4); - p2Y = radius * Math.sin(s.startAngle + s.angle / 4); - p3X = radius * Math.cos(s.startAngle + s.angle / 2); - p3Y = radius * Math.sin(s.startAngle + s.angle / 2); - p4X = radius * Math.cos(s.startAngle + s.angle / 1.5); - p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5); - p5X = radius * Math.cos(s.startAngle + s.angle); - p5Y = radius * Math.sin(s.startAngle + s.angle); - arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]]; - arrPoint = [x, y]; + var p1X = radius * Math.cos(s.startAngle), + p1Y = radius * Math.sin(s.startAngle), + p2X = radius * Math.cos(s.startAngle + s.angle / 4), + p2Y = radius * Math.sin(s.startAngle + s.angle / 4), + p3X = radius * Math.cos(s.startAngle + s.angle / 2), + p3Y = radius * Math.sin(s.startAngle + s.angle / 2), + p4X = radius * Math.cos(s.startAngle + s.angle / 1.5), + p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5), + p5X = radius * Math.cos(s.startAngle + s.angle), + p5Y = radius * Math.sin(s.startAngle + s.angle), + arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]], + arrPoint = [x, y]; // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? @@ -723,7 +725,7 @@ More detail and specific examples can be found in the included HTML file. octx.translate(centerLeft, centerTop); octx.scale(1, options.series.pie.tilt); - for (i = 0; i < highlights.length; ++i) { + for (var i = 0; i < highlights.length; ++i) { drawHighlight(highlights[i].series); } From b3a19afb05db9ab75973b6e8f4b8329720eee36f Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 08:09:48 -0500 Subject: [PATCH 08/12] Comment out bizzarre impossible code. --- jquery.flot.pie.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jquery.flot.pie.js b/jquery.flot.pie.js index 61801ab..884939c 100644 --- a/jquery.flot.pie.js +++ b/jquery.flot.pie.js @@ -674,9 +674,9 @@ More detail and specific examples can be found in the included HTML file. } function highlight(s, auto) { - if (typeof s == "number") { - s = series[s]; - } + //if (typeof s == "number") { + // s = series[s]; + //} var i = indexOfHighlight(s); @@ -694,9 +694,9 @@ More detail and specific examples can be found in the included HTML file. plot.triggerRedrawOverlay(); } - if (typeof s == "number") { - s = series[s]; - } + //if (typeof s == "number") { + // s = series[s]; + //} var i = indexOfHighlight(s); From 308ff28166f6390d061c477fbb6368f410199363 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 08:12:01 -0500 Subject: [PATCH 09/12] Declare a variable that should have been local. --- jquery.flot.stack.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.flot.stack.js b/jquery.flot.stack.js index 6d8105d..ace7011 100644 --- a/jquery.flot.stack.js +++ b/jquery.flot.stack.js @@ -71,7 +71,7 @@ adjusted (e.g for bar charts or filled areas). fromgap = true, keyOffset = horizontal ? 1 : 0, accumulateOffset = horizontal ? 0 : 1, - i = 0, j = 0, l; + i = 0, j = 0, l, m; while (true) { if (i >= points.length) From 3073264d166fff275c443174a9d26c6a0d814009 Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 08:12:53 -0500 Subject: [PATCH 10/12] Added a missing semicolon. --- jquery.flot.symbol.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.flot.symbol.js b/jquery.flot.symbol.js index a32fe31..b35bc7b 100644 --- a/jquery.flot.symbol.js +++ b/jquery.flot.symbol.js @@ -51,7 +51,7 @@ choice: ctx.moveTo(x - size, y + size); ctx.lineTo(x + size, y - size); } - } + }; var s = series.points.symbol; if (handlers[s]) From afc97ba0993d5cb8e1f76244f07bba22a5f1efeb Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 08:13:33 -0500 Subject: [PATCH 11/12] Added a missing semicolon. --- jquery.flot.threshold.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.flot.threshold.js b/jquery.flot.threshold.js index d68c404..f514a16 100644 --- a/jquery.flot.threshold.js +++ b/jquery.flot.threshold.js @@ -61,7 +61,7 @@ events. var m; for (i = 0; i < origpoints.length; i += ps) { - x = origpoints[i] + x = origpoints[i]; y = origpoints[i + 1]; prevp = p; From 8b9964055324b5014f5fea6147b95818f208b66c Mon Sep 17 00:00:00 2001 From: David Schnur Date: Sat, 1 Dec 2012 08:23:32 -0500 Subject: [PATCH 12/12] Declare variables that should have been local. --- jquery.flot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jquery.flot.js b/jquery.flot.js index 8cfa611..2a9c335 100644 --- a/jquery.flot.js +++ b/jquery.flot.js @@ -2293,7 +2293,7 @@ for (var i = 0; i < entries.length; ++i) { - entry = entries[i]; + var entry = entries[i]; if (i % options.legend.noColumns == 0) { if (rowStarted) @@ -2584,7 +2584,7 @@ function drawPointHighlight(series, point) { var x = point[0], y = point[1], - axisx = series.xaxis, axisy = series.yaxis; + axisx = series.xaxis, axisy = series.yaxis, highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)