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
}
};
};
Related
I'm using chartkick with chart.js in Ruby on Rails. I saw the documentation and some issues, but I can't find anything to solve my problem.
I'm setting my chart in html.erb file, like this:
<%=
line_chart $hash_chart,
options: {
max: $value.max+5,
min: $value.min-5,
allowDecimals: false,
colors: color_line,
xtitle: "Title of x axis",
ytitle: "Title of y axis",
discrete: true,
points: false,
width: "500px",
height: "500px",
scales: {
yAxes: [{
distribution: 'linear'
}],
xAxes: [{
distribution: 'linear',
type: 'category', (part of a configuration attempt)
categories: $time, (part of a configuration attempt)
ticks: {
stepSize: 10
}
}]
}
}
%>
The settings until height param works, but scales settings doesn't. The answer of this issue is exactly what I make (according documentation of Chart.js), but didn't work: Force display of ticks on xAxes using chartkick gem and chart.js. I tried to put this setting inside library brace too.
Basically, I want to set the ticks in x Axis and show just some labels of my array of datas. Is it possible to format this (using this type of file)?
You are using the wrong old v2 syntax of chart.js, the scales in v3 for example have to be configured like this
scales: {
x:{
ticks: {}
},
y: {
// Y config
}
}
EDIT:
Since you are on V2 your syntax of declaring axis is correct, make sure you dont run the latest version of chartKick since it uses v3.
distribution does not do anything unless your scale type is time. The stepSize only works for linear and time scales so you will need to change type: 'category' to type: 'linear' or if you are using time data to type: 'time' if you are using time data the stepsize has to be configured in the time sub part so you will need to change ticks to time
I'm working on a choropleth map that shows the share of the population that has confirmed positive case of Covid-19 in each political jurisdiction. Similar to this example in the per capita Mapbox graphic on this page of the The New York Times.
I figured out just about every detail expect how to customize the legend. Currently, the labels display the shareOfPop as a number. Though, I want to prefix each label with "1 in ${shareOfPop}", and to add a suffix to the final label "1 in ${shareOfPop} or more".
enter image description here.
I've created this map in an Observable Notebook.
Things I've tried so far...
Making us of the custom legend encodings
To specify label text:
vl.color()
.fieldQ('shareOfPop')
.scale(
{
scheme: "yelloworangered",
domain: [250, 10],
clamp: true,
}
)
.legend({
title: "Share of Pop.",
encode: {
labels: {text: "1 in ${datum.value}"}
}
})
Register a custom formatter
Which I doubt I've accomplished correctly.
Here's what my configuration looks like (which is based on the config in the Introduction to Vega-Lite notebook).
vl = {
const [vega, vegalite, api, tooltip] = await Promise.all([
'vega#5.13.0',
'vega-lite#4.14.1',
'vega-lite-api#0.11.0',
'vega-tooltip#0.22.1'
].map(module => require(module)));
const options = {
config: {
// allow custom format types
customFormatTypes: true,
config: {
view: {continuousWidth: 400, continuousHeight: 300},
mark: {tooltip: null}
}
},
init: view => {
// initialize tooltip handler
view.tooltip(new tooltip.Handler().call);
// enable horizontal scrolling for large plots
if (view.container()) view.container().style['overflow-x'] = 'auto';
// register a custom expression function...am I doing this right???
vega.expressionFunction('1inX', function(datum) {
return `1 in ${datum}`
})
},
view: {
// view constructor options
loader: vega.loader({baseURL: 'https://cdn.jsdelivr.net/npm/vega-datasets#1/'}),
renderer: 'canvas'
}
};
return api.register(vega, vegalite, options);
}
Then I specify this custom formatType when defining the mark:
vl.color()
.fieldQ('shareOfPop')
.scale(
{
scheme: "yelloworangered",
domain: [250, 10],
clamp: true,
}
)
.legend({
title: "Share of Pop.",
formatType: "1inX",
})
)
Neither of these approaches produced any noticeable change.
Gonna answer my own question here.
Turns out Legend has a general labelExpr property that allows you to specify a Vega expression for customizing the label.
In my case, I wanted to always prepend the string "1 in ", and also append "+" when over may domain limit. Here's how I did it using the join() and if() functions.
...
vl.color()
.legend(
{
labelExpr: "join(['1 in ', datum.value, if(datum.value >= 250, '+', '')], '')"
}
)
This property isn't documented for Legend, though it is for for Axis).
I would like to remove Facilities in the layerlist, but still have it show up in the map.
var manned_facilities_back = new MapImageLayer({
url: "http://dotdevgisiis02:6080/arcgis/rest/services/DOT_MAP_PORTAL/Facilities/MapServer",
sublayers: [
{
id: 1,
popupTemplate: templateFT,
},
{
id: 0,
popupTemplate: templateMF,
},
]
I've attempted to add
listmode: hide
or
display: none
under where i have url, but it didn't work. I figure this should be really simple.
Setting the property Layer.listMode to "hide" should work as expected. In your example, make sure you use the correct casing:
var layer = new MapImageLayer({
url: "http://dotdevgisiis02:6080/arcgis/rest/services/DOT_MAP_PORTAL/Facilities/MapServer",
listMode: "hide"
});
Here's a live demo hiding one of the layers from the loaded WebScene:
https://codepen.io/arnofiva/pen/eb198c9b4050b892759ef433e8664fac
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.
We've just updated to the latest Highcharts version and now a few of our chart types have a new line connecting the tooltip to the point.
It's mainly obvious on charts with fixed tooltips.
Does anyone know how to remove this line without removing the border of the tooltip itself?
I have come up with a work around that involves setting the borderwidth of the tooltip to 0 and adding a rounded, bordered, coloured div to the tooltip using useHTML:true and disabling the shadow.
Though I dont want to do this for every chart as it seems a bit nasty.
This also affects bar and tree maps that I can see and I've trawled the documentation to no avail.
http://jsfiddle.net/mattscotty/bqw4bc4x/1/
Highcharts.chart('container', {
title: {
text: 'Fixed tooltip'
},
tooltip: {
positioner: function () {
return { x: 80, y: 50 };
},
backgroundColor: 'rgba(255,255,255,0.8)',
//Uncomment below to remove line, but this also removes tooltip border
//borderWidth:0,
//shadow:false
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar']
},
series: [{
data: [29.9, 71.5, 106.4]
}, {
data: [194.1, 95.6, 54.4]
}]
});
Thanks in advance.
By default tooltip's shape is set to a callout which has a chevron/line pointing to the point. You can change the tooltip's shape to, e.g. rectangle - which does not have any connector.
tooltip: {
positioner: function () {
return { x: 80, y: 50 };
},
backgroundColor: 'rgba(255,255,255,0.8)',
shape: 'rect'
example: http://jsfiddle.net/bqw4bc4x/2/
The accepted answer only partially worked in Highstock. The connectors for the volume and indicator tooltips were suppressed, but I still had a connector from the DateTime box to the crosshair.
As an alternative to the shape: 'rect' hack, you can try:
tooltip: {
positioner: function () {
return { x: 80, y: 50 };
},
split: false,
shared: true,
backgroundColor: 'rgba(255,255,255,0.8)'
These split: and shared: settings consolidate all the tooltip boxes into a single box. Provided that this meets your needs it seems to solve the connector issue.
Very odd design decision by Highcharts. The connectors are highly intrusive visually and I can't imagine that many designers will want to use them, but you can only disable them with a hack. What were they thinking?