native element not defined when ngSwitch condition in canvas element - javascript

I am working with chart.js in my ionic 2 application if i implement canvas element with out ngSwitch condition for rendering it works fine but when i use condition i got error with native element not defined so canvas element not rendered because canvas element not ready at the time of subscribe chart data. how can i solve this.
#ViewChild('todayChart') todayChart;
#ViewChild('yesterdayChart') yesterdayChart;
ionViewWillEnter() {
this.homeauth.todaychart().subscribe((table) => {
var labels = [], datay = [], datum = [], timestamp = [];
for (var i = 0; i <= table.length - 1; i++) {
datum.push(table[i].chartdate);
labels.push(table[i].z10s3);
datay.push(table[i].z10s6);
timestamp.push(table[i].timestamp);
}
this.heutechart = new Chart(this.todayChart.nativeElement, {
type: 'line',
data: {
xLabels: labels,
datasets: [
{
label: 'G.Oil', fill: true, lineTension: 0.1, backgroundColor: "rgba(75,192,192,0.4)", borderColor: "rgba(75,192,192,1)",
pointHoverBorderWidth: 2, pointRadius: 1, pointHitRadius: 10, data: datay, spanGaps: false,
}
],
},
});
});
this.homeauth.yesterdaychart().subscribe((table) => {
var labels = [], datay = [], datum = [];
for (var i = 0; i <= table.length - 1; i++) {
datum.push(table[i].chartdate);
labels.push(table[i].z10s3);
datay.push(table[i].z10s6);
}
this.vortagschart = new Chart(this.yesterdayChart.nativeElement, {
type: 'line',
data: {
xLabels: labels,
datasets: [
{
label: 'G.Oil', fill: true, lineTension: 0.1, backgroundColor: "rgba(75,192,192,0.4)", borderColor: "rgba(75,192,192,1)",
pointHoverBorderWidth: 2, pointRadius: 1, pointHitRadius: 10, data: datay, spanGaps: false,
}
],
}
});
});
}
html:
<ion-segment [(ngModel)]="category">
<ion-segment-button value="today"> 24h </ion-segment-button>
<ion-segment-button value="yesterday"> 48h </ion-segment-button>
</ion-segment>
<div [ngSwitch]="category">
<div *ngSwitchCase="'today'">
<canvas #yesterdayChart> </canvas>
</div>
</div>
<div [ngSwitch]="category">
<div *ngSwitchCase="'yesterday'">
<canvas #todayChart></canvas>
</div>
</div>

you dont have to use ng-switch for each case.
It should be like so:
<div [ngSwitch]="category">
<div *ngSwitchCase="'today'"> <!-- case 1 -->
<canvas #yesterdayChart> </canvas>
</div>
<div *ngSwitchCase="'yesterday'">
<canvas #todayChart></canvas> <!-- case 2 -->
</div>
</div>
Add if conditions in the component since only one of these elements will be present in the DOM.
if(this.todayChart){
this.heutechart = new Chart(this.todayChart.nativeElement, {
type: 'line',
data: {
xLabels: labels,
datasets: [
{
label: 'G.Oil', fill: true, lineTension: 0.1, backgroundColor: "rgba(75,192,192,0.4)", borderColor: "rgba(75,192,192,1)",
pointHoverBorderWidth: 2, pointRadius: 1, pointHitRadius: 10, data: datay, spanGaps: false,
}
],
},
});
});
}
//Similarly for yesterdayChart

Related

Hover text of canvas in other div

I want to put text beside the canvas doughnut. This text is based on the hover information of each slide, but instead of appear on the top pf the image i want it to be next to it. (2 images as example)
https://jsfiddle.net/jak2e4zr/
HTML
<canvas id="myChart" ></canvas>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
JS
var ctx = document.getElementById("myChart");
var data = {
labels: ['Residential', 'Non-Residential', 'Utility'],
datasets: [
{
data: [19, 26, 55],
weight: 2,
spacing : 5,
borderWidth : 0,
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}]
};
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: {
circumference: 180,
rotation: -180,
plugins: {
legend: {
display: false
},
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0)',
borderColor: 'rgba(0, 0, 0, 0)',
displayColors: false,
titleAlign: 'center',
xAling: 'center'
}
},
hoverOffset: 15,
}
}); `
Image 1
Image 2
THANKS
The chart.js tooltip object accepts an additional property called position which, well, affects the position of the tooltip. By default it only accepts two strings for setting the mode being either "average" or "nearest". Luckily you're able to define your own mode by extending the Chart.Tooltip.positioners object.
As you want your tooltip to be somewhere in the middle, we can make something like this:
Chart.Tooltip.positioners.middle = function(elements, eventPosition) {
const chart = this._chart;
return {
x: chart.chartArea.width/2,
y: chart.chartArea.height/2
};
}
...so simply querying the chart's current dimensions and take the half of it. This mode can then be used by it's name "middle".
Here's a complete example:
var ctx = document.getElementById("myChart");
Chart.Tooltip.positioners.middle = function(elements, eventPosition) {
const chart = this._chart;
return {
x: chart.chartArea.width / 2,
y: chart.chartArea.height / 2
};
}
var data = {
labels: ['Residential', 'Non-Residential', 'Utility'],
datasets: [{
data: [19, 26, 55],
weight: 2,
spacing: 5,
borderWidth: 0,
backgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}]
};
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: {
responsive: false,
circumference: 180,
rotation: -180,
plugins: {
legend: {
display: false
},
tooltip: {
position: 'middle',
backgroundColor: '#ff0000',
titleColor: '#000000',
displayColors: false,
titleAlign: 'center',
xAlign: 'left'
}
},
hoverOffset: 15,
}
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="myChart"></canvas>

Is it possible to make points in a line chart of Chart JS 3.7.0 look like a donut?

the version of Chart JS is 3.7.0
I am looking for a way to make my chart's points look from this:
to something like this:
I found out that there is an option in this library where you can set the points to a certain shape. e.x: pointStyle: 'rectRot' will make the points appearance look like this:
Is there an option or a way to achieve what Im looking for? (Check the second picture).
Thanks in advance!
My chart's javascript:
const data = {
datasets: [
{
backgroundColor: 'black',
borderColor: '#2d84b4',
borderWidth: 2,
data: [
{ x: 'Dec 27', y: 0.204 },
{ x: '01:00', y: 0.234 },
{ x: '02:00', y: 0.274 },
{ x: '03:00', y: 0.234 },
{ x: '04:00', y: 0.304 },
{ x: 'Dec 28', y: 0.506 },
],
fill: false,
pointBorderColor: 'rgba(0, 0, 0, 0)',
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBackgroundColor: '#2d84b4',
pointHoverBorderColor: '#2d84b4',
},
],
};
const config = {
type: 'line',
data: data,
options: {
animation: {
duration: 0,
},
responsive: true,
maintainAspectRatio: false,
plugins: {
//Do not display legend.
legend: {
display: false,
},
},
scales: {
xAxes: {
stacked: true,
ticks: {
stepSize: 2,
},
grid: {
display: true,
drawBorder: false,
drawOnChartArea: false,
drawTicks: true,
tickLength: 4,
type: 'time',
},
},
yAxes: {
grid: {
drawBorder: false,
drawTicks: false,
},
},
},
elements: {
point: {
radius: 5,
},
},
},
};
// Initialize the Chart.
const myChart = new Chart(document.getElementById('myChart'), config);
window.addEventListener('beforeprint', () => {
myChart.resize(600, 600);
});
window.addEventListener('afterprint', () => {
myChart.resize();
});
//Disable all animations!
myChart.options.animation = false;
myChart.options.animations.colors = false;
myChart.options.animations.x = false;
myChart.options.transitions.active.animation.duration = 0;
The points seemed to work just fine with your transparent background, only on hover you setted a normal background again so the pointHoverBackgroundColor should also be transparent.
To make the point bigger on hover you can use the hoverRadius and to make the line have the same width you can use the pointHoverBorderWidth:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'black',
borderColor: '#2d84b4',
borderWidth: 2,
pointBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBackgroundColor: 'rgba(0, 0, 0, 0)',
pointHoverBorderColor: '#2d84b4',
hoverRadius: 10,
pointHoverBorderWidth: 2
}]
},
options: {}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
</body>

One common component for Chart.js to use with different y-axis With React.js

useEffect(() => {
let ctx = document.getElementById("LineChart");
const blue = [2000, 2100, 2400, 2450, 3000];
const yellow = [1800, 2150, 2550, 2800, 2000];
const pink = [1200, 1100, 1050, 1010, 1000];
const LineChart = new Chart(ctx, {
type: "line",
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May"],
datasets: [
{
data: blue,
label: "New MRR",
fill: false,
lineTension: 0.5,
backgroundColor: "#3ea5e0",
borderColor: "#3ea5e0",
pointBorderWidth: 1,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointRadius: 1,
pointHitRadius: 10,
},
{
data: yellow,
label: "Net New MRR",
fill: false,
lineTension: 0.5,
backgroundColor: "#ad9a52",
borderColor: "#ad9a52",
pointBorderWidth: 1,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointRadius: 1,
pointHitRadius: 10,
},
{
data: pink,
label: "Lost MRR",
fill: false,
lineTension: 0.5,
backgroundColor: "#5c3784",
borderColor: "#5c3784",
pointBorderWidth: 1,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointRadius: 1,
pointHitRadius: 10,
},
],
},
options: {
scales: {
yAxes: [
{
ticks: {
beginAtZero: false,
callback: function (value, index, values) {
return "$" + value;
},
},
},
],
},
},
});
let ctx2 = document.getElementById("BarChart");
const BarChart = new Chart(ctx2, {
type: "bar",
data: data,
});
I want to create a common chart component with same x-axis values but different y-axis values.I have switch case according to their type.So I can render charts with their types.Is there a short way to create a common chart or do I have to code all of them? Because right now I can only render one line chart.
Here is how you can create a common Chart component which will draw the chart given a custom data.
https://codesandbox.io/s/serverless-frog-6bu2f?file=/src/App.js

Remove data after adding it (chart.js)

I have an add data function in my bar-chart but I would like to be able to remove this data with onclick. How do I do this?
var canvas = document.getElementById("barChart");
var ctx = canvas.getContext('2d');
// We are only changing the chart type, so let's make that a global variable along with the chart object:
var chartType = 'bar';
var myBarChart;
// Global Options:
Chart.defaults.global.defaultFontColor = 'grey';
Chart.defaults.global.defaultFontSize = 16;
var data = {
labels: [ "2012", "2013", "2014", "2015", "2016", "2017"],
datasets: [{
label: "Miljoner ton",
fill: true,
lineTension: 0.1,
backgroundColor: "rgba(0,255,0,0.4)",
borderColor: "green", // The main line color
borderCapStyle: 'square',
pointBorderColor: "white",
pointBackgroundColor: "green",
pointBorderWidth: 1,
pointHoverRadius: 8,
pointHoverBackgroundColor: "yellow",
pointHoverBorderColor: "green",
pointHoverBorderWidth: 2,
pointRadius: 4,
pointHitRadius: 10,
data: [56.38, 59.3, 61.81, 58.83, 52.32, 66.86],
spanGaps: true,
}]
};
// Notice the scaleLabel at the same level as Ticks
var options = {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
title: {
fontSize: 18,
display: true,
text: 'Källa: Globallife.org',
position: 'bottom'
}
};
function addData() {
myBarChart.data.labels[7] ="Ekologisk palmolja";
myBarChart.data.datasets[0].data[7] = 14;
myBarChart.update();
}
// We add an init function down here after the chart options are declared.
init();
function init() {
// Chart declaration:
myBarChart = new Chart(ctx, {
type: chartType,
data: data,
options: options
});
}
Below is a working example that demonstrates modifying and updating the chart when clicking a button. Your addData function is a little odd in that it adds data at index 7, but the dataset only has keys 0-5, so this causes an extra blank data point to be inserted at index 6.
In case this isn't what you intended, I added some extra functions (pushData and popData) to show adding and removing from the end of a dataset as that's a quite common requirement (and therefore documented).
// same as original function; inserts or updates index 7.
function addData(e) {
myBarChart.data.labels[7] = "Ekologisk palmolja";
myBarChart.data.datasets[0].data[7] = 14;
myBarChart.update();
}
// requested function; removes index 7.
function removeData(e) {
myBarChart.data.labels.splice(7, 1);
myBarChart.data.datasets[0].data.splice(7, 1);
myBarChart.update();
}
// example of how to add data point to end of dataset.
function pushData(e) {
myBarChart.data.labels.push("Ekologisk palmolja");
myBarChart.data.datasets[0].data.push(14);
myBarChart.update();
}
// example of how to remove data point from end of dataset.
function popData(e) {
myBarChart.data.labels.pop();
myBarChart.data.datasets[0].data.pop();
myBarChart.update();
}
// set listeners on buttons
document.getElementById('add1').addEventListener('click', addData);
document.getElementById('remove1').addEventListener('click', removeData);
document.getElementById('add2').addEventListener('click', pushData);
document.getElementById('remove2').addEventListener('click', popData);
Chart.defaults.global.defaultFontColor = 'grey';
Chart.defaults.global.defaultFontSize = 16;
let myBarChart = new Chart(document.getElementById('chart'), {
type: 'bar',
data: {
labels: ["2012", "2013", "2014", "2015", "2016", "2017"],
datasets: [{
label: "Miljoner ton",
fill: true,
lineTension: 0.1,
backgroundColor: "rgba(0,255,0,0.4)",
borderColor: "green", // The main line color
borderCapStyle: 'square',
pointBorderColor: "white",
pointBackgroundColor: "green",
pointBorderWidth: 1,
pointHoverRadius: 8,
pointHoverBackgroundColor: "yellow",
pointHoverBorderColor: "green",
pointHoverBorderWidth: 2,
pointRadius: 4,
pointHitRadius: 10,
data: [56.38, 59.3, 61.81, 58.83, 52.32, 66.86],
spanGaps: true
}]
},
options: {
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
title: {
fontSize: 18,
display: true,
text: 'Källa: Globallife.org',
position: 'bottom'
}
}
});
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="chart"></canvas>
<button id="add1">Add index 7</button>
<button id="remove1">Remove index 7</button>
<button id="add2">Add to end</button>
<button id="remove2">Remove from end</button>

High resolution canvas of radar chart for pdf file

I have the given code below for displaying a radar chart using Chart.js. When I display it as PDF on my screen it appears blurry. I've been trying to scale using webkitBackingStorePixelRatio and devicePixelRatio on Chrome, but I'm a little bit stuck.
--HTML--
<div class="chart">
<canvas id="myChart"></canvas>
</div>
--Javascript--
<script>
var ctx1 = document.getElementById("myChart");
var myRadarChart1 = new Chart(ctx1, {
type: 'radar',
data: {
labels: {{ competenceCleTitle|json_encode|raw }},
datasets: [
{
backgroundColor: "#F79646",
borderColor: "#f59c1a",
pointBackgroundColor: "#f59c1a",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "#f59c1a",
pointRadius: 0,
data: {{ competenceCleNiveau|json_encode|raw }}
}
]
},
options: {
legend: {
display: false
},
responsive: true,
scale: {
reverse: false,
ticks: {
display: false,
maxTicksLimit: 8,
stepSize: 1,
beginAtZero: true,
max: 5
}
}
}
});
</script>

Categories

Resources