Chart.js Bar chart resizes again when revisiting the tab - chart.js

I'm using react-chartjs-2 wrappers Pie and Bar within Bootstrap Tab components like below.
<TabContent activeTab={activeTab}>
<TabPane tabId='1'>
<Row>
<Col>
<div className='chart-container'>
<Pie
data={pieData}
options={{...}}
/>
</div>
</Col>
</Row>
</TabPane>
<TabPane tabId='2'>
<Row>
<Col>
<div className='chart-container'>
<Bar
data={barData}
options={{...}}
/>
</div>
</Col>
</Row>
</TabPane>
</TabContent>
A part of the options object provided to the Bar instance is this.
responsive: true,
onResize: function(newChart, newSize) {
if (newSize.width < 768) {
newChart.options.scales.xAxes[0].ticks.display = false;
} else {
newChart.options.scales.xAxes[0].ticks.display = true;
}
},
legend: {
display: true,
position: 'bottom',
labels: {
generateLabels: function(chart) {
if (chart.width < 768) {
chart.options.scales.xAxes[0].ticks.display = false;
}
}
}
}, ...
When the page is loaded initially the Bar instance takes up the whole container. However when I switch to the tab 1 with the Pie instance then to the tab 2 with the Pie instance the later resizes about half the size of the container. By the size the graph reduces to it might look like the Bar instance tried to display the X axis tick labels.
The div.chart-container css rules are
.chart-container {
margin: 20px auto;
}
The complete code is at https://github.com/ElAnonimo/job-fullstack/blob/master/client/src/components/Stats.js.

Solved it like this. In the Bar chart options:
scales: {
xAxes: [{
display: true,
ticks: {
display: false,
callback: function(value, index, values) {
return `${value.date}, ${value.time}`;
}
}
}]
}
Though I would've thought display: false would turn off the ticks at the very creation (initialization) of the Bar chart still at the full screen size the ticks are there when the page first loads.
Comments or explanations are welcome.

Related

how to show text inside a chart - pie and doughnut?

I have tried a lot of it, but nothing seems to be working as expected.
I need to show the text inside the pie chart.
For the above, I tried using chartjs-plugin-datalabels but then used a formatter to change a value to a value with a percentage.
formatter: function(value:any, context:Context) {
return Math.floor(value) + '%';
},
But that affected both the data point (i.e: [11,200] is by data, I only need to add a percentage to the first data point and not to the second. Show 11% and 200.)
Code:
import ChartDataLabels,{Context} from 'chartjs-plugin-datalabels';
ChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);
export const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
datalabels: {
formatter: function(value:any, context:Context) {
return Math.floor(value) + '%';
},
color:"white",
font: {
size: 16,
weight:'bold'
}
},
title: {
display: true,
},
legend: {
display: false,
},
},
};
function MyChart(){
return(
<Pie data={dataChart} options={options} />
)
}
In the above code options in the Pie, the component shows a typescript error while using chartjs-plugin-datalabels library.
The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Omit<ChartProps<"doughnut", number[], unknown>, "type"> & { ref?: ForwardedRef<ChartJSOrUndefined<"doughnut", number[], unknown>> | undefined; }'
2: I need to show text in the center of a Doughnut chart but seems impossible with the library and reactchartjs2 don't have a feature to show text in charts. Tried a possible solution at Add text inside the Doughnut chart of the React-Chartjs-2 box to react but none helped.

Angular Chart.js Bar Chart

I am using a bar chart of chart.js in angular 7.This chart shows the relationship between policies and their number of sales. If the maximum number of sales is 2 or 1 or a small number, the chart shows the values along the y-axis in points, starts from 1 and ends on the maximum value.Right now i have maximum 6 policies, hence the values do not have points in them, but when the number of maximum policies reduce to 2, the values are as 1.0, 1.1, 1.2, 1.3....2.0. I want the values to be non-decimal in the y-axis and also they should start from zero up to the maximum number as 0,1,2,3...,. Is it possible?
//component
chartData1 = [
{
label: 'Policies',
data: this.policies
},
];
chartOptions = {
responsive: true // THIS WILL MAKE THE CHART RESPONSIVE (VISIBLE IN ANY DEVICE).
}
//template
<canvas
baseChart
[chartType]="'bar'"
[datasets]="chartData"
[labels]="labels"
[options]="chartOptions"
[legend]="true"
height="80"
width="100"
[colors]="colors"
(chartClick)="onChartClick($event)">
</canvas>
Within your component, try to define chartOptions as follows:
chartOptions = {
responsive: true,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1
}
}]
}
}

Show "No Data" message for Pie chart with no data

I have below Piechart using chartjs. I need to show a "No Data" message on it when there is nothing to show.
But I am unable to find such a way in chartjs tutorials. Can someone please help?
Pie Chart HTML
<div id="canvas-holder-CT" style="width:46%;float:right;position: absolute; left: 0px; top: 700px;">
<canvas id="chart-area-CT" width="350" height="450" style="display: block; margin-left:2em">
</canvas>
<center> <b><details>
<summary>Distribution by Call Types</summary>
</details> </b></center>
</div>
Pie chart script
var configCT = {
type : 'pie',
data : {
datasets : [{
data : valuesCT,
backgroundColor : coloringCT,
label : 'Distribution by Call Types'
}
],
labels : labelsCT
},
options : {
segmentShowStroke : false,
legend : false,
animateScale : true,
responsive : true,
showAllTooltips : false,
tooltips : {
custom : function (tooltip) {
if (!tooltip)
return;
tooltip.displayColors = false;
}
}
}
};
var ctxCT = document.getElementById("chart-area-CT").getContext("2d");
if (myPieCT != null) {
myPieCT.destroy();
}
myPieCT = new Chart(ctxCT, configCT);
Have you checked this open issue?
And the relative solution proposed by etimberg user:
Chart.plugins.register({
afterDraw: function(chart) {
if (chart.data.datasets.length === 0) {
// No data is present
var ctx = chart.chart.ctx;
var width = chart.chart.width;
var height = chart.chart.height
chart.clear();
ctx.save();
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = "16px normal 'Helvetica Nueue'";
ctx.fillText('No data to display', width / 2, height / 2);
ctx.restore();
}
}
});
See: https://jsfiddle.net/x04ptfuu/
Could be handle by CSS display property.
foo.html
<div id="showId" class="showData">
<canvas id="myChart"></canvas>
</div>
<div id="noId" class="noData">
<span>No Data Available</span>
<div>
foo.css
.showData {
display: block;
}
.noData {
display: none;
}
foo.js
// ...code
if(chartData) {
document.getElementById("showId").classList.add("showData");
document.getElementById("noId").classList.remove("noData");
} else {
document.getElementById("showId").classList.remove("showData");
document.getElementById("noId").classList.add("noData");
}

Gradient color in nvd3 area and bar charts?

Is it possible to apply gradient color to area(filled-line) charts in nvd3.
I have seen a workaround in d3 charts, using the svg object.
But is there a simpler way to do this, or any hack to get the same done?
Too little info in your question, however here below is an example of area chart with gradient.
This is based on SVG Gradients:
<svg>
<defs>
<linearGradient id="grad3" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
</defs>
</svg>
After Gradient definition in SVG use it in CSS like this:
.nv-area { fill: url(#grad3) }
var data = [{
"key": "Quantity",
"bar": true,
"area": true,
"values": [
[1301544000000, 2000],
[1304136000000, 2500],
[1306814400000, 1800],
[1309406400000, 2100],
[1312084800000, 2100],
[1314763200000, 2800]
]
}]
nv.addGraph(function() {
chart = nv.models.lineChart();
chart.margin({
left: 100,
bottom: 100
}).useInteractiveGuideline(true).showLegend(true).duration(250);
chart.xAxis.axisLabel("Date").tickFormat(function(d) {
var date = new Date(data[0].values[d][0]);
return d3.time.format("%b-%e")(date);
});
chart.yAxis.axisLabel('Quantity').tickFormat(d3.format(',.2f'));
chart.x(function(d, i) {
return i
})
.y(function(d) {
return d[1]
})
chart.showXAxis(true);
d3.select('#chart svg').datum(data)
.transition().call(chart);
return chart;
});
#chart svg {
height: 400px;
}
.nv-area { fill: url(#grad3) }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://rawgit.com/novus/nvd3/master/build/nv.d3.js"></script>
<link href="https://rawgit.com/novus/nvd3/master/build/nv.d3.css" rel="stylesheet"/>
<div id="chart">
<svg>
<defs>
<linearGradient id="grad3" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
</defs>
</svg>
</div>

google visualization chart, size in percentage

How do you set the size of a google chart in percentage :
I have this in the html:
<div id="chart_div" width="90%" height="20%"></div>
and no width nor height in the options in the js.
But the chart size doesn't adapt to the viewport.
First, use styles to set your dimensions, not attributes:
<div id="chart_div" style="width: 90%; height: 20%;"></div>
The chart will draw to the size of the div by default, but the charts are not responsive. You have to hook a "resize" event handler to the window (or other element if you are resizing within a window) that redraws the chart:
function resizeChart () {
chart.draw(data, options);
}
if (document.addEventListener) {
window.addEventListener('resize', resizeChart);
}
else if (document.attachEvent) {
window.attachEvent('onresize', resizeChart);
}
else {
window.resize = resizeChart;
}
By multiplying with appropriate factor to $(window).width() or $(window).height() in the chart options
var options = {
width: $(window).width(),
height: $(window).height()*0.75
};
Google recommend that you style, like the answer above, with correct CSS and this makes a less-glitchy Chart.
However, you can size it up in Javascript...
https://developers.google.com/chart/interactive/docs/basic_customizing_chart
So, for the options when you draw the chart (using chart.draw(data, options) as above)...
var options = {
width:400,
height:300
}
A good fiddle for a responsive design is here...
http://jsfiddle.net/toddlevy/pyAz5/
$(window).resize(function(){
var container = document.getElementById("chart_div").firstChild.firstChild;
container.style.width = "100%";
chart.draw(data, options);
});
Please Remove the width and the height properties from the options in the scripts and then add the following style to your page
<style>
.chart {
width: 100%;
min-height: 450px;
}
.row {
margin: 0 !important;
}
</style>