How to add the label of a Primefaces chart? - jsf

I have a JSF line chart that uses PrimeFaces. I want to add labels to both x-axis & y-axis eg Year & Populations. I have used showLabel:true but its not working.The is code,
<p:lineChart id="chart" value="#{chartBean.linearModel}" xaxisAngle="-90">
<f:convertDateTime pattern="d-M-yyyy"/>
</p:lineChart>
function phaseChartExt() {
this.cfg.axes = {
xaxis: {
renderer: $.jqplot.DateAxisRenderer,
rendererOptions: { tickRenderer: $.jqplot.CanvasAxisTickRenderer },
tickOptions: {
showLabel:true,
showGridline: true,
formatString: '%H:%M',
angle: -90
}
}
yaxis: {
renderer: $.jqplot.DateAxisRenderer,
rendererOptions: { tickRenderer: $.jqplot.CanvasAxisTickRenderer },
tickOptions: {
showLabel:true,
showGridline: true,
formatString: '%H:%M',
angle: -90
}
}
}
}

Try to use
xaxisLabel="Year" yaxisLabel="Populations"
<p:lineChart id="chart" value="#{chartBean.linearModel}" xaxisAngle="-90" xaxisLabel="Year" yaxisLabel="Populations">
<f:convertDateTime pattern="d-M-yyyy"/>
</p:lineChart>

Related

UIView Top Point is Lower Then Expected

I have a format problem. How I want is the 2nd picture but for some reason, my view starts a little bit lower. You can see the gap between the pictures. I want to solve this problem without offset. Might be because of .navigationBarHidden(true) but I do not want navigation bar.
I added NavigationView to my code because I have a button down-right to add a new task.
Plus for some reason, this button is not clickable. Would be good if you give a hand to that problem.
import SwiftUI
struct TaskListView: View {
#State private(set) var data = ""
#State var isSettings: Bool = false
#State var isSaved: Bool = false
var body: some View {
NavigationView {
ZStack {
Color(#colorLiteral(red: 0.9333333333, green: 0.9450980392, blue: 0.9882352941, alpha: 1)).edgesIgnoringSafeArea(.all)
VStack {
TopBar()
HStack {
CustomTextField(data: $data, tFtext: "Find task", tFImage: "magnifyingglass")
Button(action: {
self.isSettings.toggle()
}, label: {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(width: 50, height: 50, alignment: .center)
.foregroundColor(Color(#colorLiteral(red: 0.4274509804, green: 0.2196078431, blue: 1, alpha: 1)))
Image("buttonImage")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
}
.padding(.horizontal, 15)
})
}
CustomSegmentedView()
ZStack {
TaskFrameView()
Button( action: {
self.isSaved.toggle()
}, label: {
ZStack {
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color(#colorLiteral(red: 1, green: 0.7137254902, blue: 0.2196078431, alpha: 1)))
Text("+")
.foregroundColor(.white)
.font(.title)
.fontWeight(.bold)
}
.frame(width: 40, height: 40)
.offset(x: 150, y: 220)
})
NavigationLink(
destination: NewTaskView(),
isActive: $isSaved,
label: {
Text("")
})
}
}
}
Spacer()
}
.navigationBarHidden(true)
}
}
struct TopBar: View {
var body: some View {
HStack {
Image("avatar")
.resizable()
.frame(width: 100, height: 100)
VStack(alignment: .leading){
DateView()
.font(Font.custom("SFCompactDisplay", size: 20))
.foregroundColor(.gray)
.padding(.vertical, 5)
Text("Hi, Random")
.font(Font.custom("SFCompactDisplay", size: 20))
}
Image(systemName: "ellipsis")
}
}
}
It is navigation view bar. The navigationBarHidden modifier should be inside NavigationView, like
}
.navigationBarHidden(true) // << here !!
Spacer()
} // end of NavigationView

ZingChart Y Axis Label Formatting

Is it possible in ZingChart to add a secondary y scale that uses the same values as the primary y scale, but just uses a simple conversion (e.g., anomaly degrees Celsius*1.8 = anomaly degrees Fahrenheit).
something like:
var chartConfig = {
scaleY2: { format: %v*1.8 }
}
Or, perhaps a function, like:
var chartConfig = {
scaleY2: { format: 'formatAxis()' }
}
...
formatAxis = function(p){ return { format:p.value*1.8 } }
I'm plotting temperature anomalies in degrees C on the primary y-axis. I'd like the degrees F to show up on the secondary y-axis.
You do indeed use a function. I just had a syntax error.
var chartConfig = {
scaleY2: { format: 'formatAxis()' }
}
...
window.formatAxis = function(v){
return (v*1.8).toFixed(2)+'\u00B0F';
}
The above answer from #magnum-π is correct. Creating a formatting function is the easiest and most effective solution.
// how to call function from ZingChart
let chartConfig = {
scaleY2: { format: 'formatAxis()' }
}
// defining function for ZingChart to find at the window scope
window.formatAxis = function(v){
return (v*1.8).toFixed(2)+'\u00B0F';
}
I have also configured a working demo of this to assist the above answer:
// window.onload event for Javascript to run after HTML
// because this Javascript is injected into the document head
window.addEventListener('load', () => {
// Javascript code to execute after DOM content
// full ZingChart schema can be found here:
// https://www.zingchart.com/docs/api/json-configuration/
let chartConfig = {
type: 'bar',
globals: {
fontSize: '14px',
},
title: {
text: 'Multiple Scales °C vs °F',
fontSize: '24px',
adjustLayout: true,
},
legend: {
draggable: true,
},
// plot represents general series, or plots, styling
plot: {
// hoverstate
tooltip: {
// % symbol represents a token to insert a value. Full list here:
// https://www.zingchart.com/docs/tutorials/chart-elements/zingchart-tokens/
text: '%kl was %v° %plot-text',
borderRadius: '3px',
// htmlMode renders text attribute as html so
// ° is rendered
htmlMode: true
},
valueBox: {
color: '#fff',
placement: 'top-in'
},
// animation docs here:
// https://www.zingchart.com/docs/tutorials/design-and-styling/chart-animation/#animation__effect
animation: {
effect: 'ANIMATION_EXPAND_BOTTOM',
method: 'ANIMATION_STRONG_EASE_OUT',
sequence: 'ANIMATION_BY_NODE',
speed: 275
}
},
plotarea: { margin: 'dynamic',},
scaleX: {
// set scale label
label: {
text: 'Days'
},
// convert text on scale indices
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
scaleY: {
// scale label with unicode character
label: {
text: 'Temperature (°C)'
}
},
scaleY2: {
label: {
text: 'Temperature (°F)'
},
guide: { visible: false }
},
// plot values
series: [
{
text: 'Celcius',
values: [23, 20, 27, 29, 25, 17, 15],
backgroundColor: '#448aff #64b5f6' ,
scales: 'scale-x, scale-y'
},
{
text: 'Farenheit',
values: [35, 42, 33, 49, 35, 47, 35].map(v => Number((v*1.8).toFixed(2))),
backgroundColor: '#ff5252 #e57373',
scales: 'scale-x, scale-y-2'
}
]
};
// render chart
zingchart.render({
id: 'myChart',
data: chartConfig,
height: '100%',
width: '100%',
});
});
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.chart--container {
min-height: 150px;
width: 100%;
height: 100%;
}
.zc-ref {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ZingSoft Demo</title>
<script src="https://cdn.zingchart.com/zingchart.min.js"></script>
</head>
<body>
<!-- CHART CONTAINER -->
<div id="myChart" class="chart--container">
<a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
</div>
</body>
</html>

How to implement a gauge solid chart in JSF

I'm new in JSF and I want to add a highchart solid gauge in my jsf page, but I implment the demo code and when I run it, it throws me this...
Error Parsing /index.xhtml: Error Traced[line: 185] El nombre de la entidad debe aparecer inmediatamente después de '&' en la referencia de entidades.
javax.faces.view.facelets.FaceletException: Error Parsing /index.xhtml: Error Traced[line: 185] El nombre de la entidad debe aparecer inmediatamente después de '&' en la referencia de entidades.
this is the code of the index
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<div style="width: 600px; height: 400px; margin: 0 auto">
<div id="container-speed" style="width: 300px; height: 200px; float: left"></div>
<div id="container-rpm" style="width: 300px; height: 200px; float: left"></div>
</div>
<script type="text/javascript">
$(function () {
var gaugeOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
// The speed gauge
var chartSpeed = Highcharts.chart('container-speed', Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 200,
title: {
text: 'Speed'
}
},
credits: {
enabled: false
},
series: [{
name: 'Speed',
data: [80],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:25px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y}</span><br/>' +
'<span style="font-size:12px;color:silver">km/h</span></div>'
},
tooltip: {
valueSuffix: ' km/h'
}
}]
}));
// The RPM gauge
var chartRpm = Highcharts.chart('container-rpm', Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 5,
title: {
text: 'RPM'
}
},
series: [{
name: 'RPM',
data: [1],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:25px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y:.1f}</span><br/>' +
'<span style="font-size:12px;color:silver">* 1000 / min</span></div>'
},
tooltip: {
valueSuffix: ' revolutions/min'
}
}]
}));
// Bring life to the dials
setInterval(function () {
// Speed
var point,
newVal,
inc;
if (chartSpeed) {
point = chartSpeed.series[0].points[0];
inc = Math.round((Math.random() - 0.5) * 100);
newVal = point.y + inc;
if (newVal < 0 || newVal > 200) {
newVal = point.y - inc;
}
point.update(newVal);
}
// RPM
if (chartRpm) {
point = chartRpm.series[0].points[0];
inc = Math.random() - 0.5;
newVal = point.y + inc;
if (newVal < 0 || newVal > 5) {
newVal = point.y - inc;
}
point.update(newVal);
}
}, 2000);
});
</script>
</h:body>
</html>
I don't know what I'm doing wrong, hope somebody can help me
JSF using Facelets is based on XML so the ampersands (&) are gonna be taken as an entity instead of the and conditional operator in java and most programming languages. so If you want to use it in your facelets you must change all the & with & which is the ampersand entity.
This problem is caused by not using CData. You should use CDATA for this
//<![CDATA[
//javascript code
//]]>
what does mean CDATA What does <![CDATA[]]> in XML mean?

p:chart zoom with date/time axis shows nothing

I have problem to set the zoom on a chart with "date time" axis. I made a simulation comparing the chart of Primefaces with native jqplot. With jqplot native works fine, but with primefaces not.
It seems to me an bug in the calculation of the viewport.
My JSF page:
<p:chart type="line" model="#{chartController.model}" id="chart" style="height: 400px" />
My managed bean:
#Named(value = "chartController")
#ViewScoped
public class ChartController implements Serializable {
private LineChartModel model;
public ChartController() {
}
#PostConstruct
public void init() {
long[][] lines = {{1334856823000l, 2}, {1334856853000l, 1}, {1334856883000l, 0}, {1334856913000l, 4}, {1334856914000l, 13},
{1334856943000l, 16}, {1334856973000l, 23}, {1334857003000l, 24}, {1334857033000l, 36}, {1334857063000l, 14}, {1334857093000l, 1}};
model = new LineChartModel();
model.setTitle("Primefaces Chart");
model.setZoom(true);
LineChartSeries series = new LineChartSeries();
for (long[] line : lines) {
series.set(line[0], line[1]);
}
DateAxis xaxis = new DateAxis();
xaxis.setTickFormat("%e/%b %H:%M");
xaxis.setTickAngle(-30);
xaxis.setMin(1334856823000l); // if not set this, chart not work
model.getAxes().put(AxisType.X, xaxis);
Axis yaxis = new LinearAxis();
yaxis.setMin(0);
model.getAxes().put(AxisType.Y, yaxis);
model.addSeries(series);
}
public LineChartModel getModel() {
return model;
}
}
My jqplot native code:
<div id="chart" style="height: 400px"></div>
<script>
$(document).ready(function () {
$.jqplot.config.enablePlugins = true;
var lines = [[1334856823000, 2], [1334856853000, 1], [1334856883000, 0], [1334856913000, 4], [1334856914000, 13],
[1334856943000, 16], [1334856973000, 23], [1334857003000, 24], [1334857033000, 36], [1334857063000, 14], [1334857093000, 1]];
$.jqplot('chart', [lines], {
title: "Jqplot Native",
axes: {
xaxis: {
renderer: $.jqplot.DateAxisRenderer,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: {
formatString: '%e/%b %H:%M',
angle: -30
}
},
yaxis: {
renderer: $.jqplot.LinearAxisRenderer,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
min: 0
}
},
cursor: {zoom: true}
});
});
</script>
The sample project is: https://github.com/douglasjunior/PrimefacesChartZoomTest
Primefaces: 5.3
Java EE: 7.0
GlassFish: 4.1.1
I am researching a few days ago. What am I doing wrong? It's a limitation?
# UPDATE 2016-08-03:
Same problem with Primefaces 6.0
# UPDATE 2016-09-01:
Based on #lalitha ramakrishnan answer I make it work just including the jqplot.dateAxisRenderer.min.js file in xhtml page. For some bug, the Primefaces dont includes this automatically.
But now the lines was always smooth=true. I tried configure by lineSeries.setSmoothLine(false) and with extender, but not worked.
Bug report: https://github.com/primefaces/primefaces/issues/1736
You can specify xaxis renderer of your primefaces chart model to be $.jqplot.DateAxisRenderer in the javascript.
The following script will be invoked when model's extender property is set to "ext".
model.setExtender("ext");
function ext() {
//this = chart widget instance
//this.cfg = options
this.cfg.axes = {
xaxis : {
renderer : $.jqplot.DateAxisRenderer,
tickRenderer : $.jqplot.CanvasAxisTickRenderer,
tickOptions : {
formatString : "%b %#d, %H:%M:%S",
angle : -30
},
drawMajorGridlines : false
},
yaxis : {
// Other Options for Y Axis
}
};
}
See Also
How to solve primefaces xAxis overlapping Issue?
EDIT:
You need to include jqplot.dateAxisRenderer.min.js file in your xhtml page.

QML toggle PropertyChanges onclick

I try to toggle my navigation with a toggle function. I want to change "x" position.
So here is what i got so far. But don't work. I try to use a toggle function to chnage state on click. I set two different state one that the navigation is visible and one that the navigation is hidden.
I get this error "ReferenceError: toggle is not defined"
Item {
id: toggleswitch
width: 200
height: 200
property bool on: false
function toggle() {
if (toggleswitch.state == "on")
toggleswitch.state = "off";
else
toggleswitch.state = "on";
}
Rectangle {
id: open
width: parent.width
height: 35
color: "#33000000"
Text {
anchors.centerIn: parent
text: "open"
color: "white"
font.family: "Helvetica"
font.pixelSize: 25
}
MouseArea { anchors.fill: parent; onClicked: toggle() }
}
states: [
State {
name: "on"
PropertyChanges { target: navigation; x: 0 }
PropertyChanges { target: toggleswitch; on: true }
},
State {
name: "off"
PropertyChanges { target: navigation; x: -300 }
PropertyChanges { target: toggleswitch; on: false }
}
]
}
Some small slider example:
import QtQuick 2.2
Rectangle {
width: 360
height: 360
Rectangle {
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
}
id: slider
state: "close"
states: [
State {
name: "close"
PropertyChanges {
target: slider
width: 50
}
},
State {
name: "open"
PropertyChanges {
target: slider
width: 360
}
}
]
transitions: [
Transition {
NumberAnimation {
target: slider
property: "width"
duration: 500
easing.type: Easing.InOutBack
}
}
]
color: "green"
}
MouseArea {
anchors.fill: parent
onClicked: {
if (slider.state == "close")
slider.state = "open";
else
slider.state = "close";
}
}
}
transitions is optional here
You can say to QML which object is your function.
Item {
id: toggleswitch
width: 200
height: 200
state: "off" //INIT YOUR STATE !!
property bool on: false
function toggle() {
if (toggleswitch.state == "on")
toggleswitch.state = "off";
else
toggleswitch.state = "on";
}
Rectangle {
id: open
width: parent.width
height: 35
color: "#33000000"
Text {
anchors.centerIn: parent
text: "open"
color: "white"
font.family: "Helvetica"
font.pixelSize: 25
}
MouseArea { anchors.fill: parent; onClicked: toggleswitch.toggle() } //here
}
states: [
State {
name: "on"
PropertyChanges { target: navigation; x: 0 }
PropertyChanges { target: toggleswitch; on: true }
},
State {
name: "off"
PropertyChanges { target: navigation; x: -300 }
PropertyChanges { target: toggleswitch; on: false }
}
]
What I would do here is not manipulate the state directly but toggle on the property directly, and bind the states to that property.
To me it feels more readable, semantical and reduce the coupling between the object and its visual states.
This also has the advantage of having states always coherent with the on property and provides a better abstraction. When using this component you can freely change the on property programmatically and the component display will update accordingly.
That's what I would probably end up with :
Item {
id: toggleswitch
width: 200
height: 200
property bool on: false
function toggle() {
on = !on //simpler toggle function
}
Rectangle {
id: open
width: parent.width
height: 35
color: "#33000000"
Text {
anchors.centerIn: parent
text: "open"
color: "white"
font.family: "Helvetica"
font.pixelSize: 25
}
MouseArea { anchors.fill: parent; onClicked: toggleswitch.toggle() }
}
states: [
State {
name: "on"
when: toggleswith.on
PropertyChanges { target: navigation; x: 0 }
},
State {
name: "off"
when: !toggleswith.on
PropertyChanges { target: navigation; x: -300 }
}
]

Resources