gpt4 book ai didi

java - 具有异步数据 (RPC) 的 GWT Google 可视化

转载 作者:行者123 更新时间:2023-12-03 19:04:26 35 4
gpt4 key购买 nike

在为这项工作寻找合适的实用程序之后,我终于放弃并解决了我面临的问题:How do you render asynchronously loaded data (RPC) in a Google Visualization for GWT chart它本身是通过异步 AjaxLoader 加载的,并行执行两个请求?

或者换句话说:无论图表数据是在加载可视化库之前还是之后到达,我们如何才能确保图表渲染正常?

这两个限制较少(或不太雄心勃勃)的场景非常简单。

简单场景 #1:使用静态数据

不依赖于 RPC 数据,使用可视化非常简单。这是因为只有一个异步请求:加载可视化库。因此,不存在数据加载可视化库之前到达的风险。

示例代码片段:

public class MyViewImpl implements MyView {
private Panel main;

public MyViewImpl() {
this.main = new FlowPanel();

Runnable onVizLoaded = new Runnable() {
@Override
public void run() {
DataTable data = DataTable.create();
Options options = Options.create();

// Populate data and options based on static data here...

// Instantiate and attach new chart.
LineChart lineChart = new LineChart(data, options);
main.add(lineChart);
}
};
// Load Google Visualization asynchronously.
VisualizationUtils.loadVisualizationApi(onVizLoaded, LineChart.PACKAGE);
}

// View logic goes here...
}

可视化库很容易加载,LineChart 会在加载完成后创建和呈现。考虑一下负载特征的概述:

  Viz load: |---?---|
Chart data: |
Render: |--->

简单场景 #2:串行运行请求

在通过 RPC 加载图表数据时,可以使用上述代码段。但是,以下内容暗示在加载并准备好可视化库之前不会获取图表数据。您可能对这种性能影响没有意见 - 我不是!

  1. 主要是因为我无法控制可视化库的加载时间,因此无法控制获取数据之前的延迟
  2. 我不喜欢我的 View 决定应用程序的行为。应用程序逻辑属于 Presenter。

示例代码片段:

public class MyViewImpl implements MyView {
private Panel main;

public MyViewImpl() {
this.main = new FlowPanel();

Runnable onVizLoaded = new Runnable() {
@Override
public void run() {
// Make RPC call.
ClientFactory.getService().getData(new AsyncCallback<MyResult>() {
@Override
public void onSuccess(MyResult result) {
DataTable data = DataTable.create();
Options options = Options.create();

// Populate data from RPC result.
data.addColumn(ColumnType.DATE);
data.addRow();
data.setValue(0, 0, result.getDate());
// ... Etc.

// Set options.
options.setWidth(500);
// ... Etc.

// Instantiate and attach new chart.
LineChart lineChart = new LineChart(data, options);
main.add(lineChart);
}

@Override
public void onFailure(Throwable caught) {
// Handle RPC error.
}
});
}
};
// Load Google Visualization asynchronously.
VisualizationUtils.loadVisualizationApi(onVizLoaded, LineChart.PACKAGE);
}

// View logic goes here...
}

负载特性说明问题:

  Viz load: |---?---|
Chart data: |----~----|
Render: |--->

期望的场景:并行运行

所需的场景将具有以下特征,可视化库加载速度快于数据:

  Viz load: |---?---|
Chart data: |----~----|
Render: |--->

或者比可视化库更快的数据加载:

  Viz load: |---?---|
Chart data: |--~--|
Render: |--->

问题是:如何?

最佳答案

以下策略将满足要求:

  1. 请求并行运行
  2. 图表在两个请求完成后立即呈现
  3. 应用程序逻辑(RPC 调用)保留在 Presenter 中。

示例代码片段:Presenter

public class MyPresenter implements MyView.Presenter {
private MyView view;

// ... Constructor etc. goes here...

@Override
public void render() {
// Make RPC call immediately when Presenter should begin rendering.
ClientFactory.getService().getData(new AsyncCallback<MyResult>() {
@Override
public void onSuccess(MyResult result) {
// Pass data to view for rendering (when appropriate.)
view.render(result);
}

@Override
public void onFailure(Throwable caught) {
// Handle RPC error.
}
});
}
}

示例代码片段:ViewImpl

public class MyViewImpl implements MyView {
private Panel main;
private AsyncChart<LineChart> asyncLineChart;

public MyViewImpl() {
this.main = new FlowPanel();

// Runnable wrapper (see next snippet.)
this.asyncLineChart = new AsyncChart<LineChart>() {
@Override
public LineChart onAttach(DataTable data, Options options) {
// Instantiate and attach new chart.
LineChart lineChart = new LineChart(data, options);
main.add(lineChart);

return lineChart;
}
};

// Load Google Visualization asynchronously.
VisualizationUtils.loadVisualizationApi(this.asyncLineChart, LineChart.PACKAGE);
}

@Override
public void render(final MyResult result) { // Invoked from Presenter (see above snippet.)
// Schedule rendering to be invoked ASAP (but not before Visualization library is loaded.)
this.asyncLineChart.enqueueWriter(new AsyncChartWriter() {
@Override
public void onWrite(DataTable data, Options options) {
// Populate data from RPC result.
data.addColumn(ColumnType.DATE);
data.addRow();
data.setValue(0, 0, result.getDate());
// ... Etc.

// Set options.
options.setWidth(500);
// ... Etc.
}
});
}
}

现在是肉!

示例代码片段:AsyncChart 准备复制。

import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.corechart.CoreChart;
import com.google.gwt.visualization.client.visualizations.corechart.Options;


/**
* Wrapping {@link Runnable} to use with the load methods of {@link VisualizationUtils}
* allowing a chart to be populated asynchronously (e.g., via RPC.)
*
* This wrapper handles the process of deferred attachment of the chart via the
* {@link #onAttach(DataTable, Options)} method.
*
* Chart data is set / updated by means of a {@link AsyncChartWriter} mutating the
* passed {@link DataTable} and {@link Options} instances.
*
* {@link AsyncChartWriter} can be reassigned (via {@link #enqueueWriter(AsyncChartWriter)})
* in order to redraw the chart.
*
* @param <T> The concrete chart type.
*/
public abstract class AsyncChart<T extends CoreChart> implements Runnable {
public interface AsyncChartWriter {
void onWrite(DataTable data, Options options);
}

private enum State {
NEW,
LOADED,
ATTACHED
}

private State state;
private T chart;
private AsyncChartWriter enqueuedWriter;

public AsyncChart() {
this.state = State.NEW;
}

public abstract T onAttach(DataTable data, Options options);

/**
* Enqueues a writer to populate or manipulate the chart. This will happen immediately
* if the visualization API is already loaded and will otherwise be deferred.
*
* @param writer The writer to enqueue.
*/
public void enqueueWriter(AsyncChartWriter writer) {
this.enqueuedWriter = writer;
processWriter();
}

/* (non-Javadoc)
* @see java.lang.Runnable#run()
*
* Invoked when the visualization API has loaded.
*/
@Override
public void run() {
this.state = State.LOADED;
if (this.enqueuedWriter != null) {
processWriter();
}
}

private void processWriter() {
if (this.state == State.LOADED || this.state == State.ATTACHED) {
DataTable data = DataTable.create();
Options options = CoreChart.createOptions();
this.enqueuedWriter.onWrite(data, options);
if (this.state == State.LOADED) {
this.chart = onAttach(data, options); // Instantiate and attach.
this.state = State.ATTACHED;
} else {
this.chart.draw(data, options); // Redraw already attached chart.
}
this.enqueuedWriter = null;
}
// If state = NEW do nothing until run() is invoked (and state has changed to LOADED.)
}
}

享受您的并行负载。

关于java - 具有异步数据 (RPC) 的 GWT Google 可视化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28106040/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com