Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added tooltip label to line chart #31

Merged
merged 4 commits into from
Nov 15, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Added tooltip label to line chart
Originally based on #12.
Added an optional Label option to Line Annotation.
Updated the documentation to display this. Also added a sample showing
how it can work.
  • Loading branch information
Pete Walker committed Nov 4, 2016
commit e20ec9165948a21b166a2246c8d45b22b23290fc
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,36 @@ Vertical or horizontal lines are supported.

// Line Dash Offset
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
borderDashOffset: 5
borderDashOffset: 5,

label: {
// Background color of label, default below
backgroundColor: 'rgba(0,0,0,0.8)',
// Font family of text, inherits from global
fontFamily: "sans-serif",
// Font size of text, inherits from global
fontSize: 12,
// Font style of text, default below
fontStyle: "bold",
// Font color of text, default below
fontColor: "#fff",
// Padding of label to add left/right, default below
xPadding: 6,
// Padding of label to add top/bottom, default below
yPadding: 6,
// Radius of label rectangle, default below
cornerRadius: 6,
// Anchor position of label on line, can be one of: top, bottom, left, right, center. Default below.
position: "center",
// Adjustment along x-axis (left-right) of label relative to above number (can be negative)
xAdjust: 0,
// Adjustment along y-axis (top-bottom) of label relative to above number (can be negative)
yAdjust: 0,
// Whether the label is enabled and should be displayed
enabled: false,
// Text to display in label - default is null
content: "Test label"
}
}
```

Expand Down
92 changes: 88 additions & 4 deletions chartjs-plugin-annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ function drawAnnotations(drawTime, chartInstance, easingDecimal) {
var ctx = chartInstance.chart.ctx;

annotationObjects.forEach(function(obj) {
obj.transition(easingDecimal).draw(ctx);
var opts = annotationOpts.annotations[obj._index];
obj.transition(easingDecimal).draw(ctx, opts);
});
}
}
Expand All @@ -139,12 +140,27 @@ var annotationPlugin = {
beforeInit: function(chartInstance) {
var options = chartInstance.options;
options.annotation = helpers.configMerge(Chart.Annotation.defaults, options.annotation);

var defaultLabelOptions = {
backgroundColor: 'rgba(0,0,0,0.8)',
fontFamily: options.defaultFontFamily,
fontSize: options.defaultFontSize,
fontStyle: "bold",
fontColor: "#fff",
xPadding: 6,
yPadding: 6,
cornerRadius: 6,
position: "center",
xAdjust: 0,
yAdjust: 0,
enabled: false,
content: null
};
var annotationConfigs = options.annotation.annotations;
if (isArray(annotationConfigs)) {
var annotationObjects = chartInstance._annotationObjects = [];

annotationConfigs.forEach(function(configuration, i) {
configuration.label = helpers.configMerge(defaultLabelOptions, configuration.label);
var Constructor = annotationTypes[configuration.type];
if (Constructor) {
annotationObjects.push(new Constructor({
Expand Down Expand Up @@ -198,14 +214,19 @@ module.exports = annotationPlugin;
Chart.pluginService.register(annotationPlugin);

},{"./box.js":2,"./line.js":4,"chart.js":1}],4:[function(require,module,exports){
// Get the chart variable
var Chart = require('chart.js');
Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
var helpers = Chart.helpers;

// Line Annotation implementation
module.exports = function(Chart) {
var horizontalKeyword = 'horizontal';
var verticalKeyword = 'vertical';

var LineAnnotation = Chart.Element.extend({

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

// Canvas setup
Expand All @@ -224,13 +245,76 @@ module.exports = function(Chart) {
ctx.lineTo(view.x2, view.y2);
ctx.stroke();
ctx.restore();

if (options.label.enabled && options.label.content) {
ctx.fillStyle = options.label.backgroundColor;
ctx.font = helpers.fontString(
options.label.fontSize,
options.label.fontStyle,
options.label.fontFamily
);
var text = ctx.measureText(options.label.content);
var position = calculatePosition(
options.label.position,
options.label.xAdjust,
options.label.yAdjust,
view,
text.width,
options.label.fontSize
);

// Draw the tooltip
helpers.drawRoundedRectangle(
ctx,
position.x - options.label.xPadding, // x
position.y - options.label.yPadding, // y
text.width + (2 * options.label.xPadding), // width
options.label.fontSize + (2 * options.label.yPadding), // height
options.label.cornerRadius // radius
);
ctx.fill();

// Draw the text
ctx.fillStyle = options.label.fontColor;
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.fillText(
options.label.content,
position.x,
position.y
);
}
}
});

function isValid(num) {
return !isNaN(num) && isFinite(num);
}

function calculatePosition(option, adjustX, adjustY, view, width, height) {
var ret = {
x: ((view.x1 + view.x2 - width) / 2),
y: ((view.y1 + view.y2 - height) / 2)
};
switch (option) {
case "top":
ret.y = view.y1 > view.y2 ? view.y2 : view.y1;
break;
case "left":
ret.x = view.x1 > view.x2 ? view.x1 : view.x2;
break;
case "bottom":
ret.y = view.y1 > view.y2 ? view.y1 : view.y2;
break;
case "right":
ret.x = view.x1 > view.x2 ? view.x2 : view.x1;
break;
}
ret.x += adjustX;
ret.y += adjustY;
return ret;
}

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

Expand Down Expand Up @@ -268,4 +352,4 @@ module.exports = function(Chart) {
};
};

},{}]},{},[3]);
},{"chart.js":1}]},{},[3]);
2 changes: 1 addition & 1 deletion chartjs-plugin-annotation.min.js

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

164 changes: 164 additions & 0 deletions samples/labels.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<!doctype html>
<html>

<head>
<title>Scatter Chart</title>
<script src="../node_modules/chart.js/dist/Chart.bundle.js"></script>
<script src="../Chart.Annotation.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>

<body>
<div style="width:75%">
<div>
<canvas id="canvas"></canvas>
</div>
</div>
<script>
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColor = function(opacity) {
return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + (opacity || '.3') + ')';
};

var scatterChartData = {
datasets: [{
label: "My First dataset",
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}, {
label: "My Second dataset",
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}]
};

scatterChartData.datasets.forEach(function(dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.1);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});

window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
title: {
display: true,
text: 'Chart.js Scatter Chart'
},
scales: {
xAxes: [{
position: 'top',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'x axis'
},
ticks: {
maxRotation: 0,
reverse: true
}
}],
yAxes: [{
position: 'right',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'y axis'
},
ticks: {
reverse: true
}
}]
},
annotation: {
annotations: [{
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-1',
value: '25',
borderColor: 'black',
borderWidth: 5,
label: {
backgroundColor: "red",
content: "This is a long test label",
enabled: true
}
},
{
type: 'line',
mode: 'vertical',
scaleID: 'x-axis-1',
value: '25',
borderColor: 'red',
borderWidth: 5,
label: {
position: "top",
yAdjust: 15,
content: "This is a another test label",
enabled: true
}
}]
}
}
});
};
</script>
</body>

</html>
Loading