问题
Hi I've been strugling with this for hours, I want to send my POJO in JSON format using Primefaces Request Context to a Highchart inside my JSF to update its value. Basically I am following this solution of @Bhesh Gurung from his own stackoverflow question but I cant seem to make it work. Right now it is throwing a:
Cannot find component with identifier "pieData" referenced from "j_idt31".
I want to sucessfully create a highchart using the JSON data through the Primefaces Request Context. Please help Thanks in advance.
This are my codes below
@ManagedBean
@ViewScoped
public class PieDataProvider {
public void retrievePieData() {
List<String> categories = new ArrayList<String>();
categories.add("Electronic");
categories.add("Food");
categories.add("Liguor");
categories.add("Stationary");
categories.add("Mechanical");
List<Integer> itemCounts = new ArrayList<Integer>();
itemCounts.add(5);
itemCounts.add(20);
itemCounts.add(1);
itemCounts.add(50);
itemCounts.add(10);
RequestContext reqCtx = RequestContext.getCurrentInstance();
reqCtx.addCallbackParam("categories", new Gson().toJson(categories));
reqCtx.addCallbackParam("itemCounts", new Gson().toJson(itemCounts));
System.out.println(categories);
}
}
My xhtml page5.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition template="/template/common/commonLayout.xhtml">
<ui:define name="content">
<h:head>
<script type="text/javascript">
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"
src="http://code.highcharts.com/highcharts.js"
src="http://code.highcharts.com/modules/exporting.js"
</script>
<script type="text/javascript">
function feedPieData(xhr, status, args) {
var categories = eval('(' + args.categories + ')');
var itemCounts = eval('(' + args.itemCounts + ')');
options.xAxis.categories = categories;
var series = {
data : []
};
series.name = new Date().toString();
series.data = itemCounts;
options.series = [ series ];
chart = new Highcharts.Chart(options);
}
</script>
</h:head>
<h:body>
<p:commandLink action="#{pieDataProvider.retrievePieData}"
oncomplete="feedPieData(xhr, status, args);" value="Pie chart demo"
update="pieData" />
</h:body>
</ui:define>
<ui:define name="footer">
<h2>This is page5 Footer</h2>
</ui:define>
</ui:composition>
UPDATE: MODIFIED XHTML
<?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://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:body>
<ui:composition template="/template/common/commonLayout.xhtml">
<ui:define name="content">
<h:head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$('#container')
.highcharts(
{
chart : {
plotBackgroundColor : null,
plotBorderWidth : null,
plotShadow : false
},
title : {
text : 'Most used words, 2010'
},
tooltip : {
pointFormat : '{series.name}: {point.percentage}',
percentageDecimals : 1
},
plotOptions : {
pie : {
allowPointSelect : true,
cursor : 'pointer',
dataLabels : {
enabled : true,
color : '#000000',
connectorColor : '#000000',
formatter : function() {
return '<b>'
+ this.point.name
+ '</b>: '
+ this.percentage
//+ ' %'
;
}
}
}
},
series : [ {
type : 'pie',
name : 'Browser share',
data : [ [ 'Red', 45.0 ],
[ 'Orange', 26.8 ], {
name : 'Yellow',
y : 12.8,
sliced : true,
selected : true
}, [ 'Green', 8.5 ],
[ 'Blue', 6.2 ],
[ 'Violet', 0.7 ] ]
} ]
});
});
</script>
<script type="text/javascript">
function feedPieData(xhr, status, args) {
var categories = JSON.parse(args.categories);
var itemCounts = JSON.parse(args.itemCounts);
var series = {
data : []
};
options.series[0].data.length = 0;
series.data = categories;
series.data = itemCounts;
options.series = [ series ];
chart = new Highcharts.Chart(options);
}
</script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</h:head>
<h:body>
<div id="container"
style="min-width: 400px; height: 400px; margin: 0 auto"></div>
<h:form>
<p:commandLink action="#{pieDataProvider.retrievePieData}"
oncomplete="feedPieData(xhr, status, args);"
value="Pie chart demo" />
</h:form>
</h:body>
</ui:define>
<ui:define name="footer">
<h2>This is page5 Footer</h2>
</ui:define>
</ui:composition>
</h:body>
</html>
回答1:
You seem to fail to understand that Highcharts is a JavasScript environment that runs solely on the client, while PrimeFaces/JSF is on the server side and they act in this context simply as HTML, CSS and JavaScript code generator.
In your particular case, PrimeFaces is simply used to send data from the server to the client via RequestContext
. After AJAX call completes and effectively, serialized data is received by the client, you call a JavaScript function that creates a Highcharts JS component entirely on the client from the received data.
All in all, it yields us with the following setup.
** The view elements **
<h:form>
<p:commandLink action="#{pieDataProvider.retrievePieData}"
oncomplete="feedPieData(xhr, status, args);"
value="Generate pie chart" />
</h:form>
** The JavaScript **
<script type="text/javascript">
function feedPieData(xhr, status, args) {
var categories = JSON.parse(args.categories);//serialized data from server
var itemCounts = JSON.parse(args.itemCounts);//serialized data from server
//next you create the chart and show it
}
</script>
** The action method **
public void retrievePieData() {
List<String> categories = generateCategories();
List<Integer> itemCounts = generateItems();
RequestContext reqCtx = RequestContext.getCurrentInstance();
reqCtx.addCallbackParam("categories", new Gson().toJson(categories));//additional serialized data to be sent
reqCtx.addCallbackParam("itemCounts", new Gson().toJson(itemCounts));//additional serialized data to be sent
}
来源:https://stackoverflow.com/questions/16414903/how-to-send-json-using-jsf2-primefaces-request-context-to-highchart