hey guys thanks for reading, and helping...
i have chart bar using chart.js, i found similar on js fiddle
here is the link http://jsfiddle.net/uh9vw0ao/
var chartData = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [
{
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data: [60, 80, 81, 56, 55, 40]
}
]
};
var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.points.forEach(function (points) {
ctx.fillText(points.value, points.x, points.y - 10);
});
})
}
});
var ctx = document.getElementById("myChart2").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.bars.forEach(function (bar) {
ctx.fillText(bar.value, bar.x, bar.y - 5);
});
})
}
});
question is how can i add value beside existing data, example :
example please click..
Thankyou very much!
A very quick and dirty method would be to use a paired array that has the values you want to disaply for each data point at the same index point
i.e. var supportingData = [12, 14, 15, 16, 17, 26];
then in the onAnimation complete use the index of the current data set to draw out the data form this array at the same time
dataset.bars.forEach(function(bar, index) {
//keep a refence of the fillstyle to change back to later
var ctxColour = ctx.fillStyle;
ctx.fillText(bar.value, bar.x, bar.y - 5);
ctx.fillStyle = "#FF0000";
ctx.fillText("$" + supportingData[index], bar.x + (ctx.measureText(bar.value).width)+10, bar.y - 5);
//reset the fill style
ctx.fillStyle = ctxColour;
});
because this is chartjs 1.x I do not think extra data you give to the chart is passed to the actual chart so if you wanted something a bit nicer you would need to extend your own chart and allow it to take this extra supporting data, but the method for displaying would be the same
var chartData = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data: [60, 80, 81, 56, 55, 40]
}]
};
//add an array to have your paird data in
var supportingData = [12, 14, 15, 16, 17, 26];
var ctx = document.getElementById("myChart2").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
showTooltips: false,
onAnimationComplete: function() {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function(dataset) {
dataset.bars.forEach(function(bar, index) {
//keep a refence of the fillstyle to change back to later
var ctxColour = ctx.fillStyle;
ctx.fillText(bar.value, bar.x, bar.y - 5);
ctx.fillStyle = "#FF0000";
ctx.fillText("$" + supportingData[index], bar.x + (ctx.measureText(bar.value).width)+10, bar.y - 5);
//reset the fill sty;e
ctx.fillStyle = ctxColour;
});
})
}
});
<script src="https://rawgit.com/nnnick/Chart.js/v1.0.2/Chart.min.js"></script>
<canvas id="myChart2" height="300" width="500"></canvas>
Related
i have the following bar chart and tooltip showing info value
var chartData = {
labels: ["Chevrolet", "Volkswagen", "Fiat", "Ford", "Renault", "Toyota"],
datasets: [
{
fillColor: "#FFB6C1",
strokeColor: "#FF1493",
data: [87, 80, 56, 50, 18, 78]
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
});
Fiddle
I would like to print this graphic but the tooltip values will not print. So how can I show the values at the top of the bar chart ?
You can loop through the bars onAnimationComplete function and display the values
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.datasets.forEach(function (dataset) {
dataset.bars.forEach(function (bar) {
ctx.fillText(bar.value, bar.x, bar.y - 5);
});
})
}
look in my full Fiddle
I've been trying to add a vertical line that shows up with a tooltip when hovering over the chart. But I'm using chart.js 2.6 and the syntax from 1.x seems to be outdated.
I've the following code working for 1.x
var data = {
labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
datasets: [{
data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1]
}]
};
var ctx = document.getElementById("LineWithLine").getContext("2d");
Chart.types.Line.extend({
name: "LineWithLine",
initialize: function() {
Chart.types.Line.prototype.initialize.apply(this, arguments);
var originalShowTooltip = this.showTooltip;
this.showTooltip = function(activePoints) {
if (activePoints.length) {
var ctx = this.chart.ctx;
var scale = this.scale;
ctx.save();
ctx.strokeStyle = '#aaa';
ctx.beginPath();
ctx.moveTo(activePoints[0].x, scale.startPoint);
ctx.lineTo(activePoints[0].x, scale.endPoint);
ctx.stroke();
ctx.restore();
}
return originalShowTooltip.apply(this, arguments);
}
}
});
new Chart(ctx).LineWithLine(data, {
datasetFill: false,
lineAtIndex: 2
});
<canvas id="LineWithLine" style="width: 98vw; height:180px"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
External link
Anyone know how to make it work for 2.6
Solution for ChartJS 2.6.0
ꜱᴄʀɪᴘᴛ (ᴇxᴛᴇɴᴅɪɴɢ ʟɪɴᴇ ᴄʜᴀʀᴛ)
Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
draw: function(ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
var activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.legend.bottom,
bottomY = this.chart.chartArea.bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 2;
ctx.strokeStyle = '#07C';
ctx.stroke();
ctx.restore();
}
}
});
You would also need to set intersect: false for tooltips.
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩
Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
draw: function(ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
var activePoint = this.chart.tooltip._active[0],
ctx = this.chart.ctx,
x = activePoint.tooltipPosition().x,
topY = this.chart.legend.bottom,
bottomY = this.chart.chartArea.bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 2;
ctx.strokeStyle = '#07C';
ctx.stroke();
ctx.restore();
}
}
});
var chart = new Chart(ctx, {
type: 'LineWithLine',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
datasets: [{
label: 'Statistics',
data: [3, 1, 2, 5, 4, 7, 6],
backgroundColor: 'rgba(0, 119, 204, 0.8)',
borderColor: 'rgba(0, 119, 204, 0.3)',
fill: false
}]
},
options: {
responsive: false,
tooltips: {
intersect: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" height="200"></canvas>
Try this:
var ctx = this.$refs.canvas.getContext("2d");
// new Chart(ctx, config);
var originalLineDraw = Chart.controllers.line.prototype.draw;
Chart.helpers.extend(Chart.controllers.line.prototype, {
draw: function() {
originalLineDraw.apply(this, arguments);
var chart = this.chart;
var ctx = chart.chart.ctx;
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
var activePoint = this.chart.tooltip._active[0];
var ctx = this.chart.ctx;
var x = activePoint.tooltipPosition().x;
var topY = this.chart.scales['y-axis-0'].top;
var bottomY = this.chart.scales['y-axis-0'].bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 0.5;
ctx.strokeStyle = '#eeeeee';
ctx.stroke();
ctx.restore();
}
}});
This will definitely help you.
This question is five years old. Nowadays, we can achieve this using plugins and hook calls in this case beforeTooltipDraw to capture the tooltip.caretX. Also we can use the build-in interaction option to achieve this.
This implementacion works with versions 3.x and 4.0.1 of ChartJS
const $chart = document.getElementById('chart')
const plugin = {
id: 'verticalLiner',
afterInit: (chart, args, opts) => {
chart.verticalLiner = {}
},
afterEvent: (chart, args, options) => {
const {inChartArea} = args
chart.verticalLiner = {draw: inChartArea}
},
beforeTooltipDraw: (chart, args, options) => {
const {draw} = chart.verticalLiner
if (!draw) return
const {ctx} = chart
const {top, bottom} = chart.chartArea
const {tooltip} = args
const x = tooltip?.caretX
if (!x) return
ctx.save()
ctx.beginPath()
ctx.moveTo(x, top)
ctx.lineTo(x, bottom)
ctx.stroke()
ctx.restore()
}
}
const data = {
labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
datasets: [{
data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1]
}]
}
const options = {
type: 'line',
data,
options: {
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
verticalLiner: {}
}
},
plugins: [plugin]
}
const chart = new Chart($chart, options)
<div class="wrapper" style="width: 98vw; height:180px">
<canvas id="chart"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
In the javascript graphing library, is there a way I can change the line segment color of the line between two adjacent points?
Thanks
You can extend the chart to redraw the segment of your choice with the different color.
Preview
Script
Chart.types.Line.extend({
name: "LineAlt",
draw: function () {
Chart.types.Line.prototype.draw.apply(this, arguments);
var index = 1;
var datasetIndex = 0;
var hasValue = function(item){
return item.value !== null;
},
previousPoint = function (point, collection, index) {
return Chart.helpers.findPreviousWhere(collection, hasValue, index) || point;
};
var ctx = this.chart.ctx;
var dataset = this.datasets[datasetIndex];
var pointsWithValues = Chart.helpers.where(dataset.points, hasValue);
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.beginPath();
var point = dataset.points[index];
ctx.moveTo(point.x, point.y);
point = dataset.points[index + 1];
var previous = previousPoint(point, pointsWithValues, index + 1);
ctx.bezierCurveTo(
previous.controlPoints.outer.x,
previous.controlPoints.outer.y,
point.controlPoints.inner.x,
point.controlPoints.inner.y,
point.x,
point.y
);
ctx.stroke();
}
});
and
...
new Chart(ctx).LineAlt(data);
Fiddle - http://jsfiddle.net/021xvuhd/10/
Here's a working example to do this in Charts.js 2
https://jsfiddle.net/egamegadrive16/zjdwr4fh/
var ctx = document.getElementById('myChart').getContext('2d');
//adding custom chart type
Chart.defaults.multicolorLine = Chart.defaults.line;
Chart.controllers.multicolorLine = Chart.controllers.line.extend({
draw: function(ease) {
var
startIndex = 0,
meta = this.getMeta(),
points = meta.data || [],
colors = this.getDataset().colors,
area = this.chart.chartArea,
originalDatasets = meta.dataset._children
.filter(function(data) {
return !isNaN(data._view.y);
});
function _setColor(newColor, meta) {
meta.dataset._view.borderColor = newColor;
}
if (!colors) {
Chart.controllers.line.prototype.draw.call(this, ease);
return;
}
for (var i = 2; i <= colors.length; i++) {
if (colors[i-1] !== colors[i]) {
_setColor(colors[i-1], meta);
meta.dataset._children = originalDatasets.slice(startIndex, i);
meta.dataset.draw();
startIndex = i - 1;
}
}
meta.dataset._children = originalDatasets.slice(startIndex);
meta.dataset.draw();
meta.dataset._children = originalDatasets;
points.forEach(function(point) {
point.draw(area);
});
}
});
var chart = new Chart(ctx, {
// The type of chart we want to create
type: 'multicolorLine',
// The data for our dataset
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45],
//first color is not important
colors: ['', 'red', 'green', 'blue']
}]
},
// Configuration options go here
options: {}
});
source: https://github.com/chartjs/Chart.js/issues/4895#issuecomment-342747042
It's now built into CHart.js 3:
https://www.chartjs.org/docs/latest/samples/line/segments.html
I am trying to get Chart.js 2.0 to display point values in a line chart using the animation onComplete function. I found a post making it work using 1.02, how to display data values on Chart.js, but I am unable to make it work in v2.
My failing fiddle is at Line Chart v2. Any help would be appreciated.
var chartData = {
labels: ["January", "February", "March", "April", "May", "June"],
datasets: [{
label: "Buttons",
strokeColor: "#79D1CF",
tension: 0,
fill: false,
data: [60, 80, 81, 56, 55, 40]
}, {
label: "Zipppers",
strokeColor: "rgba(255,255,0,1)",
tension: 0,
fill: false,
data: [50, 75, 42, 33, 80, 21]
}]
};
var options = {
animation: {
onComplete: function() {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
//alert(ctx.font);
ctx.fillStyle = this.scale.textColor
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
var datasetName = chartData.data.datasets[0].label;
alert(chartData.data.datasets[0].label)
myLine.data.datasets.forEach(function(dataset) {
ctx.fillStyle = dataset.strokeColor;
dataset.points.forEach(function(points) {
ctx.fillText(points.value, points.x, points.y - 10);
});
})
}
}
};
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = true;
Chart.defaults.global.title.display = true;
Chart.defaults.global.title.text = "My Chart";
Chart.defaults.global.title.fontSize = 30;
Chart.defaults.global.legend.position = "bottom";
Chart.defaults.global.hover.mode = "label";
Chart.defaults.global.tooltips.enabled = true;
var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx, {
type: 'line',
data: chartData,
options: options
});
onComplete: function(animation) {
let ctx: any = this.chart.ctx;
let chart: any = this;
ctx.fillStyle = 'rgb(133, 157, 189)';
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
let datasets = this.config.data.datasets;
datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y - 0);
});
});
}
I use the Version 2.5
I can only assume there is a better way, but for now try this:
var options = {
animation: {
onComplete: function() {
var ctx = this.chart.ctx;
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
this.chart.config.data.datasets.forEach(function(dataset) {
ctx.fillStyle = dataset.strokeColor;
dataset.metaDataset._points.forEach(function(p) {
ctx.fillText(p._chart.config.data.datasets[p._datasetIndex].data[p._index], p._model.x, p._model.y - 10);
});
})
}
}};
for version 2.5 I noticed there is no metaDataset too.
I used this (assuming 'yourdata' contains the data array of your chart).
dataset._meta['1'].dataset._children.forEach((point, index) => {
ctx.fillText(yourdata[index], point._view.x, point._view.y - 15);
});
Hope this helps!
We have been using Chart.js for several months now and like the power it gives us with ease of programming. One of the things we would like to start adding to the charts produced from Chart.js is a little nicer styling of the charts we generate. Most of the charts we are using are bar charts, with a few line charts thrown in.
When I use the term "styling" what I am really talking about is making the bars or lines look a little nicer. Specifically I would like to add a drop shadow behind the bar and line charts, and maybe even a bevel to the bars.
I've looked through many questions, and can't seem to find what I am looking for. I've also done some experimenting myself by modifying the Chart.js file to add a drop shadow and blur to the javascript, but I'm not getting it added in the correct place. I put these changes inside of the Chart.Element.extend draw function:
ctx.shadowColor = '#000';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 8;
I put it right before the ctx.fill() and it almost does what I want. The result is I get a drop shadow that looks pretty good on both the bar and line charts I am drawing, but I also get a drop shadow on the labels for the x and y axes, which does not look good. I'd like to have the drop shadow on just the bars and the lines, not on the labels.
Any help you can provide would be greatly appreciated. I am not experienced with javascript, but have been able to pull off quite a bit of coding I wouldn't otherwise be able to do without the help of everyone on Stack Overflow.
Adding a Drop Shadow for Line Charts
You can extend the line chart type to do this
Preview
Script
Chart.types.Line.extend({
name: "LineAlt",
initialize: function () {
Chart.types.Line.prototype.initialize.apply(this, arguments);
var ctx = this.chart.ctx;
var originalStroke = ctx.stroke;
ctx.stroke = function () {
ctx.save();
ctx.shadowColor = '#000';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 8;
originalStroke.apply(this, arguments)
ctx.restore();
}
}
});
and then
...
var myChart = new Chart(ctx).LineAlt(data, {
datasetFill: false
});
Fiddle - https://jsfiddle.net/7kbz1L4t/
𝚂𝚘𝚕𝚞𝚝𝚒𝚘𝚗 𝚏𝚘𝚛 𝙲𝚑𝚊𝚛𝚝𝙹𝚂 𝟸.𝚡.𝚡
ᴘʀᴇᴠɪᴇᴡ
ꜱᴄʀɪᴘᴛ overriding the draw function
let draw = Chart.controllers.line.prototype.draw;
Chart.controllers.line.prototype.draw = function() {
draw.apply(this, arguments);
let ctx = this.chart.chart.ctx;
let _stroke = ctx.stroke;
ctx.stroke = function() {
ctx.save();
ctx.shadowColor = '#07C';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 4;
_stroke.apply(this, arguments);
ctx.restore();
}
};
let draw = Chart.controllers.line.prototype.draw;
Chart.controllers.line.prototype.draw = function() {
draw.apply(this, arguments);
let ctx = this.chart.chart.ctx;
let _stroke = ctx.stroke;
ctx.stroke = function() {
ctx.save();
ctx.shadowColor = '#07C';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 4;
_stroke.apply(this, arguments);
ctx.restore();
}
};
let ctx = document.querySelector("#canvas").getContext('2d');
let myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
data: [65, 59, 75, 64, 70, 30, 40],
borderColor: '#07C',
pointBackgroundColor: "#FFF",
pointBorderColor: "#07C",
pointHoverBackgroundColor: "#07C",
pointHoverBorderColor: "#FFF",
pointRadius: 4,
pointHoverRadius: 4,
fill: false,
tension: 0.15
}]
},
options: {
responsive: false,
tooltips: {
displayColors: false,
callbacks: {
label: function(e, d) {
return `${e.xLabel} : ${e.yLabel}`
},
title: function() {
return;
}
}
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
max: 90
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="canvas" width="400" height="210" style="background-color: #E4E8F0"></canvas>
This works for new version of Chart JS
We can create a plugin object and register to the chart JS, Plugins are a way for a developer to modify a chart as it is being created, for reference please look at
https://riptutorial.com/chart-js/example/22332/plugins-introduction
Example Plugin to add a shadow to any of the chart
var simpleplugin = {
beforeDraw : function(chartInstance)
{
let _stroke = chartInstance.ctx.stroke;
chartInstance.ctx.stroke = function () {
chartInstance.ctx.save();
chartInstance.ctx.shadowColor = 'gray';
chartInstance.ctx.shadowBlur = 10;
chartInstance.ctx.shadowOffsetX = 2;
chartInstance.ctx.shadowOffsetY = 2;
_stroke.apply(this, arguments)
chartInstance.ctx.restore();
}
let _fill = chartInstance.ctx.fill;
ctx.fill = function () {
chartInstance.ctx.save();
chartInstance.ctx.shadowColor = 'gray';
chartInstance.ctx.shadowBlur = 10;
chartInstance.ctx.shadowOffsetX = 2;
chartInstance.ctx.shadowOffsetY = 2;
_fill.apply(this, arguments)
chartInstance.ctx.restore();
}
}
}
$(function()
{
Chart.pluginService.register(simpleplugin);
});