Skip to content

Commit

Permalink
Added special-case for highlighting bars
Browse files Browse the repository at this point in the history
git-svn-id: https://flot.googlecode.com/svn/trunk@90 1e0a6537-2640-0410-bfb7-f154510ff394
  • Loading branch information
olau@iola.dk committed Sep 21, 2008
1 parent 5a86074 commit 20fe8fd
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 92 deletions.
3 changes: 2 additions & 1 deletion API.txt
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,8 @@ also need to listen to "mouseout" events on the placeholder div.

"mouseActiveRadius" specifies how far the mouse can be from an item
and still activate it. If there are two or more points within this
radius, Flot chooses the closest item.
radius, Flot chooses the closest item. For bars, the top-most bar
(from the latest specified data series) is chosen.


Customizing the selection
Expand Down
3 changes: 1 addition & 2 deletions NEWS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ Interactivity: added a new "plothover" event and this and the
/david, patch by Mark Byers for bar support). See the revamped
"interacting with the data" example for some hints on what you can do.

Highlighting: you can now highlight points and points are
Highlighting: you can now highlight points and datapoints are
autohighlighted when you hover over them (if hovering is turned on).
Note: bars haven't been special-cased, yet.

Support for dual axis has been added (based on patch by someone who's
annoyed and /david). For each data series you can specify which axes
Expand Down
197 changes: 108 additions & 89 deletions jquery.flot.js
Original file line number Diff line number Diff line change
Expand Up @@ -1293,84 +1293,90 @@
ctx.restore();
}

function drawBar(x, y, barLeft, barRight, offset, fill, axisx, axisy, c) {
var drawLeft = true, drawRight = true,
drawTop = true, drawBottom = false,
left = x + barLeft, right = x + barRight,
bottom = 0, top = y;

// account for negative bars
if (top < bottom) {
top = 0;
bottom = y
drawBottom = true;
drawTop = false;
}

// clip
if (right < axisx.min || left > axisx.max ||
top < axisy.min || bottom > axisy.max)
return;

if (left < axisx.min) {
left = axisx.min;
drawLeft = false;
}

if (right > axisx.max) {
right = axisx.max;
drawRight = false;
}

if (bottom < axisy.min) {
bottom = axisy.min;
drawBottom = false;
}

if (top > axisy.max) {
top = axisy.max;
drawTop = false;
}

// fill the bar
if (fill) {
c.beginPath();
c.moveTo(axisx.p2c(left), axisy.p2c(bottom) + offset);
c.lineTo(axisx.p2c(left), axisy.p2c(top) + offset);
c.lineTo(axisx.p2c(right), axisy.p2c(top) + offset);
c.lineTo(axisx.p2c(right), axisy.p2c(bottom) + offset);
c.fill();
}

// draw outline
if (drawLeft || drawRight || drawTop || drawBottom) {
c.beginPath();
left = axisx.p2c(left);
bottom = axisy.p2c(bottom);
right = axisx.p2c(right);
top = axisy.p2c(top);

c.moveTo(left, bottom + offset);
if (drawLeft)
c.lineTo(left, top + offset);
else
c.moveTo(left, top + offset);
if (drawTop)
c.lineTo(right, top + offset);
else
c.moveTo(right, top + offset);
if (drawRight)
c.lineTo(right, bottom + offset);
else
c.moveTo(right, bottom + offset);
if (drawBottom)
c.lineTo(left, bottom + offset);
else
c.moveTo(left, bottom + offset);
c.stroke();
}
}

function drawSeriesBars(series) {
function plotBars(data, deltaLeft, deltaRight, offset, fill, axisx, axisy) {
function plotBars(data, barLeft, barRight, offset, fill, axisx, axisy) {
for (var i = 0; i < data.length; i++) {
if (data[i] == null)
continue;

var x = data[i][0], y = data[i][1],
drawLeft = true, drawRight = true,
drawTop = true, drawBottom = false,
left = x + deltaLeft, right = x + deltaRight,
bottom = 0, top = y;

// account for negative bars
if (top < bottom) {
top = 0;
bottom = y
drawBottom = true;
drawTop = false;
}

// clip
if (right < axisx.min || left > axisx.max ||
top < axisy.min || bottom > axisy.max)
continue;

if (left < axisx.min) {
left = axisx.min;
drawLeft = false;
}

if (right > axisx.max) {
right = axisx.max;
drawRight = false;
}

if (bottom < axisy.min) {
bottom = axisy.min;
drawBottom = false;
}

if (top > axisy.max) {
top = axisy.max;
drawTop = false;
}

// fill the bar
if (fill) {
ctx.beginPath();
ctx.moveTo(axisx.p2c(left), axisy.p2c(bottom) + offset);
ctx.lineTo(axisx.p2c(left), axisy.p2c(top) + offset);
ctx.lineTo(axisx.p2c(right), axisy.p2c(top) + offset);
ctx.lineTo(axisx.p2c(right), axisy.p2c(bottom) + offset);
ctx.fill();
}

// draw outline
if (drawLeft || drawRight || drawTop || drawBottom) {
ctx.beginPath();
ctx.moveTo(axisx.p2c(left), axisy.p2c(bottom) + offset);
if (drawLeft)
ctx.lineTo(axisx.p2c(left), axisy.p2c(top) + offset);
else
ctx.moveTo(axisx.p2c(left), axisy.p2c(top) + offset);

if (drawTop)
ctx.lineTo(axisx.p2c(right), axisy.p2c(top) + offset);
else
ctx.moveTo(axisx.p2c(right), axisy.p2c(top) + offset);
if (drawRight)
ctx.lineTo(axisx.p2c(right), axisy.p2c(bottom) + offset);
else
ctx.moveTo(axisx.p2c(right), axisy.p2c(bottom) + offset);
if (drawBottom)
ctx.lineTo(axisx.p2c(left), axisy.p2c(bottom) + offset);
else
ctx.moveTo(axisx.p2c(left), axisy.p2c(bottom) + offset);
ctx.stroke();
}
drawBar(data[i][0], data[i][1], barLeft, barRight, offset, fill, axisx, axisy, ctx);
}
}

Expand All @@ -1397,24 +1403,24 @@
ctx.lineWidth = series.bars.lineWidth;
ctx.strokeStyle = series.color;
setFillStyle(series.bars, series.color);
var deltaLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
plotBars(series.data, deltaLeft, deltaLeft + series.bars.barWidth, 0, series.bars.fill, series.xaxis, series.yaxis);
var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
plotBars(series.data, barLeft, barLeft + series.bars.barWidth, 0, series.bars.fill, series.xaxis, series.yaxis);
ctx.restore();
}

function setFillStyle(obj, seriesColor) {
var fill = obj.fill;
if (fill) {
if (obj.fillColor)
ctx.fillStyle = obj.fillColor;
else {
var c = parseColor(seriesColor);
c.a = typeof fill == "number" ? fill : 0.4;
c.normalize();
ctx.fillStyle = c.toString();
}
}
if (!fill)
return;

if (obj.fillColor)
ctx.fillStyle = obj.fillColor;
else {
var c = parseColor(seriesColor);
c.a = typeof fill == "number" ? fill : 0.4;
c.normalize();
ctx.fillStyle = c.toString();
}
}

function insertLegend() {
Expand Down Expand Up @@ -1535,7 +1541,7 @@
// and no other point can be nearby
if (!foundPoint && mx >= x + barLeft &&
mx <= x + barRight &&
(y > 0 ? my >= 0 && my <= y : my <= 0 && my >= y))
my >= Math.min(0, y) && my <= Math.max(0, y))
item = result(i, j);
}

Expand Down Expand Up @@ -1681,8 +1687,11 @@
var i, h;
for (i = 0; i < highlights.length; ++i) {
h = highlights[i];

drawPointHighlight(h.series, h.point);

if (h.series.bars.show)
drawBarHighlight(h.series, h.point);
else
drawPointHighlight(h.series, h.point);
}
octx.restore();

Expand Down Expand Up @@ -1760,6 +1769,16 @@
octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, true);
octx.stroke();
}

function drawBarHighlight(series, point) {
octx.lineJoin = "round";
octx.lineWidth = series.bars.lineWidth;
octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
octx.fillStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
drawBar(point[0], point[1], barLeft, barLeft + series.bars.barWidth,
0, true, series.xaxis, series.yaxis, octx);
}

function triggerSelectedEvent() {
var x1 = Math.min(selection.first.x, selection.second.x),
Expand Down

0 comments on commit 20fe8fd

Please sign in to comment.