- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用了JSF 2.2,Primefaces 6.0,CDI和Highcharts 4.2.3。我的页面之一包含一张图表(Highcharts)和一个干扰我图表的简单表格。我剪切了代码(请看下面),向您展示代码中最重要的部分。
我想实现这样的目标:
commandButton
时,图表应使用新数据重新创建。 createChart
函数,该函数使用#{bean.getDataForChart1a(typeOfData)}
从CDI bean(实际上是从数据库)下载数据(对于我的图表),并将这些数据放入js变量中。除了下移数据外,该函数还创建图表。 createNewChart
函数,该函数销毁了我当前的图表,并调用createChart
函数来创建应包含新数据的新图表。 oncomplete="createNewChart();"
属性添加到了
commandButton
中,此刻,我的页面如下所示:
commandButton
时,将重新创建图表,但它使用的是旧数据。我注意到createChart
函数中没有再次下载数据,js没有执行#{bean.getDataForChart1a(typeOfData)}
。因此,#{bean.getDataForChart1a(typeOfData)}
在开始时仅执行一次。我不明白为什么。 <!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:head>
<!-- loading css -->
</h:head>
<h:body>
<div id="container" style="height: 750px; width: 100%; margin: 0 auto;"/>
<script type="text/javascript">
//<![CDATA[
var chart;
var protos;
var dataChart;
var color;
var seriesChart;
var i, len;
function createChart() {
//Downloading data for the chart
protos = #{visualizationController.getDataForChart1a("protos")};
dataChart = #{visualizationController.getDataForChart1a("data")};
color = #{visualizationController.getDataForChart1a("color")};
seriesChart = [];
//Creating several series of the data
for (i = 0, len = protos.length; i < len; i++) {
seriesChart.push({
color: color[i],
name: protos[i],
data: dataChart[i]
//other options
});
}
console.time('scatter');
console.time('asyncRender');
Highcharts.setOptions({
lang: {
//translate
}
});
// Create the chart
chart = new Highcharts.Chart({
//other options
chart: {
//other options
renderTo: "container"
},
series : seriesChart
});
console.timeEnd('scatter');
}
function createNewChart(){
chart.destroy();
createChart();
}
createChart();
//]]>
</script>
<h:form id="filterForm">
<p:selectManyCheckbox id="filter" value="#{visualizationController.selectedKindOfNetwork}" layout="responsive" columns="4">
<p:ajax update="filterButton" />
<f:selectItems value="#{visualizationController.kindOfNetwork}" var="kindOfNetwork" itemLabel="#{kindOfNetwork}" itemValue="#{kindOfNetwork}" />
</p:selectManyCheckbox>
<br/>
<p:commandButton id="filterButton" value="Filtruj" action="#{visualizationController.actionFilterButtonForChart1a()}"
disabled="#{!visualizationController.visibilityFilterButtonForChart1a}"
update="filterForm"
oncomplete="createNewChart();"/>
</h:form>
</h:body>
</html>
最佳答案
我已经达到了预期的结果。基于@SiMag的评论,我发布了答案,其中包括几种可能的解决方案。帖子分为几个部分,使您可以了解我做错了什么以及为解决此问题所做的事情。
我做错什么了?
就像@SiMag写道:
The script tag isn't updated after the first load so the #{visualizationController.getData...} expressions aren't evaluated anymore and they are referring to the old data.
createChart
javascript函数(自动执行,无需任何按钮或链接),并且该函数应使用我在CDI bean中设置的多个值。作为此操作的结果,应显示该图表。 changeData
javascript函数,并且该函数应使用在CDI bean中设置的几个值。作为此操作的结果,图表应更新其显示的数据。 RequestContext
将一些值从CDI bean传递到javascript。为了实现这一点,我基于素语表documentation (第11.1章RequestContext); createChart
函数; changeChart
函数。 <script type="text/javascript">
//<![CDATA[
var chart;
var protos;
var dataChart;
var color;
var seriesChart;
var i, len;
//Creating the chart.
function createChart(protosArg, dataArg, colorsArg) {
$(function() {
//The data are parsed
protos = JSON.parse(protosArg);
dataChart = eval(dataArg);
colors = JSON.parse(colorsArg);
seriesChart = [];
//Creating several series of the data
for (i = 0, len = protos.length; i < len; i++) {
seriesChart.push({
color: color[i],
name: protos[i],
data: dataChart[i]
//other options
});
}
console.time('scatter');
console.time('asyncRender');
Highcharts.setOptions({
lang: {
//translate
}
});
// Create the chart
chart = new Highcharts.Chart({
//other options
chart: {
//other options
renderTo: "container"
},
series : seriesChart
});
console.timeEnd('scatter');
});
}
//Updating the chart using the new supplied data.
function changeData(protosArg, dataArg, colorsArg){
$(function() {
protos = JSON.parse(protosArg);
dataChart = eval(dataArg);
colors = JSON.parse(colorsArg);
seriesChart = [];
//Creating several series of the data using the new supplied data.
for (i = 0, len = protos.length; i < len; i++) {
seriesChart.push({
color: color[i],
name: protos[i],
data: dataChart[i]
//other options
});
}
//Removing the old data from the chart.
for (i = 0, len = chart.series.length; i < len; i++) {
chart.series[0].remove(false);
}
//Inserting the new data to the chart.
for (i = 0, len = protos.length; i < len; i++) {
chart.addSeries(seriesChart[i],false);
}
chart.redraw();
});
}
//]]>
</script>
String
变量。在服务器端,此变量的输出如下所示:
["tcp","udp",...]
[[[date,23],[date,1234]],[[date,1234]]]
["black","white",...]
JSON.parse()
和
eval()
方法保存传递的数据。为什么?由于浏览器将传递的数据解释为字符串,因此我们必须将数据转换为数组。
RequestContext#addCallbackParam()
方法创建了几个回调参数。
getProtos()
,
getData()
和
getColors()
方法返回带有我准备好的数据的字符串。
requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam("protosArg", getProtos());
requestContext.addCallbackParam("dataArg", getData());
requestContext.addCallbackParam("colorsArg", getColors());
RequestContext#execute()
方法,该方法调用
createChart
javascript函数并传递三个必需值:
@PostConstruct
public void init() {
//Creating the callback parameters.
initData();
requestContext.execute(String.format("createChart('%s', '%s', '%s')", getProtos(),getData(),getColors()));
}
''
字符在javascript端实现了正确的表示。目前,浏览器会将数据解释为字符串。我在CDI bean的
execute()
方法(具有
init()
批注)中调用
@PostConstruct
方法,因此,我确定:
createChart
javascript函数在开始时仅执行一次(CDI bean具有@ViewScoped
批注); oncomplete
组件的
<p:commandButton>
属性的值。
oncomplete
属性调用
changeData
javascript函数。
args
参数引用我在服务器端设置的回调参数。
<p:commandButton id="filterButton" value="Filter" action="#{chart2Controller.actionFilterButton()}"
disabled="#{!chart2Controller.visibilityFilterButton}"
update="filterForm"
oncomplete="changeData(args.protosArg, args.dataArg, args.colorsArg);"/>
@Named
@ViewScoped
public class Chart2Controller implements Serializable {
/**
* Start method.
*/
@PostConstruct
public void init() {
//Creating the callback parameters.
initData();
requestContext.execute(String.format("createChart('%s', '%s', '%s')", getProtos(),getData(),getColors()));
}
/**
* Downloading the data from the database.
*/
private void initData(){
/*
* Sending the query to the database including the filter options of the form,
* saving the result and preparing the data basing on the result.
*/
//Preparing the callback parameters.
requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam("protos", protos);
requestContext.addCallbackParam("data", data);
requestContext.addCallbackParam("colors", colors);
}
/**
* Action for the filter button.
*/
public void actionFilterButton(){
initData();
}
/**
* Visibility for filter button.
*/
public boolean getVisibilityFilterButton(){
//return true or false.
}
//Getter and Setter
private static final long serialVersionUID = -8128862377479499815L;
@Inject
private VisualizationService visualizationService;
private RequestContext requestContext;
private List<String> kindOfNetwork;
private List<String> selectedKindOfNetwork;
private String protos;
private String data;
private String colors;
}
RequestContext
将一些值从CDI bean传递到javascript; createChart
函数; changeChart
函数。 createChart
函数正在调用的位置不同。在这种情况下,我在客户端调用了
createChart
,并使用EL从CDI bean提供值。
RequestContext#execute()
方法外,我已经完成了与以前的解决方案相同的操作。取而代之的是,我在脚本结尾处在客户端调用了
createChart
函数。该脚本应如下所示:
<script type="text/javascript">
//<![CDATA[
var protos;
var dataChart;
var color;
//other code
//Creating the chart.
function createChart(protosArg, dataArg, colorsArg) {
$(function() {
protos = protosArg;
dataChart = dataArg;
colors = colorsArg;
//other code
});
}
//Updating the chart using the new supplied data.
function changeData(protosArg, dataArg, colorsArg){
$(function() {
//The data are parsed
protos = JSON.parse(protosArg);
dataChart = eval(dataArg);
colors = JSON.parse(colorsArg);
//other code
});
}
createChart(#{chart2Controller.protos}, #{chart2Controller.data}, #{chart2Controller.colors});
//]]>
</script>
JSON.parse()
函数中删除了
eval()
和
createChart
方法,因为EL已直接写入javascript代码,并且浏览器将数据正确解释为数组。
<h:inputHidden>
组件将一些值从CDI bean传递到javascript; createChart
函数; changeChart
函数。 <h:inputHidden>
componenet(每个要传递给javascript的值一个)。该表格应如下所示:
<h:form id="filterForm">
<h:inputHidden id="protos" value="#{chart2Controller.protos}" />
<h:inputHidden id="data" value="#{chart2Controller.data}" />
<h:inputHidden id="colors" value="#{chart2Controller.colors}" />
<p:selectManyCheckbox id="filter" value="#{chart2Controller.selectedKindOfNetwork}" layout="responsive" columns="4">
<p:ajax update="filterButton" />
<f:selectItems value="#{chart2Controller.kindOfNetwork}" var="kindOfNetwork" itemLabel="#{kindOfNetwork}" itemValue="#{kindOfNetwork}" />
</p:selectManyCheckbox>
<br/>
<p:commandButton id="filterButton" value="Filtruj" action="#{chart2Controller.actionFilterButton()}"
disabled="#{!chart2Controller.visibilityFilterButton}"
update="filterForm"
oncomplete="changeData();"/>
</h:form>
id
的
value
和
<h:inputHidden>
属性,并将所需的数据保存在
value
属性中。
update
组件的
<p:commandButton>
属性),因此,我确定每次按下时,都会下载输入的
value
属性中的数据按钮。
document.getElementById("filterForm:idOfInput").value
在javascript代码中引用了这些值。请记住使用
JSON.parse()
或
eval()
,因为数据被解释为字符串。该脚本应如下所示:
<script type="text/javascript">
//<![CDATA[
var chart;
var protos;
var dataChart;
var colors;
function createChart() {
$(function() {
protos = JSON.parse(document.getElementById("filterForm:protos").value);
dataChart = eval(document.getElementById("filterForm:data").value);
colors = JSON.parse(document.getElementById("filterForm:colors").value);
//other code
});
}
function changeData(){
$(function() {
protos = JSON.parse(document.getElementById("filterForm:protos").value);
dataChart = eval(document.getElementById("filterForm:data").value);
colors = JSON.parse(document.getElementById("filterForm:colors").value);
//other code
});
}
//]]>
</script>
function changeData(...){
//Preparation of the received data.
//Removing the old data from the chart.
for (i = 0, len = chart.series.length; i < len; i++) {
chart.series[0].remove(false);
}
//Inserting the new data to the chart.
for (i = 0, len = protos.length; i < len; i++) {
chart.addSeries(seriesChart[i],false);
}
chart.redraw();
}
false
参数设置了
redraw
。 Highcharts API说:
If doing more operations on the chart, it is a good idea to set redraw to false and call chart.redraw() after.
changeData
javascript函数:
function changeData(...){
chart.destroy();
createChart(...);
}
function changeData(...){
//Preparation of the received data.
for(var i = 0; i < chart.series.length; i++){
chart.series[i].setData(seriesData[i],false);
}
chart.redraw();
}
关于javascript - 使用旧数据重新创建图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38463938/
几周前,我安装了一个新的 ssl 证书来替换一个过期的证书。 .crt 和 .key 的文件名保持不变。只是内容变了。 现在,当我访问我的网站时,它说证书已过期,我看到它正在使用旧的证书链。我可以确认
这个问题在这里已经有了答案: Make namespaces backwards compatible in PHP (4 个回答) 8 年前关闭。 我真的很想在我的工作流程中采用命名空间。据我了解,
我从 CN1 开始,然后以 Todo App 为例。当我在 Netbeans 中运行 de app 时,只出现一个空白表单,我更改了主题,添加了一个 jpg 图像并使用旧的 GUI Builder 在
我想知道是否有一些 Laravel 人员可以帮忙。 我有一个表单,其中有 2 个单选按钮,当表单提交时,它会通过验证器,如果验证器失败,它会返回表单,使用输入填充字段并显示错误消息。 我似乎无法对单选
我正在使用 Java 中没有泛型的旧代码。 hashMap 是在该代码中定义的,没有泛型,例如: Map A = new HashMap(); 在这段代码中,我想如何确定要在键和值中放入什么内容,以及
我想问一个关于项目兼容性的问题。我的论文项目是在Windows Vista和XP上在JRE 1.6和JDK 1.6下开发的。该项目使用Java新套接字。今天我尝试在 Windows 8(64 位)机器
有谁知道一个脚本可以将旧的 Products 命名空间样式 Plone 附加组件包装到 Egg 中吗? 生成setup.py 创建目录结构 还需要采取其他措施吗? 鸡蛋化过程中有什么陷阱吗? 最佳答案
我已经运行 MySQL 5.6.12 一段时间了。我决定将我的 WAMP 服务器更新到最新的 PHP 版本。 在此过程中,它还将 MySQL 更新到 5.6.17,保留 .12 数据,但无法访问。 如
最近,我一直在尝试根据互联网上的各种旧教程编写论坛代码,但是我最近遇到了一个问题 - 尽管我完全按照教程所述进行操作,但我收到了空格错误。我认为这可能是因为某些 MySQL 命令可能已更改。如果有人可
我正在创建对 Count 表的查询。 $Month = $_POST['Month']; $query = "SELECT ANY_VALUE(AD) AS ad, COU
如果我使用 mysqldump 工具备份旧版本的 MySql 数据库,是否存在任何已知风险?例如,如果我在生产机器上使用 mysqldump 5.6 来备份 MySql 5.X 数据库。 最佳答案 有
当将 columnsData 值分配给 columns 时,我有两个 JSON 对象 columnsData 和 columns,这两个值都会更改。 var columnsData = [
我有一个需要在 gcc 4.4 上编译的多线程应用程序,我不允许使用 c++0x 标志。 我希望一个变量以原子方式运行,但不幸的是没有 C++0x 标志我无法使用 atomic在 C++ 中。 我试过
我可以借助广播事件(ACTION_TIME_CHANGED 和 ACTION_DATE_CHANGED)获取时间更改事件。 我需要在时间更改后获取之前的时间。例如,当前时间是 10:00。我要把时间改
我正在尝试在我的 Android 应用程序中创建一个 DatePickerDialog,但是当我创建一个 DatePickerDialog 时,我收到以下消息:Call requires API le
{!! Form::open(array('route' => 'posts.store', 'data-parsley-validate' => '')) !!} {{ Form::labe
我的问题与 iOS 周围的蓝牙技术有关。我看过关于蓝牙低功耗 101、新功能、基础知识等的 WWDC,以及关于使用 iOS 5 及更高版本中可用的 CoreBluetooth 框架的内容。我浏览了不同
我有一个有五个屏幕的应用。 在每个屏幕上,我在 viewDidLoad 中从服务器访问数据。 在每个屏幕上我都有下一个按钮。 当我从屏幕一转到屏幕五(通过单击下一步 4 次)时,在 NSLog 中,我
我最近在一家网络报纸找到了一份工作。在网站上,我们有一个非常古老且重要的 Symfony 应用程序,它是为一位年长的开发人员编写的,已经消失很久了。该应用程序是神圣的:是报纸收入的血液。问题是我们没有
我相信我已经找到了一种方法来实现类似可移植 C89 中众所周知的“struct hack”的方法。我很好奇这是否真的严格符合 C89。 主要思想是:我分配足够大的内存来容纳初始结构和数组元素。确切的大
我是一名优秀的程序员,十分优秀!