How to add datalabels to chartJS on Primefaces - primefaces

I'm creating charts with the new ChartJS lib on Primefaces, but I could not find a way to add the value as label on the bar chart or line chart.
Looking on the internet, I've found a JS plugin called chartjs-plugin-datalabels! that does what I need.
How could I use this plugin on my Java Primefaces application?

Try this...
Add the script to your XHTML page:
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0"></script>
In your Java model for your chart set the Extender feature on.
chartModel.setExtender("chartExtender");
In your XHTML add this JavaScript code function to match when you set in #2 Java bean.
function chartExtender() {
var options = {
plugins: [ChartDataLabels],
options: {
plugins: {
// Change options for ALL labels of THIS CHART
datalabels: {
color: '#36A2EB'
}
}
},
data: {
datasets: [{
// Change options only for labels of THIS DATASET
datalabels: {
color: '#FFCE56'
}
}]
}
};
//merge all options into the main chart options
$.extend(true, this.cfg.config, options);
};
This was all based on their configuration guide https://chartjs-plugin-datalabels.netlify.com/guide/getting-started.html#configuration But this should at least get the plugin going.

Related

How to display timestamped data with PrimeFaces and ChartJs?

Since the public 7.0 release of PrimeFaces includes ChartJs, I thought I'd give it a try.
It works fine, however so far I have not been able to properly display data with values changing over time in a line chart.
chart.js has cartesian time axes for this purpose, however in PrimeFaces , only CartesianLinearAxes is available.
Feeding date objects (instead of String labels) to ChartData simply results in no x-axis being drawn.
Am I missing something or did they just skip this functionality when including chart.js in Primefaces?
OK great questions.
First, PF knows they did not implement time yet but there is an open ticket: https://github.com/primefaces/primefaces/issues/4564
Second, have no fear you can use the Extender feature to make it work. Here is an example we used.
In your Java model for your chart set the Extender feature on.
chartModel.setExtender("chartExtender");
In your XHTML add this JavaScript code function to match when you set in #1 Java bean.
function chartExtender() {
//copy the config options into a variable
var options = $.extend(true, {}, this.cfg.config);
options = {
//remove the legend
legend: {
display: false
},
scales: {
xAxes: [{
display: true,
type: "time",
time: {
parser: 'h:mm:ss a',
tooltipFormat: 'h:mm:ss a',
unit: 'hour',
displayFormats: {
'hour': 'h:mm:ss a'
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Your Y Axis',
fontSize: 13,
}
}]
}
};
//merge all options into the main chart options
$.extend(true, this.cfg.config, options);
};
You can see the different time formats available from ChartsJS using MomentJS.
Just a complement to do the extender works, use this.cfg.config.options = {...
for exemple:
function extName() {
this.cfg.config.options = {
legend: {
display: false
}
};
};

Error on Chartjs and Angular 5 - "can't acquire context from the given item"

I need to display a graph in my Angular project. A simple doughnut chart with 3 datasets. When I try to run the project, the console throws the following error:
"Failed to create chart: can't acquire context from the given item"
I've read the documentation, used the templates and even checked on few questions of StackOverflow :
chart.js Failed to create chart: can't acquire context from the given item
Using Chart.js on Angular 4
Angular/Chart.js error: Failed to create chart: can't acquire context from the given item
None of them worked and I think that it owes to the typescript doesn't "find" the ID of the < canvas >, but I sincerely don't know what am I doing wrong
Here's the code:
HTML
<canvas #grafico id="grafico">{{ grafico }}</canvas>
TypeScript
import Chart = require('chart.js');
grafico: any;
this.grafico = new Chart('grafico',{
type:"doughnut",
data:{
labels: ['Expirados', 'Sem exames', 'Proximo de expirar'],
datasets:[
{ // Exames expirados
data:res[0].num_funcion_expir, // Data from API
backgroundColor:'#EA3100'
},
{ // Exames expirados
data:res[0].num_funcion_sem_exam_ini, // Data from API
backgroundColor:'#ff6384'
},
{ // Exames expirados
data:res[0].num_funcion_expir_prox_exam, // Data from API
backgroundColor:'#EAA900'
},
]
},
options:{
legend:{
display:true
}
}
});
Any help is appreciated
You only need to add this to the html template
<div [hidden]="!grafico"><canvas id="grafico">{{ grafico }}</canvas></div>
Here is an example of Angular using Chart.JS
Refer the canvas with template reference in the component where you are creating the chart.
Component (Use static as true if you are generating the chart in ngOnInit):
#ViewChild('grafico',{static:true}) grafico: Chart = [];
Template (Because if you are using *ngIf , it removes the element from the dom if the condition evaluates to false) :
<div [hidden]="!grafico"><canvas id="grafico">{{ grafico }}</canvas></div>
Further more, you can debug the applicatio and verify if the chart is getting created properly or not.

primefaces p:textEditor tab/keyboard navigation doesn't focus the next UI component

We are using p:textEditor (based on quill editor) in our application and we have more UI components below p:textEditor. The problem is for accessibility, the user need to tab through the components in the page using keyboard; but when it comes to p:textEditor a tab acts as adding a tab(4 spaces).
The primefaces showcase here also has the same problem, how can we navigate to the submit button from p:textEditor using keyboard?
Thanks Kukeltje, I disabled the tab key in quill editor.
For anyone who wants to do the same, you have to edit the texteditor.js file under META-INF/resources/primefaces/texteditor/ (when you reverse engineer the primefaces-version.jar (version=6.1 in my case)) and add the below code in render: function()
_render: function() {
...
this.cfg.modules = {
toolbar: PrimeFaces.escapeClientId(this.id + '_toolbar'),
keyboard: {
bindings: {
tab: {
key: 9,
handler: function() {
// do nothing
return true;
}
},
'remove tab': {
key: 9,
shiftKey: true,
collapsed: true,
prefix: /\t$/,
handler: function() {
// do nothing
return true;
}
}
}
}
};
...
}
For anyone who wants additional key customization can use the Quill Interactive Playground to validate your changes.

How to increase width of lines in Primefaces line chart

How to increase width of lines in Primefaces line chart? I want to increase width of line in line charts , but there is no option in tag
Charts in Primefaces are based on jqPlot. For options that are not accessible by the Chart API you have to use the "Extender".
E.g. if you want to set the color and line width for all series you have to create a Javascript function with the extended configuration for your chart:
function myLineChartExtender() {
// this = chart widget instance
// this.cfg = jqPlot options
this.cfg.seriesDefaults = {
color: "#000000",
lineWidth: 10.0
}
}
Then you have to specify the extender:
Primefaces 5.0 and later:
Specify the name of the Javascript function when you initialize the model:
LineChartModel model = new LineChartModel();
...
model.setExtender("myLineChartExtender");
Primefaces before 5.0:
Specify the name of the Javascript function as XHTML parameter:
<p:chart type="line" model="#{bean.model}" extender="myLineChartExtender" />
See jqPlot Options Tutorial for further explanation on how to use the options. A list of all options can be found here.

primefaces barchart : displaying data point on bar

how can I display data point on bar in barchart?
I don't want to use datatip or tooltip which will highlight data points only when they are moused over.
I want to display the data point always on the bar.
is there any right way to get it?
thanks.
I want exactly like this
following is my code
<p:barChart id="barChartId" value="#{myBean.myModel}"
orientation="horizontal"
stacked="true" extender="ext" animate="true" shadow="false" />
<h:outputScript>
function ext() {
this.cfg.highlighter = {
useAxesFormatters: false,
tooltipAxes: 'x'
};
this.cfg.legend = {
show: true,
location: 'ne',
placement: 'outside'
};
this.cfg.seriesDefaults = {
pointLabels : { show: true },
};
}
</h:outputScript>
here, highlighter and legend are working fine but point labels are not displaying on bar
Not sure if it will work...
Use the extender of the <p:barChart , like this:
<p:barChart value="#{myBean.myModel}" widgetVar="myBarChart" extender="my_ext"/>
<script type="text/javascript">
function my_ext() {
this.cfg.seriesDefaults = {
renderer:$.jqplot.BarRenderer,
pointLabels: {show: true}
};
this.cfg.stackSeries: true;
}
</script>
or this
<script type="text/javascript">
function my_ext() {
this.cfg.seriesDefaults = {
pointLabels: {show: true}
};
this.cfg.stackSeries: true;
}
</script>
Also take a look at the jqplot examples : Bar charts
Just in case someone doesn't crawl through the comments of the marked answer, as I didn't do in the first place.
The problem basically is not the configuration of the pointLabelselement, but rather that primefaces (as of 4.0) in its original state does not ship with the needed plugin of jqPlot included.
Therefore actually the solution is to make the needed plugin jqplot.pointLabels.min.js available. From a ticket in the bug tracker (http://code.google.com/p/primefaces/issues/detail?id=5378) I extracted, that primefaces uses jqPlot version 1.0.8.
download jqplot 1.0.8 from https://bitbucket.org/cleonello/jqplot/downloads/
add the plugin to your project (e.g. src/main/webapp/resources/jqplot-plugins)
add the plugin as script to your page (<h:outputScript library="jqplot-plugins" name="jqplot.pointLabels.min.js" />)