I'm trying to add a text to the right side of the chart. That's working fine. But I want import that text into pdf and/or image files, generated by the exporting library, and right now that is not working. Here is my code: http://jsfiddle.net/mrocha/TQ54c/
$(function () {
/**
* Create the data table
*/
Highcharts.drawTable = function() {
// user options
var tableTop = 420,
colWidth = 60,
tableLeft = 20,
rowHeight = 20,
cellPadding = 2.5,
valueDecimals = 1,
valueSuffix = ' C';
// internal variables
var chart = this,
series = chart.series,
renderer = chart.renderer,
cellLeft = tableLeft;
// draw category labels
$.each(series, function(serie_index, serie) {
renderer.text(
serie.name,
cellLeft + cellPadding,
tableTop + (serie_index + 2) * rowHeight - cellPadding
)
.css({
fontWeight: 'bold'
})
.add();
});
$.each(chart.xAxis[0].categories, function(category_index, category) {
cellLeft += colWidth;
// Apply the cell text
renderer.text(
category,
cellLeft - cellPadding + colWidth,
tableTop + rowHeight - cellPadding
)
.attr({
align: 'right'
})
.css({
fontWeight: 'bold'
})
.add();
$.each(series, function(i) {
renderer.text(
Highcharts.numberFormat(series[i].data[category_index].y, valueDecimals) + valueSuffix,
cellLeft + colWidth - cellPadding,
tableTop + (i + 2) * rowHeight - cellPadding
)
.attr({
align: 'right'
})
.add();
});
});
}
/**
* Draw a single line in the table
*/
Highcharts.tableLine = function (renderer, x1, y1, x2, y2) {
renderer.path(['M', x1, y1, 'L', x2, y2])
.attr({
'stroke': 'silver',
'stroke-width': 1
})
.add();
};
/**
* Create the chart
*/
window.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
events: {
load: Highcharts.drawTable
},
height: 600,
width: 800,
marginBottom: 250
},
title: {
text: 'Average monthly temperatures'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
title: {
text: 'Temperature (C)'
}
},
legend: {
y: -170
},
series: [{
name: 'Tokyo',
data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}, {
name: 'Berlin',
data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
}, {
name: 'London',
data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
}]
});
chart.renderer.text('This text should be at the right side of the chart. And should be exported into pdf or image file',
680, 80 ).
css({
width: 100,
color: 'green',
textAlign: 'left'
}).attr({
zIndex: 999
}).add();
});
Any idea? Am I doing something wrong? Thanks in advance!
Oh, by the way, I'm including a table too, and that table is exported nicely to pdf and image files. I just need to include my green text too.
It is caused, becase you add text by renderer, but during export chart is gernerated again without "dynamic" content which you add. So the solution is move using renderer to load event in chart. In your case it is to function drawTable.
Take look at example:
http://jsfiddle.net/mrocha/TQ54c/
Highcharts.drawTable = function() {
//custom text
this.renderer.text('This text should be at the right side of the chart. And should be exported into pdf or image file',
680, 80 ).
css({
width: 100,
color: 'green',
textAlign: 'left'
}).attr({
zIndex: 999
}).add();
//...
};
Related
I am having trouble displaying small values in my chart.js chart. My issue is very similar to a question asked here:
How to show small values in Flot Pie chart
Does anyone know if there is a workaround in chart.js?
You can use chartjs-plugin-datalabels and define a dataset with same data but weight: 0 for displaying small values outside of the chart.
{
data: data,
weight: 0,
borderWidth: 20,
datalabels: {
formatter: v => v < 5 ? v : ''
}
}
Then also add a datalabels.formatter to the original dataset and make sure, it returns an empty string for small values.
datalabels: {
textAlign: 'center',
formatter: v => v < 5 ? '' : v
}
Please take a look at the runnable code below and see how it works.
const data = [48, 56, 3, 1, 44];
Chart.register(ChartDataLabels);
new Chart('myChart', {
type: 'pie',
data: {
labels: ['red', 'blue', 'green', 'purple', 'gray'],
datasets: [{
data: data,
weight: 0,
borderWidth: 20,
datalabels: {
formatter: v => v < 5 ? v : ''
}
},
{
label: 'My Dataset',
data: data,
backgroundColor: ['rgba(255, 0, 0, 0.2)', 'rgba(0, 0, 255, 0.2)', 'rgba(0, 255, 0, 0.2)', 'rgba(145, 90, 185, 0.2)', 'rgba(124, 124, 124, 0.2)'],
datalabels: {
textAlign: 'center',
formatter: v => v < 5 ? '' : v
}
}
]
},
options: {
responsive: false,
plugins: {
legend: {
display: false
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2"></script>
<canvas id="myChart" height="300"></canvas>
Need help with chart js
ACTUALLY, I'M USING VUE-CHARTJS BUT IT'S JUST A WRAPPER
in the line chart on the left side, the number is increasing by 5(0, 5, 10, 15, etc) I want it to increase by 10 and also decrease the height of the chart so the aspect ratio is something like 16/9
also is it possible to make the left number say 5k+, 10k+, 15k+ instead of just 5, 10, 15
here's my code for the chart
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
data: () => ({
chartdata: {
labels: ['January', 'February', 'March', 'April', 'May','Jun'],
datasets: [
{
data: [12, 20, 27, 22, 14, 10],
borderColor: "#135193",
pointBackgroundColor: "#135193",
pointBorderColor: "#135193",
backgroundColor: 'rgba(255, 255, 255, 0)'
},
{
data: [3, 12, 17, 20, 30, 40],
borderColor: "#FF8811",
pointBackgroundColor: "#FF8811",
pointBorderColor: "#FF8811",
backgroundColor: 'rgba(255, 255, 255, 0)'
}
]
},
options: {
responsive: true,
legend: {
display: false
}
}
}),
mounted () {
this.renderChart(this.chartdata, this.options)
}
}
</script>
Yes, you can just use CSS to set the dimensions of the canvas and set maintainAspectRatio to false in the options, for the ticks you can use the tick callback:
const labels = ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"];
const options = {
type: 'line',
data: {
labels,
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'red',
backgroundColor: 'pink'
}]
},
options: {
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
callback: (val) => (`${val}K`)
}
}]
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
canvas {
max-height: 180px;
max-width: 320px;
}
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
Okay it turns out its as simple as wrapping the chart with a container and set height of that container as needed
I'm plotting a HighCharts heatmap of a wafer with around 50~70k points (it's like a CPU/processor silicon wafer). I need to put horizontal and vertical gridlines visible on the map, so that our engineers can easily figure out what's going on with the actual unit.
I have two concerns:
Horizontal gridlines are already OK, but the vertical gridlines are not drawn or visible. I thought, I just need to set gridZIndex=4. Kindly see image below - it should be drawn based on xAxis.tickPositions values (similar to yAxis)
I put some color options I found, but none of them could change the grid's color.
So far this is my code:
var option = {
chart: {
type: 'heatmap',
zoomType: 'xy',
},
boost: {
useGPUTranslations: true
},
title: {
text: chrt_title,
align: 'left',
x: 0,
style: {
fontSize: '12px',
}
},
exporting: {
buttons: {
contextButton: {
menuItems: [
'viewFullscreen', 'downloadPNG', 'downloadXLS'
]
}
},
enable: true,
},
xAxis: {
title: {
text: null
},
labels: {
enabled: false,
},
tickPositions: [1, 19, 43, 67, 91, 115, 139, 163, 183],
gridZIndex: 4, // DOESN'T WORK
gridLineDashStyle: 'Dash',
gridLineWidth: 1, // DOESN'T WORK
lineColor: 'red',
minorTickColor: 'red',
tickColor: 'red'
},
yAxis: {
title: {
text: null
},
reversed: true,
labels: {
enabled: false,
},
tickPositions: [1, 82, 116, 174, 272, 370, 428, 462, 544]
gridZIndex: 4, // ONLY PUT THIS AND WORKS ALREADY
gridLineDashStyle: 'Dash', // THIS WORKS TOO (Dot,Solid,etc)
lineColor: 'red',
minorTickColor: 'red',
tickColor: 'red'
},
colorAxis: {
stops: colrstops,
min: minval,
max: maxval,
startOnTick: true,
endOnTick: true,
labels: {
format: '{value}',
style: {
fontSize: '8px',
fontFamily: 'Verdana, sans-serif'
}
}
},
series: [{
boostThreshold: 100,
borderWidth: 0,
nullColor: '#ffffff',
tooltip: {
headerFormat: chrt_title + '<br/>',
pointFormat: 'RB{point.y} SL{point.x} <b>{point.value}</b>'
},
turboThreshold: Number.MAX_VALUE, // #3404, remove after 4.0.5 release
data: data
}]
}
As you can see, both xAxis and yAxis have gridZIndex = 4, gridLineDashStyle = 'Dash', but only the yAxis that gives the horizontal gridlines, no luck for xAxis (assuming this is where need to set the vertical gridlines) :(
the only similar question i found reg vertical gridlines is this one:
Highcharts: xAxis with vertical gridlines
but I tried to put the gridLineWidth=1, still nothin's happening T-T please help. thanks very much.
Update:
I temporarily replaced my option{} based on #ppotaczek sample but vertical gridlines still did not appeared.
Then I played with my own option{}, tried to add min and max in xAxis, and tried to temporarily removed my dynamic data and use #ppotaczek sample, the layout remains the same (no vertical gridlines)..
Also thought it has something to do with the version i'm using..? it's 9.0.1 - so I tried to update to latest 9.1.1, but also have same result.
var option = {
chart: {
type: 'heatmap',
},
xAxis: {
tickPositions: [1, 19, 43, 67, 91, 115, 139, 163, 183],
min: 1,
max: 183,
gridZIndex: 4, // DOESN'T WORK
gridLineDashStyle: 'Dash',
gridLineWidth: 1, // DOESN'T WORK
lineColor: 'red',
minorTickColor: 'red',
tickColor: 'red'
},
yAxis: {
title: {
text: null
},
reversed: true,
labels: {
enabled: false,
},
tickPositions: [1, 82, 116, 174, 272, 370, 428, 462, 544],
gridLineDashStyle: 'Dash', // THIS WORKS TOO (Dot,Solid,etc)
lineColor: 'red',
minorTickColor: 'red',
tickColor: 'red',
},
colorAxis: {},
series: [{
data: [
[10, 0, 1],
[20, 1, 5],
[30, 1, 5],
],
}]
}
I am using highchart. I want to display the maximum value and value label at the bottom of the pie chart.please see the attached screenshot. if the maximum value is equal display both value and that label.
this.pieChart.push(
{
chart: {
type: 'pie',
options3d: {
enabled: true,
alpha: 45
}
},
title: {
text: 'Question Title'
},
subtitle: {
text: ''
},
plotOptions: {
pie: {
innerSize: 100,
depth: 45,
dataLabels: {
enabled: true,
format: '<b></b><br>{point.percentage:.1f} %',
distance: -50,
filter: {
property: 'percentage',
operator: '>',
value: 4
}
}
}
},
series: [{
name: 'Answer Selected',
data: [
['1st Que ans - 1', 3],
['1st Que ans - 2', 2],
['1st Que ans - 3', 1],
['1st Que ans - 4', 2]
]
}]
})
Here is an example of how to render a custom label base on the included data and using the render callback. The instruction what is happening is in the code. If something is unclear - feel free to ask.
Demo: https://jsfiddle.net/BlackLabel/euLyc49j/
events: {
render() {
let chart = this,
max = Math.max(...chart.series[0].processedYData);
chart.series[0].points.forEach(p => {
if (p.y === max) {
if (p.customLabel) {
p.customLabel.destroy();
}
//render label in the (0, 0)
p.customLabel = chart.renderer.label(p.name + ' - ' + p.y , 0, 0)
.css({
color: '#FFFFFF'
})
.attr({
fill: 'rgba(0, 0, 0, 0.75)',
padding: 8,
r: 5,
zIndex: 6
})
.add();
// position label in the bottom center
p.customLabel.translate(chart.plotWidth / 2 - p.customLabel.getBBox().width / 2, chart.plotSizeY + chart.plotTop)
}
})
}
}
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
API: https://api.highcharts.com/highcharts/chart.events.render
I'm trying to draw a mass and balance diagram with Chart.js. Basically it's a rectangle. This is my code so far (as a test):
const data: any = {
//labels: ["L1", "L2", "L2+", "L3"],
datasets: [
{
label: "My First dataset",
backgroundColor: "rgba(255, 99, 132, 0.2)",
borderColor: "rgba(255, 99, 132, 1)",
data: [{ x: 10, y: 20 }, { x: 15, y: 30 },{x:15, y:40}, { x: 20, y: 80 }],
lineTension: 0
}
],
};
const options: any = {
}
const ctx: CanvasRenderingContext2D = (document.getElementById("massAndBalanceCanvas") as HTMLCanvasElement).getContext("2d");
const diagram: Chart = new Chart(ctx, {
type: "line",
data: data,
options: options
});
If I change the chart type from "line" to "scatter", the diagram corners are correctly set but I can't managed to connect the point with lines.
Somebody know how to achieve it?
Thanks!