ingo@521: package de.intevation.flys.client.client.ui.chart;
ingo@521:
ingo@521: import java.util.Date;
ingo@521:
ingo@521: import com.google.gwt.core.client.GWT;
ingo@538: import com.google.gwt.user.client.rpc.AsyncCallback;
ingo@521:
ingo@521: import com.smartgwt.client.widgets.Canvas;
ingo@521: import com.smartgwt.client.widgets.Img;
ingo@521:
ingo@521: import com.smartgwt.client.widgets.layout.HLayout;
ingo@521: import com.smartgwt.client.widgets.layout.VLayout;
ingo@521:
ingo@521: import com.smartgwt.client.widgets.events.ResizedEvent;
ingo@521: import com.smartgwt.client.widgets.events.ResizedHandler;
ingo@521:
ingo@538: import de.intevation.flys.client.shared.Transform2D;
ingo@521: import de.intevation.flys.client.shared.model.Collection;
ingo@521: import de.intevation.flys.client.shared.model.OutputMode;
ingo@521: import de.intevation.flys.client.client.Config;
ingo@531: import de.intevation.flys.client.client.event.OutputParameterChangeEvent;
ingo@531: import de.intevation.flys.client.client.event.OutputParameterChangeHandler;
ingo@541: import de.intevation.flys.client.client.event.ZoomEvent;
ingo@541: import de.intevation.flys.client.client.event.ZoomHandler;
ingo@538: import de.intevation.flys.client.client.services.ChartInfoService;
ingo@538: import de.intevation.flys.client.client.services.ChartInfoServiceAsync;
ingo@521: import de.intevation.flys.client.client.ui.CollectionView;
ingo@521: import de.intevation.flys.client.client.ui.OutputTab;
ingo@521:
ingo@521:
ingo@521: /**
ingo@521: * @author Ingo Weinzierl
ingo@521: */
ingo@531: public class ChartOutputTab
ingo@531: extends OutputTab
ingo@541: implements ResizedHandler, OutputParameterChangeHandler, ZoomHandler
ingo@531: {
ingo@521: public static final int DEFAULT_CHART_WIDTH = 600;
ingo@521: public static final int DEFAULT_CHART_HEIGHT = 500;
ingo@521:
ingo@527: public static final int THEMEPANEL_MIN_WIDTH = 200;
ingo@527:
ingo@527:
ingo@538: /** The service that is used to fetch chart information.*/
ingo@538: protected ChartInfoServiceAsync info = GWT.create(ChartInfoService.class);
ingo@538:
ingo@538: /** The transformer used to transform image pixels into chart coordinates.*/
ingo@538: protected Transform2D transformer;
ingo@538:
ingo@538: /** The collection view.*/
ingo@538: protected CollectionView view;
ingo@538:
ingo@538:
ingo@521: /** The canvas that wraps the chart toolbar.*/
ingo@521: protected Canvas tbarPanel;
ingo@521:
ingo@521: /** The canvas that wraps the theme editor.*/
ingo@521: protected Canvas left;
ingo@521:
ingo@521: /** The canvas that wraps the chart.*/
ingo@521: protected Canvas right;
ingo@521:
ingo@521:
ingo@542: /** Chart zoom options.*/
ingo@542: protected double[] xrange;
ingo@542: protected double[] yrange;
ingo@542:
ingo@542:
ingo@521: /**
ingo@521: * The default constructor to create a new ChartOutputTab.
ingo@521: *
ingo@521: * @param title The title of this tab.
ingo@521: * @param collection The Collection which this chart belongs to.
ingo@521: * @param mode The OutputMode.
ingo@521: */
ingo@521: public ChartOutputTab(
ingo@521: String title,
ingo@521: Collection collection,
ingo@521: OutputMode mode,
ingo@521: CollectionView collectionView
ingo@521: ){
ingo@521: super(title, collection, mode);
ingo@521:
ingo@538: view = collectionView;
ingo@521: left = new Canvas();
ingo@521: right = new Canvas();
ingo@534: tbarPanel = new ChartToolbar(collectionView, this);
ingo@542: xrange = new double[2];
ingo@542: yrange = new double[2];
ingo@521:
ingo@521: left.setBorder("1px solid black");
ingo@527: left.setWidth(THEMEPANEL_MIN_WIDTH);
ingo@527: left.setMinWidth(THEMEPANEL_MIN_WIDTH);
ingo@521: right.setWidth("*");
ingo@521:
ingo@521: VLayout vLayout = new VLayout();
ingo@521: vLayout.setMembersMargin(2);
ingo@521:
ingo@521: HLayout hLayout = new HLayout();
ingo@521: hLayout.setWidth100();
ingo@521: hLayout.setHeight100();
ingo@521: hLayout.setMembersMargin(10);
ingo@521:
ingo@521: hLayout.addMember(left);
ingo@521: hLayout.addMember(right);
ingo@521:
ingo@531: ChartThemePanel ctp = new ChartThemePanel(collection, mode);
ingo@531: ctp.addOutputParameterChangeHandler(this);
ingo@531:
ingo@521: right.addChild(createChartPanel());
ingo@531: left.addChild(ctp);
ingo@521:
ingo@521: vLayout.addMember(tbarPanel);
ingo@521: vLayout.addMember(hLayout);
ingo@521:
ingo@521: setPane(vLayout);
ingo@521:
ingo@521: right.addResizedHandler(this);
ingo@521: }
ingo@521:
ingo@521:
ingo@521: /**
ingo@521: * This method is called after the chart panel has resized. It removes the
ingo@521: * chart - if existing - and requests a new one with adjusted size.
ingo@521: *
ingo@521: * @param event The resize event.
ingo@521: */
ingo@521: public void onResized(ResizedEvent event) {
ingo@531: updateChartPanel();
ingo@538: updateTransformer();
ingo@531: }
ingo@531:
ingo@531:
ingo@531: /**
ingo@531: * Listens to change event in the chart them panel and updates chart after
ingo@531: * receiving such an event.
ingo@531: *
ingo@531: * @param event The OutputParameterChangeEvent.
ingo@531: */
ingo@531: public void onOutputParameterChanged(OutputParameterChangeEvent event) {
ingo@531: updateChartPanel();
ingo@531: }
ingo@531:
ingo@531:
ingo@538: /**
ingo@541: * Listens to zoom events and refreshes the current chart in such case.
ingo@541: *
ingo@541: * @param evt The ZoomEvent that stores the coordinates for zooming.
ingo@541: */
ingo@541: public void onZoom(ZoomEvent evt) {
ingo@541: double[] lower = transformer.transform(evt.getStartX(), evt.getStartY());
ingo@541: double[] upper = transformer.transform(evt.getEndX(), evt.getEndY());
ingo@541:
ingo@542: xrange[0] = lower[0];
ingo@542: xrange[1] = upper[0];
ingo@542: yrange[0] = upper[1];
ingo@542: yrange[1] = lower[1];
ingo@541:
ingo@542: updateChartPanel();
ingo@541: }
ingo@541:
ingo@541:
ingo@543: public void resetRanges() {
ingo@543: xrange[0] = 0;
ingo@543: xrange[1] = 0;
ingo@543: yrange[0] = 0;
ingo@543: yrange[1] = 0;
ingo@543:
ingo@543: updateChartPanel();
ingo@543: }
ingo@543:
ingo@543:
ingo@541: /**
ingo@544: * This method is used to zoom out.
ingo@544: *
ingo@544: * @param factor The factor should be between 0-100.
ingo@544: */
ingo@544: public void zoomOut(int factor) {
ingo@544: if (factor < 0 || factor > 100 || xrange == null || yrange == null) {
ingo@544: return;
ingo@544: }
ingo@544:
ingo@548: double xadd = (xrange[1] - xrange[0]) / 100 * factor;
ingo@548: double yadd = (yrange[1] - yrange[0]) / 100 * factor;
ingo@548:
ingo@548: xrange[0] -= xadd;
ingo@548: xrange[1] += xadd;
ingo@548: yrange[0] -= yadd;
ingo@548: yrange[1] += yadd;
ingo@544:
ingo@544: updateChartPanel();
ingo@544: }
ingo@544:
ingo@544:
ingo@544: /**
ingo@538: * Updates the Transform2D object using the chart info service.
ingo@538: */
ingo@538: public void updateTransformer() {
ingo@538: Canvas chart = getChartPanel();
ingo@538:
ingo@538: Config config = Config.getInstance();
ingo@538: String url = config.getServerUrl();
ingo@538: String locale = config.getLocale();
ingo@538:
ingo@538: info.getChartInfo(
ingo@538: view.getCollection(),
ingo@538: url,
ingo@538: locale,
ingo@538: mode.getName(),
ingo@538: chart.getWidth(),
ingo@538: chart.getHeight(),
ingo@538: new AsyncCallback() {
ingo@538: public void onFailure(Throwable caught) {
ingo@538: GWT.log("ERROR: " + caught.getMessage());
ingo@538: }
ingo@538:
ingo@538: public void onSuccess(Transform2D transformer) {
ingo@538: setTransformer(transformer);
ingo@538: }
ingo@538: });
ingo@538: }
ingo@538:
ingo@538:
ingo@531: public void updateChartPanel() {
ingo@521: Canvas[] children = right.getChildren();
ingo@521: for (Canvas child: children) {
ingo@521: right.removeChild(child);
ingo@521: }
ingo@521:
ingo@521: right.addChild(createChartPanel(right.getWidth(), right.getHeight()));
ingo@521: }
ingo@521:
ingo@521:
ingo@542: /**
ingo@542: * Returns the existing chart panel.
ingo@542: *
ingo@542: * @return the existing chart panel.
ingo@542: */
ingo@534: public Canvas getChartPanel() {
ingo@538: Canvas[] children = right.getChildren();
ingo@538:
ingo@538: if (children == null || children.length == 0) {
ingo@538: GWT.log("=> No chart image in the panel.");
ingo@538: return right;
ingo@538: }
ingo@538:
ingo@538: return children[0];
ingo@538: }
ingo@538:
ingo@538:
ingo@538: /**
ingo@538: * Returns the Transform2D object used to transform image coordinates into
ingo@538: * chart coordinates.
ingo@538: *
ingo@538: * @return the Transform2D object.
ingo@538: */
ingo@538: public Transform2D getTransformer() {
ingo@538: return transformer;
ingo@538: }
ingo@538:
ingo@538:
ingo@538: /**
ingo@538: * Set a new Transform2D object for the chart. This should be the case, only
ingo@538: * if the chart image size has changed.
ingo@538: *
ingo@538: * @param transformer The new Transform2D object.
ingo@538: */
ingo@538: protected void setTransformer(Transform2D transformer) {
ingo@538: this.transformer = transformer;
ingo@534: }
ingo@534:
ingo@534:
ingo@542: /**
ingo@542: * Creates a new chart panel with default size.
ingo@542: *
ingo@542: * @return the created chart panel.
ingo@542: */
ingo@521: protected Canvas createChartPanel() {
ingo@521: return createChartPanel(DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT);
ingo@521: }
ingo@521:
ingo@521:
ingo@542: /**
ingo@542: * Creates a new chart panel with specified width and height.
ingo@542: *
ingo@542: * @param width The width for the chart panel.
ingo@542: * @param height The height for the chart panel.
ingo@542: *
ingo@542: * @return the created chart panel.
ingo@542: */
ingo@521: protected Canvas createChartPanel(int width, int height) {
ingo@521: Img chart = getChartImg(width, height);
ingo@521: chart.setWidth100();
ingo@521: chart.setHeight100();
ingo@521:
ingo@521: return chart;
ingo@521: }
ingo@521:
ingo@521:
ingo@521: /**
ingo@521: * Builds the chart image and returns it.
ingo@521: *
ingo@521: * @param width The chart width.
ingo@521: * @param height The chart height.
ingo@521: *
ingo@521: * @return the chart image.
ingo@521: */
ingo@521: protected Img getChartImg(int width, int height) {
ingo@521: return new Img(getImgUrl(width, height));
ingo@521: }
ingo@521:
ingo@521:
ingo@521: /**
ingo@521: * Builds the URL that points to the chart image.
ingo@521: *
ingo@521: * @param width The width of the requested chart.
ingo@521: * @param height The height of the requested chart.
ingo@542: * @param xr Optional x range (used for zooming).
ingo@542: * @param yr Optional y range (used for zooming).
ingo@521: *
ingo@521: * @return the URL to the chart image.
ingo@521: */
ingo@521: protected String getImgUrl(int width, int height) {
ingo@521: Config config = Config.getInstance();
ingo@521:
ingo@521: String imgUrl = GWT.getModuleBaseURL();
ingo@521: imgUrl += "chart";
ingo@521: imgUrl += "?uuid=" + collection.identifier();
ingo@521: imgUrl += "&type=" + mode.getName();
ingo@521: imgUrl += "&server=" + config.getServerUrl();
ingo@521: imgUrl += "&locale=" + config.getLocale();
ingo@521: imgUrl += "×tamp=" + new Date().getTime();
ingo@521: imgUrl += "&width=" + Integer.toString(width);
ingo@521: imgUrl += "&height=" + Integer.toString(height);
ingo@521:
ingo@542: if (xrange != null) {
ingo@542: GWT.log("Zoom to xrange.");
ingo@542: imgUrl += "&minx=" + Double.toString(xrange[0]);
ingo@542: imgUrl += "&maxx=" + Double.toString(xrange[1]);
ingo@542: }
ingo@542:
ingo@542: if (yrange != null) {
ingo@542: GWT.log("Zoom to xrange.");
ingo@542: imgUrl += "&miny=" + Double.toString(yrange[0]);
ingo@542: imgUrl += "&maxy=" + Double.toString(yrange[1]);
ingo@542: }
ingo@542:
ingo@521: return imgUrl;
ingo@521: }
ingo@521: }
ingo@521: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :