Commit 3a1d1e7b authored by olau@iola.dk's avatar olau@iola.dk

Added support for gradient bars

git-svn-id: https://flot.googlecode.com/svn/trunk@132 1e0a6537-2640-0410-bfb7-f154510ff394
parent ab264f6e
...@@ -409,7 +409,7 @@ Customizing the data series ...@@ -409,7 +409,7 @@ Customizing the data series
show: boolean show: boolean
lineWidth: number lineWidth: number
fill: boolean or number fill: boolean or number
fillColor: color fillColor: null or color/gradient
} }
points: { points: {
...@@ -449,12 +449,13 @@ points), the fill color is auto-set to the color of the data series. ...@@ -449,12 +449,13 @@ points), the fill color is auto-set to the color of the data series.
You can adjust the opacity of the fill by setting fill to a number You can adjust the opacity of the fill by setting fill to a number
between 0 (fully transparent) and 1 (fully opaque). between 0 (fully transparent) and 1 (fully opaque).
"barWidth" is the width of the bars in units of the x axis, contrary For bars, fillColor can be a gradient, see the gradient documentation
to most other measures that are specified in pixels. For instance, for below. "barWidth" is the width of the bars in units of the x axis,
time series the unit is milliseconds so 24 * 60 * 60 * 1000 produces contrary to most other measures that are specified in pixels. For
bars with the width of a day. "align" specifies whether a bar should instance, for time series the unit is milliseconds so 24 * 60 * 60 *
be left-aligned (default) or centered on top of the value it 1000 produces bars with the width of a day. "align" specifies whether
represents. a bar should be left-aligned (default) or centered on top of the value
it represents.
The "colors" array specifies a default color theme to get colors for The "colors" array specifies a default color theme to get colors for
the data series from. You can specify as many colors as you like, like the data series from. You can specify as many colors as you like, like
...@@ -655,6 +656,15 @@ black to gray like this: ...@@ -655,6 +656,15 @@ black to gray like this:
backgroundColor: { colors: ["#000", "#999"] } backgroundColor: { colors: ["#000", "#999"] }
} }
For the series you can specify the gradient as an object that
specifies the scaling of the brightness and the opacity of the series
color, e.g.
{ colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ]
where the first color simply has its alpha scaled, whereas the second
is also darkened.
Flot currently only supports vertical gradients drawn from top to Flot currently only supports vertical gradients drawn from top to
bottom because that's what works with IE. bottom because that's what works with IE.
......
...@@ -28,17 +28,18 @@ Changes: ...@@ -28,17 +28,18 @@ Changes:
- Added "borderColor" option to the grid (patch from Amaury Chamayou - Added "borderColor" option to the grid (patch from Amaury Chamayou
and patch from Mike R. Williamson). and patch from Mike R. Williamson).
- Added support for gradient background for the grid, take a look at - Added support for gradient backgrounds for the grid, take a look at
the "setting options" example (based on patch from Amaury Chamayou, the "setting options" example (based on patch from Amaury Chamayou,
issue 90). issue 90).
- Gradient bars (suggestion by stefpet).
- Added a "plotunselected" event which is triggered when the selection - Added a "plotunselected" event which is triggered when the selection
is removed, see "selection" example (suggestion by Meda Ugo); is removed, see "selection" example (suggestion by Meda Ugo);
- The option legend.margin can now specify horizontal and vertical - The option legend.margin can now specify horizontal and vertical
margins independently (suggestion by someone who's annoyed). margins independently (suggestion by someone who's annoyed).
Bug fixes: Bug fixes:
- Fixed two corner-case bugs when drawing filled curves (report and - Fixed two corner-case bugs when drawing filled curves (report and
......
...@@ -858,7 +858,7 @@ ...@@ -858,7 +858,7 @@
// draw background, if any // draw background, if any
if (options.grid.backgroundColor) { if (options.grid.backgroundColor) {
ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor); ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight);
ctx.fillRect(0, 0, plotWidth, plotHeight); ctx.fillRect(0, 0, plotWidth, plotHeight);
} }
...@@ -1270,9 +1270,11 @@ ...@@ -1270,9 +1270,11 @@
ctx.lineWidth = lw; ctx.lineWidth = lw;
ctx.strokeStyle = series.color; ctx.strokeStyle = series.color;
setFillStyle(series.lines, series.color); var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
if (series.lines.fill) if (fillStyle) {
ctx.fillStyle = fillStyle;
plotLineArea(series.data, series.xaxis, series.yaxis); plotLineArea(series.data, series.xaxis, series.yaxis);
}
if (lw > 0) if (lw > 0)
plotLine(series.data, 0, series.xaxis, series.yaxis); plotLine(series.data, 0, series.xaxis, series.yaxis);
...@@ -1280,7 +1282,7 @@ ...@@ -1280,7 +1282,7 @@
} }
function drawSeriesPoints(series) { function drawSeriesPoints(series) {
function plotPoints(data, radius, fill, axisx, axisy) { function plotPoints(data, radius, fillStyle, axisx, axisy) {
for (var i = 0; i < data.length; ++i) { for (var i = 0; i < data.length; ++i) {
if (data[i] == null) if (data[i] == null)
continue; continue;
...@@ -1291,8 +1293,10 @@ ...@@ -1291,8 +1293,10 @@
ctx.beginPath(); ctx.beginPath();
ctx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, true); ctx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, true);
if (fill) if (fillStyle) {
ctx.fillStyle = fillStyle;
ctx.fill(); ctx.fill();
}
ctx.stroke(); ctx.stroke();
} }
} }
...@@ -1331,13 +1335,13 @@ ...@@ -1331,13 +1335,13 @@
ctx.lineWidth = series.points.lineWidth; ctx.lineWidth = series.points.lineWidth;
ctx.strokeStyle = series.color; ctx.strokeStyle = series.color;
setFillStyle(series.points, series.color); plotPoints(series.data, series.points.radius,
plotPoints(series.data, series.points.radius, series.points.fill, getFillStyle(series.points, series.color),
series.xaxis, series.yaxis); series.xaxis, series.yaxis);
ctx.restore(); ctx.restore();
} }
function drawBar(x, y, barLeft, barRight, offset, fill, axisx, axisy, c) { function drawBar(x, y, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c) {
var drawLeft = true, drawRight = true, var drawLeft = true, drawRight = true,
drawTop = true, drawBottom = false, drawTop = true, drawBottom = false,
left = x + barLeft, right = x + barRight, left = x + barLeft, right = x + barRight,
...@@ -1376,24 +1380,27 @@ ...@@ -1376,24 +1380,27 @@
drawTop = false; drawTop = false;
} }
left = axisx.p2c(left);
bottom = axisy.p2c(bottom);
right = axisx.p2c(right);
top = axisy.p2c(top);
// fill the bar // fill the bar
if (fill) { if (fillStyleCallback) {
c.beginPath(); c.beginPath();
c.moveTo(axisx.p2c(left), axisy.p2c(bottom) + offset); c.moveTo(left, bottom);
c.lineTo(axisx.p2c(left), axisy.p2c(top) + offset); c.lineTo(left, top);
c.lineTo(axisx.p2c(right), axisy.p2c(top) + offset); c.lineTo(right, top);
c.lineTo(axisx.p2c(right), axisy.p2c(bottom) + offset); c.lineTo(right, bottom);
ctx.fillStyle = fillStyleCallback(bottom, top);
c.fill(); c.fill();
} }
// draw outline // draw outline
if (drawLeft || drawRight || drawTop || drawBottom) { if (drawLeft || drawRight || drawTop || drawBottom) {
c.beginPath(); c.beginPath();
left = axisx.p2c(left);
bottom = axisy.p2c(bottom);
right = axisx.p2c(right);
top = axisy.p2c(top);
// FIXME: inline moveTo is buggy with excanvas
c.moveTo(left, bottom + offset); c.moveTo(left, bottom + offset);
if (drawLeft) if (drawLeft)
c.lineTo(left, top + offset); c.lineTo(left, top + offset);
...@@ -1416,11 +1423,11 @@ ...@@ -1416,11 +1423,11 @@
} }
function drawSeriesBars(series) { function drawSeriesBars(series) {
function plotBars(data, barLeft, barRight, offset, fill, axisx, axisy) { function plotBars(data, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
if (data[i] == null) if (data[i] == null)
continue; continue;
drawBar(data[i][0], data[i][1], barLeft, barRight, offset, fill, axisx, axisy, ctx); drawBar(data[i][0], data[i][1], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx);
} }
} }
...@@ -1428,7 +1435,7 @@ ...@@ -1428,7 +1435,7 @@
ctx.translate(plotOffset.left, plotOffset.top); ctx.translate(plotOffset.left, plotOffset.top);
ctx.lineJoin = "round"; ctx.lineJoin = "round";
// FIXME: figure out a way to add shadows // FIXME: figure out a way to add shadows (for instance along the right edge)
/* /*
var bw = series.bars.barWidth; var bw = series.bars.barWidth;
var lw = series.bars.lineWidth; var lw = series.bars.lineWidth;
...@@ -1446,25 +1453,24 @@ ...@@ -1446,25 +1453,24 @@
ctx.lineWidth = series.bars.lineWidth; ctx.lineWidth = series.bars.lineWidth;
ctx.strokeStyle = series.color; ctx.strokeStyle = series.color;
setFillStyle(series.bars, series.color);
var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; 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); var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
plotBars(series.data, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
ctx.restore(); ctx.restore();
} }
function setFillStyle(obj, seriesColor) { function getFillStyle(filloptions, seriesColor, bottom, top) {
var fill = obj.fill; var fill = filloptions.fill;
if (!fill) if (!fill)
return; return null;
if (filloptions.fillColor)
return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
if (obj.fillColor)
ctx.fillStyle = obj.fillColor;
else {
var c = parseColor(seriesColor); var c = parseColor(seriesColor);
c.a = typeof fill == "number" ? fill : 0.4; c.a = typeof fill == "number" ? fill : 0.4;
c.normalize(); c.normalize();
ctx.fillStyle = c.toString(); return c.toString();
}
} }
function insertLegend() { function insertLegend() {
...@@ -1872,10 +1878,10 @@ ...@@ -1872,10 +1878,10 @@
octx.lineJoin = "round"; octx.lineJoin = "round";
octx.lineWidth = series.bars.lineWidth; octx.lineWidth = series.bars.lineWidth;
octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString(); 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 fillStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
drawBar(point[0], point[1], barLeft, barLeft + series.bars.barWidth, drawBar(point[0], point[1], barLeft, barLeft + series.bars.barWidth,
0, true, series.xaxis, series.yaxis, octx); 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx);
} }
function setPositionFromEvent(pos, e) { function setPositionFromEvent(pos, e) {
...@@ -2023,17 +2029,19 @@ ...@@ -2023,17 +2029,19 @@
Math.abs(selection.second.y - selection.first.y) >= minSize; Math.abs(selection.second.y - selection.first.y) >= minSize;
} }
function getColorOrGradient(spec) { function getColorOrGradient(spec, bottom, top, defaultColor) {
if (typeof spec == "string") if (typeof spec == "string")
return spec; return spec;
else { else {
// assume this is a gradient spec; IE currently only // assume this is a gradient spec; IE currently only
// supports a simple vertical gradient properly, so that's // supports a simple vertical gradient properly, so that's
// what we support too // what we support too
var gradient = ctx.createLinearGradient(0, 0, 0, plotHeight); var gradient = ctx.createLinearGradient(0, top, 0, bottom);
for (var i = 0, l = spec.colors.length; i < l; ++i) for (var i = 0, l = spec.colors.length; i < l; ++i) {
gradient.addColorStop(i / (l - 1), spec.colors[i]); var c = spec.colors[i];
gradient.addColorStop(i / (l - 1), typeof c == "string" ? c : parseColor(defaultColor).scale(c.brightness, c.brightness, c.brightness, c.opacity));
}
return gradient; return gradient;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment