Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 77 additions & 55 deletions Chart.Annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
// Box Annotation implementation
module.exports = function(Chart) {
var BoxAnnotation = Chart.Element.extend({
draw: function(ctx) {
draw: function(chartInstance, options) {
var view = this._view;
var ctx = chartInstance.chart.ctx;

// Canvas setup
ctx.lineWidth = view.borderWidth;
Expand Down Expand Up @@ -111,7 +112,7 @@ var updateFunctions = Chart.Annotation.updateFunctions = {
box: boxAnnotation.update
};

// Chartjs Zoom Plugin
// Chartjs Plugin hooks.
var AnnotationPlugin = Chart.PluginBase.extend({
beforeInit: function(chartInstance) {
var options = chartInstance.options;
Expand Down Expand Up @@ -148,14 +149,16 @@ var AnnotationPlugin = Chart.PluginBase.extend({
}
},

afterDraw: function(chartInstance, easingDecimal) {
beforeDraw: function(chartInstance, easingDecimal) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should be beforeDatasetsDraw per my comment in the other issue

// If we have annotations, draw them
var annotationObjects = chartInstance._annotationObjects;
var annotationOpts = chartInstance.options.annotation;

if (isArray(annotationObjects)) {
var ctx = chartInstance.chart.ctx;

annotationObjects.forEach(function(obj) {
obj.transition(easingDecimal).draw(ctx);
var opts = annotationOpts.annotations[obj._index];
obj.transition(easingDecimal).draw(chartInstance, opts);
});
}
}
Expand All @@ -166,55 +169,74 @@ Chart.pluginService.register(new AnnotationPlugin());

},{"./box.js":2,"./line.js":4,"chart.js":1}],4:[function(require,module,exports){
// Line Annotation implementation
module.exports = function(Chart) {
var horizontalKeyword = 'horizontal';
var verticalKeyword = 'vertical';

var LineAnnotation = Chart.Element.extend({

draw: function(ctx) {
var view = this._view;

// Canvas setup
ctx.lineWidth = view.borderWidth;
ctx.strokeStyle = view.borderColor;

// Draw
ctx.beginPath();
ctx.moveTo(view.x1, view.y1);
ctx.lineTo(view.x2, view.y2);
ctx.stroke();
}
});

function lineUpdate(obj, options, chartInstance) {
var model = obj._model = obj._model || {};

var scale = chartInstance.scales[options.scaleID];
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
var chartArea = chartInstance.chartArea;

if (!isNaN(pixel)) {
if (options.mode == horizontalKeyword) {
model.x1 = chartArea.left;
model.x2 = chartArea.right;
model.y1 = model.y2 = pixel;
} else {
model.y1 = chartArea.top;
model.y2 = chartArea.bottom;
model.x1 = model.x2 = pixel;
}
}

model.borderColor = options.borderColor;
model.borderWidth = options.borderWidth;
}


return {
Constructor: LineAnnotation,
update: lineUpdate
};
module.exports = function (Chart) {
var horizontalKeyword = 'horizontal';
var verticalKeyword = 'vertical';

var LineAnnotation = Chart.Element.extend({

draw: function (chartInstance, options) {
var view = this._view;
var ctx = chartInstance.chart.ctx;
var scale = chartInstance.scales[options.scaleID];
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
var chartArea = chartInstance.chartArea;
// Canvas setup
ctx.lineWidth = view.borderWidth;
ctx.strokeStyle = view.borderColor;

// Draw
ctx.beginPath();
ctx.moveTo(view.x1, view.y1);
ctx.lineTo(view.x2, view.y2);
ctx.stroke();
//Verify that label has been specified, so that we don't add a null label.
//TODO: Added customizable badge options, like: where to display the badge, left/right/center. or, Badge Border Color and Badge Background color.
//I would also like to add an option for different directional offsets, horizontalOffset, and VertOffset for example.
//Current issue with background color is that it likes to disappear when you hover over any other element on the chart.
if (options.label) {
//draw the background of the badge.
ctx.fillStyle = 'white';
ctx.fillRect((chartArea.right / 2), pixel - 5, 35, 15);
//Draw the border around the badge.
ctx.fillStyle = view.borderColor;
ctx.strokeRect((chartArea.right / 2), pixel - 5, 35, 15);
//Draw the text of the badge.
ctx.fillStyle = 'black';
ctx.textAlign = 'left';
ctx.fillText(options.label ? options.label : '', (chartArea.right / 2) + 5, pixel - 5);
}
}
});

function lineUpdate(obj, options, chartInstance) {
var model = obj._model = obj._model || {};

var scale = chartInstance.scales[options.scaleID];
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
var chartArea = chartInstance.chartArea;

if (!isNaN(pixel)) {
if (options.mode == horizontalKeyword) {
model.x1 = chartArea.left;
model.x2 = chartArea.right;
model.y1 = model.y2 = pixel;

} else {
model.y1 = chartArea.top;
model.y2 = chartArea.bottom;
model.x1 = model.x2 = pixel;
}
}
model.borderColor = options.borderColor;
model.borderWidth = options.borderWidth;

}


return {
Constructor: LineAnnotation,
update: lineUpdate
};
};

},{}]},{},[3]);
2 changes: 1 addition & 1 deletion Chart.Annotation.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ To configure the annotations plugin, you can simply add new config options to yo
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-1',
value: '25',
value: 25,
borderColor: 'red',
borderWidth: 2
borderWidth: 2,
label: 'Super Important Data'
}]
}
}
Expand All @@ -43,7 +44,10 @@ Vertical or horizontal lines are supported.
borderColor: 'red',

// Line width
borderWidth: 2
borderWidth: 2,

//Label
label: 'This is a Custom Label'
}
```

Expand Down
7 changes: 4 additions & 3 deletions samples/horizontal-line.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<head>
<title>Scatter Chart</title>
<script src="../node_modules/chart.js/dist/Chart.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.min.js"></script>
<script src="../Chart.Annotation.js"></script>
<style>
canvas {
Expand Down Expand Up @@ -131,9 +131,10 @@
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-1',
value: '25',
value: 25,
borderColor: 'black',
borderWidth: 5
borderWidth: 5,
label: '%B: 45%'
}]
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/box.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Box Annotation implementation
module.exports = function(Chart) {
var BoxAnnotation = Chart.Element.extend({
draw: function(ctx) {
draw: function(chartInstance, options) {
var view = this._view;
var ctx = chartInstance.chart.ctx;

// Canvas setup
ctx.lineWidth = view.borderWidth;
Expand Down
10 changes: 6 additions & 4 deletions src/chart.annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var updateFunctions = Chart.Annotation.updateFunctions = {
box: boxAnnotation.update
};

// Chartjs Zoom Plugin
// Chartjs Plugin hooks.
var AnnotationPlugin = Chart.PluginBase.extend({
beforeInit: function(chartInstance) {
var options = chartInstance.options;
Expand Down Expand Up @@ -64,14 +64,16 @@ var AnnotationPlugin = Chart.PluginBase.extend({
}
},

afterDraw: function(chartInstance, easingDecimal) {
beforeDatasetsDraw: function(chartInstance, easingDecimal) {
// If we have annotations, draw them
var annotationObjects = chartInstance._annotationObjects;
var annotationOpts = chartInstance.options.annotation;

if (isArray(annotationObjects)) {
var ctx = chartInstance.chart.ctx;

annotationObjects.forEach(function(obj) {
obj.transition(easingDecimal).draw(ctx);
var opts = annotationOpts.annotations[obj._index];
obj.transition(easingDecimal).draw(chartInstance, opts);
});
}
}
Expand Down
120 changes: 70 additions & 50 deletions src/line.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,71 @@
// Line Annotation implementation
module.exports = function(Chart) {
var horizontalKeyword = 'horizontal';
var verticalKeyword = 'vertical';

var LineAnnotation = Chart.Element.extend({

draw: function(ctx) {
var view = this._view;

// Canvas setup
ctx.lineWidth = view.borderWidth;
ctx.strokeStyle = view.borderColor;

// Draw
ctx.beginPath();
ctx.moveTo(view.x1, view.y1);
ctx.lineTo(view.x2, view.y2);
ctx.stroke();
}
});

function lineUpdate(obj, options, chartInstance) {
var model = obj._model = obj._model || {};

var scale = chartInstance.scales[options.scaleID];
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
var chartArea = chartInstance.chartArea;

if (!isNaN(pixel)) {
if (options.mode == horizontalKeyword) {
model.x1 = chartArea.left;
model.x2 = chartArea.right;
model.y1 = model.y2 = pixel;
} else {
model.y1 = chartArea.top;
model.y2 = chartArea.bottom;
model.x1 = model.x2 = pixel;
}
}

model.borderColor = options.borderColor;
model.borderWidth = options.borderWidth;
}


return {
Constructor: LineAnnotation,
update: lineUpdate
};
};
module.exports = function (Chart) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did the whitespace change here?

Copy link
Author

@Adondriel Adondriel Jul 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@etimberg It looks like it must have... not sure why github sees it as one big change. But that line was also readded below.

var horizontalKeyword = 'horizontal';
var verticalKeyword = 'vertical';

var LineAnnotation = Chart.Element.extend({

draw: function (chartInstance, options) {
var view = this._view;
var ctx = chartInstance.chart.ctx;
var scale = chartInstance.scales[options.scaleID];
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to call this again? would we be able to use the view?

var chartArea = chartInstance.chartArea;
// Canvas setup
ctx.lineWidth = view.borderWidth;
ctx.strokeStyle = view.borderColor;

// Draw
ctx.beginPath();
ctx.moveTo(view.x1, view.y1);
ctx.lineTo(view.x2, view.y2);
ctx.stroke();
//Verify that label has been specified, so that we don't add a null label.
//TODO: Added customizable badge options, like: where to display the badge, left/right/center. or, Badge Border Color and Badge Background color.
//I would also like to add an option for different directional offsets, horizontalOffset, and VertOffset for example.
//Current issue with background color is that it likes to disappear when you hover over any other element on the chart.
if (options.label) {
//draw the background of the badge.
ctx.fillStyle = 'white';
ctx.fillRect((chartArea.right / 2), pixel - 5, 35, 15);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that this took a while. I went to merge this and do some testing and I noticed this is incorrect. The width of the fill rect should be the width of the text. The text can be measured using ctx.measureText. To use this effectively, the font should be configurable and would need to be set before calling measureText.

The height of the rect would be the font size in px.

//Draw the border around the badge.
ctx.fillStyle = view.borderColor;
ctx.strokeRect((chartArea.right / 2), pixel - 5, 35, 15);
//Draw the text of the badge.
ctx.fillStyle = 'black';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This colour should probably be configurable as well

ctx.textAlign = 'left';
ctx.fillText(options.label ? options.label : '', (chartArea.right / 2) + 5, pixel - 5);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the extra check for label being present is not necessary. How will this location work for vertical lines? There should probably be a check for that case and change the position

}
}
});

function lineUpdate(obj, options, chartInstance) {
var model = obj._model = obj._model || {};

var scale = chartInstance.scales[options.scaleID];
var pixel = scale ? scale.getPixelForValue(options.value) : NaN;
var chartArea = chartInstance.chartArea;

if (!isNaN(pixel)) {
if (options.mode == horizontalKeyword) {
model.x1 = chartArea.left;
model.x2 = chartArea.right;
model.y1 = model.y2 = pixel;

} else {
model.y1 = chartArea.top;
model.y2 = chartArea.bottom;
model.x1 = model.x2 = pixel;
}
}
model.borderColor = options.borderColor;
model.borderWidth = options.borderWidth;

}


return {
Constructor: LineAnnotation,
update: lineUpdate
};
};