I am trying to add data to the Label. Currently, it's showing only the Label, How can I add data to the Label, for example, Red(12)? If I hover over the chart, it shows the number, Red # of votes: 12,
Now in the Header, it's showing Red, I want to show Red(12) => Label with data and the rest of the Label with Data.
Here is the link to the example:https://codesandbox.io/s/github/reactchartjs/react-chartjs-2/tree/master/sandboxes/doughnut/default?from-embed=&file=/App.tsx:127-142
create custom labels using separate variable for label and data,
import React from 'react';
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js';
import { Doughnut } from 'react-chartjs-2';
ChartJS.register(ArcElement, Tooltip, Legend);
var doughnutData = [12, 19, 3, 5, 2, 3]; //this
var doughnutlabel = ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'] //and this
doughnutlabel = doughnutlabel.map((i, index) => i + ` (${doughnutData[index]})`); //create custom labels
export const data = {
labels: doughnutlabel, //use here
datasets: [
{
label: '# of Votes',
data: doughnutData, //and here
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)',
],
borderWidth: 1,
},
],
};
export function App() {
return <Doughnut data={data} />;
}
That one is called tooltip, to customize it please refer to:
https://www.chartjs.org/docs/latest/configuration/tooltip.html
https://www.chartjs.org/docs/latest/configuration/tooltip.html#tooltip-callbacks
You can do something like:
export function App() {
return (
<Doughnut
data={data}
options={{
plugins: {
tooltip: {
callbacks: {
title: (tooltipItems) => {
return tooltipItems.map(
(item) => `${item.label} (${item.formattedValue})`
);
}
}
}
}
}}
/>
);
}
Result:
And if you want to customize the labels on your chart, you can have aa look at chartjs-plugin-datalabel
And then have something like
export function App() {
return (
<Doughnut
data={data}
options={{
plugins: {
tooltip: {
callbacks: {
title: (tooltipItems) => {
return tooltipItems.map(
(item) => `${item.label} (${item.formattedValue})`
);
}
}
},
datalabels: {
labels: {
title: {
font: {
weight: "bold"
},
formatter: function (value, context) {
console.log(value);
console.log(context);
console.log("-");
return `${
context.chart.data.labels[context.dataIndex]
} (${value})`;
}
},
value: null
}
}
}
}}
/>
);
}
Result:
A working example: https://codesandbox.io/s/dreamy-raman-1wrrgc
Edit:
For performance reasons, you may want to consider Shaikh's solution, I think it would be better to prepare your labels before you render the chart instead of calling chart.js's callback for each element.
(Of course, you may have a different use case, or you don't feel the impact of any of these approaches)
Related
I'm trying to do a pie chart with vue chart, I am trying to convert an object into an array to update de label in vuechartjs and make it dynamic according to the api, but it seems almost impossible. My goal is to fetch the concert name in the label and then fetch (data) how many booking we have for each concert. Would someone would be kind enough to help ? I have tried everything. thanks Here is my code :
<script>
import { Pie } from 'vue-chartjs'
export default {
extends: Pie,
data () {
return {
bandNames:[],
booking:[],
bandName:[],
data:[],
chartData: {
labels:[],
datasets: [{
borderWidth: 1,
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)'
],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
],
data: [1000]
}]
},
options: {
legend: {
display: true
},
responsive: true,
maintainAspectRatio: false
}
}
},
created(){
var vm = this;
this.axios
.get('http://localhost:3000/booking', {})
.then(function (response) {
console.log(response.data);
vm.booking = response.data;
});
this.axios
.get('http://localhost:3000/concerts', {})
.then(function (response) {
console.log(response.data);
vm.bandNames = response.data;
vm.bandNames.forEach((item)=>{
vm.bandName.push(item.band)
})
vm.chartData.labels = vm.bandName[0]
var data = []
var i = vm.bandName.length
for(var a = 0 ; a < i ; a++){
data.push([vm.bandName[a]])
vm.chartData.labels = data
}
});
},
mounted () {
this.renderChart(this.chartData, this.options)
}
}
You can directly push the labels to the chartOptions in the loop , so change this :
vm.bandNames.forEach((item)=>{
vm.bandName.push(item.band)
})
vm.chartData.labels = vm.bandName[0]
by :
vm.bandNames.forEach((item)=>{
vm.chartData.labels.push(item.band)
})
I am trying to implement a simple chart in my angular app with chart.js. But unfortunately I am getting following error:
Failed to create chart: can't acquire context from the given item
I already found several similar questions here but somehow none of the answers really helped. Does anyone has an idea how to fix this?
task-activity.component.html
<nb-tab tabIcon="bar-chart-2-outline" tabTitle="Insights">
<div id="divChart">
<canvas id="myChart" width="400px" height="400px"></canvas>
</div>
</nb-tab>
task-activity.component.ts
import { Component, Input, ViewChild, OnInit, AfterViewInit, TemplateRef } from '#angular/core';
import { Chart } from 'chart.js';
#Component({
selector: 'ngx-task-activity',
templateUrl: './task-activity.component.html',
styleUrls: ['./task-activity.component.scss'],
})
export class TaskActivityComponent implements OnInit, AfterViewInit {
chart= [];
constructor(private dialogService: NbDialogService,
public organizationService: OrganizationService) {
this.userId = organizationService.getUserId();
console.info('this.userId:', this.userId);
setTimeout(() => {
this.user = organizationService.getUser();
}, 2000);
}
ngOnInit() {
this.initData();
this.chart.push(new Chart('myChart', {
// The type of chart we want to create
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
}));
}
This an answer on how to dynamically update an angular-chatr.js chart using the ng2-charts package. Make sure you include node_modules/dist/Chart.min.js to your web manifest, or as a link in your index.html
Please visit this
https://stackoverflow.com/a/64793266/12683543
I am New to Vue and chart js, what I am trying to do is to target the chart, Add, delete and update the chart's labels and data values.
I have a link to chartJs documentation, but where I am stuck at is in what scope in the export default {} block could I target the data.
i have my chart set in a Vue component, I am also using a CLI Webpack setup.
// HERE IS MY HTML
<v-flex xs12 md12 width="400px" height="400px" mt-5 >
<canvas id="myChart" ></canvas>
</v-flex>
export default {
methods: {
CreateChart(chartId, chartData) {
const ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['JavaScript', 'NodeJs', 'VueJs', 'DataBase'],
datasets: [{
label: '# of votes',
data: [12, 15, 23, 15],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
},
mounted() {
let data = data;
this.CreateChart('chart', data);
},
}
Now, as per ChartJs official documentation, I could have a function, I think after the createChart() method within the `methods{}' scope, the function should allow me target the bars or labels for instance in the following way
function addData(myChart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset) => {
dataset.data.push(data);
});
chart.update();
}
function removeData(chart) {
chart.data.labels.pop();
chart.data.datasets.forEach((dataset) => {
dataset.data.pop();
});
chart.update();
}
Thanks in advance
I am getting this error while setting up react-chartjs, i am using example given here .
This is the error i am getting:
Uncaught (in promise) TypeError: Cannot read property 'xLabels' of undefined
at updatePoints (core.js:127)
at Object.classData.componentWillReceiveProps (core.js:48)
...... so on
In this post they said they have fixed it already, but they did't i think.
Here is my code:
var Chart = require('chart.js');
var LineChart = require("react-chartjs").Line;
export default class Dashboard extends Component {
constructor(props){
super(props);
var result = '';
this.state = {
chartData: '',
chartOptions: ''
};
}
componentDidMount(){
var chartData = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
}
var chartOptions = {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
this.setState({
chartData: chartData,
chartOptions: chartOptions
})
}
render () {
return (
<div className="container">
<div className="chart-wrapper">
<LineChart data={this.state.chartData} width="600" height="250"/>
</div>
</div>
)
}
}
What could be the issue? i am new to react and stuck with charts. Any help would be appreciated.
"redraw" should help:
<LineChart data={this.state.chartData} width="600" height="250" redraw/>
in this code, I was able to get the data from database in the JSON format. now iam struggling to draw a chart in JS with columns as values and rows as time stamp. i have a controller(chartController) that goes into the database and extract the desired data and change it into JSON format, that is values and timestamp. then i created a route for this controller, Route::get('json/{notification_id}','ChartController#speedHistory')->name('speedhistory')
i hava a js class as follows,
document.addEventListener('DOMContentLoaded', function() {
$.getJSON("json", function getdata(data) {
console.log(data);
var pageSpeedValues = o_response;
createChartHistory(pageSpeedLabels);
});
function fetchValues(Labels, Values) {
var pageSpeedLabels = Values;
var pageSpeedValues = Labels;
createChartHistory(pageSpeedLabels);
}
// This function allows us to create a chart for the history page
function createChartHistory(pageSpeedLabels, pageSpeedValues) {
var ctx = document.getElementById("pageSpeedHistoryChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: pageSpeedLabels,
datasets: [{
label: 'PageSpeed History',
data: pageSpeedValues,
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(255, 206, 86, 0.5)',
'rgba(75, 192, 192, 0.5)',
'rgba(153, 102, 255, 0.5)',
'rgba(255, 159, 64, 0.5)',
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(32, 206, 86, 0.5)',
'rgba(77, 192, 192, 0.5)',
'rgba(153, 102, 255, 0.5)',
'rgba(255, 159, 64, 0.5)'
]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
max: 100,
min: 0
}
}]
}
}
});
}
if(document.querySelector('#pageSpeedHistoryChart')) {
getdata();
}
});
I am not getting the data from the controller into the app.js class, any one how get the idea? iam learning js but seems a bit difficult at this point.
here is my chart controller
<?php
namespace App\Http\Controllers;
use App\Notification;
use App\Status;
use Illuminate\Http\Request;
class ChartController extends Controller
{
public function speedHistory($notification_id){
$o_notification = Notification::find(intval($notification_id));
$o_status = Status::where('name','speed')->first();
$o_response = $o_notification->statuses()->where('status_id', $o_status->id)
->select('values AS value', 'created_at AS timestamp')->orderBy('created_at','DESC')->get()
->transform(function ($item, $key) {
return collect([
'values' => $item->pivot->values,
'created_at' => $item->pivot->created_at->toDateTimeString()
]);
});
return response()->json($o_response);
}
}