ingo@521: package de.intevation.flys.client.client.ui.chart;
ingo@521:
ingo@521: import java.util.Date;
ingo@549: import java.util.HashMap;
ingo@549: import java.util.Map;
ingo@1280: import java.util.Stack;
ingo@521:
ingo@521: import com.google.gwt.core.client.GWT;
ingo@538: import com.google.gwt.user.client.rpc.AsyncCallback;
ingo@521:
ingo@610: import com.smartgwt.client.types.Overflow;
ingo@610:
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@552: import de.intevation.flys.client.shared.model.Axis;
ingo@552: import de.intevation.flys.client.shared.model.ChartInfo;
ingo@521: import de.intevation.flys.client.shared.model.Collection;
ingo@521: import de.intevation.flys.client.shared.model.OutputMode;
ingo@1280: import de.intevation.flys.client.shared.model.ZoomObj;
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@552: import de.intevation.flys.client.client.event.PanEvent;
ingo@552: import de.intevation.flys.client.client.event.PanHandler;
felix@858: import de.intevation.flys.client.client.event.RedrawRequestHandler;
ingo@911: import de.intevation.flys.client.client.event.RedrawRequestEvent;
ingo@911: import de.intevation.flys.client.client.event.RedrawRequestEvent.Type;
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: /**
felix@1545: * Tab representing and showing one Chart-output.
felix@1545: *
ingo@521: * @author Ingo Weinzierl
ingo@521: */
ingo@531: public class ChartOutputTab
ingo@531: extends OutputTab
felix@855: implements ResizedHandler,
felix@855: OutputParameterChangeHandler,
felix@855: ZoomHandler,
felix@858: PanHandler,
felix@858: RedrawRequestHandler
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:
felix@855: /** The service that is used to fetch chart information. */
ingo@538: protected ChartInfoServiceAsync info = GWT.create(ChartInfoService.class);
ingo@538:
ingo@552: /** The ChartInfo object that provides information about the current
felix@855: * chart. */
ingo@552: protected ChartInfo chartInfo;
ingo@552:
felix@855: /** Transformer used to transform image pixels into chart coordinates. */
ingo@561: protected Transform2D[] transformer;
ingo@538:
ingo@538: /** The collection view.*/
ingo@538: protected CollectionView view;
ingo@538:
felix@1579: /** The ThemePanel to expose control over themes (facettes). */
ingo@911: protected ChartThemePanel ctp;
ingo@911:
felix@855: /** The canvas that wraps the chart toolbar. */
ingo@521: protected Canvas tbarPanel;
ingo@521:
felix@855: /** The canvas that wraps the theme editor. */
ingo@521: protected Canvas left;
ingo@521:
felix@855: /** The canvas that wraps the chart. */
ingo@521: protected Canvas right;
ingo@521:
ingo@610: protected Img chart;
ingo@610:
felix@855: /** Chart zoom options. */
ingo@561: protected int[] xrange;
ingo@561: protected int[] yrange;
ingo@561:
felix@1579: /** Stack of ZoomObj to allow 'redo last zoom'-kind of actions. */
ingo@1280: protected Stack zoomStack;
ingo@1597: protected Number[] zoom;
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.
felix@858: * @param collectionView The shown collection.
ingo@521: */
ingo@521: public ChartOutputTab(
sascha@615: String title,
ingo@521: Collection collection,
ingo@521: OutputMode mode,
ingo@521: CollectionView collectionView
ingo@521: ){
ingo@1364: super(title, collection, collectionView, mode);
ingo@521:
ingo@538: view = collectionView;
ingo@521: left = new Canvas();
ingo@521: right = new Canvas();
ingo@561: xrange = new int[2];
ingo@561: yrange = new int[2];
ingo@1280: zoomStack = new Stack();
ingo@521:
ingo@1597: zoom = new Number[] {
ingo@1597: new Integer(0), new Integer(1),
ingo@1597: new Integer(0), new Integer(1) };
ingo@1597:
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:
felix@858: // Output "cross_section" needs slightly modified ThemePanel
felix@858: // (with action buttons).
felix@858: if (mode.getName().equals("cross_section")) {
felix@1555: ctp = new CrossSectionChartThemePanel(mode, this.view);
felix@858: }
felix@858: else {
felix@1555: ctp = new ChartThemePanel(mode, this.view);
felix@858: }
felix@858:
felix@859: ctp.addRedrawRequestHandler(this);
ingo@531: ctp.addOutputParameterChangeHandler(this);
ingo@531:
ingo@610: chart = createChartImg();
ingo@610: right.addChild(chart);
ingo@610: right.setOverflow(Overflow.HIDDEN);
ingo@610: //right.addChild(createChartPanel());
ingo@531: left.addChild(ctp);
ingo@521:
felix@1545: tbarPanel = new ChartToolbar(this);
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@561: updateChartInfo();
ingo@531: }
ingo@531:
ingo@531:
felix@1550: /** For RESET type of events, just reset the ranges, otherwise do a
felix@1550: * complete refresh of panel, info and collection. */
ingo@911: public void onRedrawRequest(RedrawRequestEvent event) {
ingo@911: if (event.getType() == Type.RESET) {
ingo@911: resetRanges();
ingo@911: }
ingo@911: else {
ingo@911: ctp.updateCollection();
ingo@911: updateChartPanel();
ingo@911: updateChartInfo();
ingo@911: }
felix@858: }
felix@858:
felix@858:
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) {
raimund@2477: updateChartInfo();
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@1280: zoomStack.push(new ZoomObj(zoom[0], zoom[1], zoom[2], zoom[3]));
ingo@1280:
ingo@561: xrange[0] = evt.getStartX();
ingo@561: xrange[1] = evt.getEndX();
ingo@561: yrange[0] = evt.getStartY();
ingo@561: yrange[1] = evt.getEndY();
ingo@541:
ingo@561: xrange[0] = xrange[0] < xrange[1] ? xrange[0] : xrange[1];
ingo@561: yrange[0] = yrange[0] < yrange[1] ? yrange[0] : yrange[1];
ingo@541:
ingo@561: translateCoordinates();
ingo@561:
ingo@561: updateChartInfo();
ingo@542: updateChartPanel();
ingo@541: }
ingo@541:
ingo@541:
ingo@1597: protected Number[] translateCoordinates() {
ingo@561: if (xrange == null || (xrange[0] == 0 && xrange[1] == 0)) {
ingo@561: zoom[0] = 0d;
ingo@561: zoom[1] = 1d;
ingo@561: }
ingo@561: else {
ingo@561: translateXCoordinates();
ingo@561: }
ingo@561:
ingo@561: if (yrange == null || (yrange[0] == 0 && yrange[1] == 0)) {
ingo@561: zoom[2] = 0d;
ingo@561: zoom[3] = 1d;
ingo@561: }
ingo@561: else {
ingo@561: translateYCoordinates();
ingo@561: }
ingo@561:
ingo@561: return zoom;
ingo@561: }
ingo@561:
ingo@561:
ingo@561: protected void translateXCoordinates() {
ingo@561: Axis xAxis = chartInfo.getXAxis(0);
ingo@561:
ingo@1597: Number xmin = xAxis.getMin();
ingo@1597: Number xmax = xAxis.getMax();
ingo@1597: Number xRange = subtract(xmax, xmin);
ingo@561:
ingo@561: Transform2D transformer = getTransformer(0);
ingo@561:
ingo@561: double[] start = transformer.transform(xrange[0], yrange[0]);
ingo@561: double[] end = transformer.transform(xrange[1], yrange[1]);
ingo@561:
ingo@1597: zoom[0] = divide(subtract(start[0], xmin), xRange);
ingo@1597: zoom[1] = divide(subtract(end[0], xmin), xRange);
ingo@561: }
ingo@561:
ingo@561:
ingo@561: protected void translateYCoordinates() {
ingo@561: Axis yAxis = chartInfo.getYAxis(0);
ingo@561:
ingo@1597: Number ymin = yAxis.getMin();
ingo@1597: Number ymax = yAxis.getMax();
ingo@1597: Number yRange = subtract(ymax, ymin);
ingo@561:
ingo@561: Transform2D transformer = getTransformer(0);
ingo@561:
ingo@561: double[] start = transformer.transform(xrange[0], yrange[0]);
ingo@561: double[] end = transformer.transform(xrange[1], yrange[1]);
ingo@561:
ingo@1597: zoom[2] = divide(subtract(start[1], ymin), yRange);
ingo@1597: zoom[3] = divide(subtract(end[1], ymin), yRange);
ingo@561: }
ingo@561:
ingo@561:
ingo@552: public void onPan(PanEvent event) {
ingo@561: if (chartInfo == null) {
sascha@555: return;
sascha@555: }
ingo@561:
ingo@552: int[] start = event.getStartPos();
ingo@552: int[] end = event.getEndPos();
ingo@552:
ingo@561: Transform2D t = getTransformer();
ingo@552:
ingo@561: double[] ts = t.transform(start[0], start[1]);
ingo@561: double[] tt = t.transform(end[0], end[1]);
ingo@552:
ingo@561: double diffX = ts[0] - tt[0];
ingo@561: double diffY = ts[1] - tt[1];
ingo@561:
ingo@552: Axis xAxis = chartInfo.getXAxis(0);
ingo@552: Axis yAxis = chartInfo.getYAxis(0);
ingo@552:
ingo@1597: Number[] x = panAxis(xAxis, diffX);
ingo@1597: Number[] y = panAxis(yAxis, diffY);
ingo@552:
ingo@561: zoom[0] = x[0];
ingo@561: zoom[1] = x[1];
ingo@561: zoom[2] = y[0];
ingo@561: zoom[3] = y[1];
ingo@561:
ingo@561: updateChartInfo();
ingo@552: updateChartPanel();
ingo@552: }
ingo@552:
ingo@552:
ingo@1597: protected Number[] panAxis(Axis axis, double diff) {
ingo@1597: Number min = axis.getFrom();
ingo@1597: Number max = axis.getTo();
ingo@561:
ingo@1597: min = add(min, diff);
ingo@1597: max = add(max, diff);
ingo@561:
ingo@561: return computeZoom(axis, min, max);
ingo@561: }
ingo@561:
ingo@561:
ingo@543: public void resetRanges() {
ingo@1281: zoomStack.push(new ZoomObj(zoom[0], zoom[1], zoom[2], zoom[3]));
ingo@1281:
ingo@561: zoom[0] = 0d;
ingo@561: zoom[1] = 1d;
ingo@561: zoom[2] = 0d;
ingo@561: zoom[3] = 1d;
ingo@543:
ingo@561: updateChartInfo();
ingo@543: updateChartPanel();
ingo@543: }
ingo@543:
ingo@543:
ingo@541: /**
ingo@1281: * This method zooms the current chart out by a given factor.
ingo@1281: *
ingo@1281: * @param factor The factor should be between 0-100.
ingo@1281: */
ingo@1281: public void zoomOut(int factor) {
ingo@1281: if (factor < 0 || factor > 100 || chartInfo == null) {
ingo@1281: return;
ingo@1281: }
ingo@1281:
ingo@1281: zoomStack.push(new ZoomObj(zoom[0], zoom[1], zoom[2], zoom[3]));
ingo@1281:
ingo@1281: Axis xAxis = chartInfo.getXAxis(0);
ingo@1281: Axis yAxis = chartInfo.getYAxis(0);
ingo@1281:
ingo@1597: Number[] x = zoomAxis(xAxis, factor);
ingo@1597: Number[] y = zoomAxis(yAxis, factor);
ingo@1281:
ingo@1281: zoom[0] = x[0];
ingo@1281: zoom[1] = x[1];
ingo@1282: zoom[2] = y[0];
ingo@1281: zoom[3] = y[1];
ingo@1281:
ingo@1281: updateChartInfo();
ingo@1281: updateChartPanel();
ingo@1281: }
ingo@1281:
ingo@1281:
ingo@1281: /**
felix@2542: * This method is used to zoom out. Zooming out is realized with a stacked
ingo@1280: * logic. Initially, you cannot zoom out. For each time you start a zoom-in
ingo@1280: * action, the extent of the chart is stored and pushed onto a stack. A
felix@2542: * zoom-out will now lead you to the last extent that is popped from stack.
ingo@544: */
ingo@1280: public void zoomOut() {
ingo@1280: if (!zoomStack.empty()) {
ingo@1280: zoom = zoomStack.pop().getZoom();
ingo@548:
ingo@1280: updateChartInfo();
ingo@1280: updateChartPanel();
ingo@1280: }
ingo@544: }
ingo@544:
ingo@544:
ingo@1597: public Number[] zoomAxis(Axis axis, int factor) {
ingo@1282: GWT.log("Prepare Axis for zooming (factor: " + factor + ")");
ingo@561:
ingo@1597: Number min = axis.getMin();
ingo@1597: Number max = axis.getMax();
ingo@1597: Number range = isBigger(max, min) ? subtract(max, min) : subtract(min, max);
ingo@561:
ingo@1597: Number curFrom = axis.getFrom();
ingo@1597: Number curTo = axis.getTo();
ingo@561:
ingo@1597: Number diff = isBigger(curTo, curFrom)
ingo@1597: ? subtract(curTo, curFrom)
ingo@1597: : subtract(curFrom, curTo);
ingo@1282:
ingo@1282: GWT.log(" max from : " + min);
ingo@1282: GWT.log(" max to : " + max);
ingo@1282: GWT.log(" max range : " + range);
ingo@1282: GWT.log(" current from: " + curFrom);
ingo@1282: GWT.log(" current to : " + curTo);
ingo@1282: GWT.log(" current diff: " + diff);
ingo@1282:
ingo@1597: Number newFrom = subtract(curFrom, divide(multi(diff, factor), 100));
ingo@1597: Number newTo = add(curTo, divide(multi(diff, factor), 100));
ingo@1282:
ingo@1282: GWT.log(" new from: " + newFrom);
ingo@1282: GWT.log(" new to : " + newTo);
ingo@1282:
ingo@1597: return new Number[] {
ingo@1597: divide(subtract(newFrom, min), range),
ingo@1597: divide(subtract(newTo, min), range)
ingo@1282: };
ingo@561: }
ingo@561:
ingo@561:
ingo@1597: public static Number[] computeZoom(Axis axis, Number min, Number max) {
ingo@1597: Number[] zoom = new Number[2];
ingo@561:
ingo@1597: Number absMin = axis.getMin();
ingo@1597: Number absMax = axis.getMax();
ingo@1597: Number diff = isBigger(absMax, absMin)
ingo@1597: ? subtract(absMax, absMin)
ingo@1597: : subtract(absMin, absMax);
ingo@561:
ingo@1597: zoom[0] = divide(subtract(min, absMin), diff);
ingo@1597: zoom[1] = divide(subtract(max, absMin), diff);
ingo@561:
ingo@561: return zoom;
ingo@561: }
ingo@561:
ingo@561:
felix@1551: /** Get Collection from ChartThemePanel. .*/
felix@1551: public Collection getCtpCollection() {
felix@1551: return this.ctp.getCollection();
felix@1551: }
felix@1551:
felix@1551:
ingo@544: /**
ingo@538: * Updates the Transform2D object using the chart info service.
ingo@538: */
ingo@561: public void updateChartInfo() {
ingo@538: Config config = Config.getInstance();
ingo@538: String locale = config.getLocale();
ingo@538:
ingo@538: info.getChartInfo(
ingo@538: view.getCollection(),
ingo@538: locale,
ingo@538: mode.getName(),
ingo@549: getChartAttributes(),
ingo@552: new AsyncCallback() {
ingo@538: public void onFailure(Throwable caught) {
ingo@610: GWT.log("ChartInfo ERROR: " + caught.getMessage());
ingo@538: }
ingo@538:
ingo@552: public void onSuccess(ChartInfo chartInfo) {
ingo@552: setChartInfo(chartInfo);
ingo@538: }
ingo@538: });
ingo@538: }
ingo@538:
ingo@538:
ingo@531: public void updateChartPanel() {
ingo@610: int w = right.getWidth();
ingo@610: int h = right.getHeight();
ingo@521:
ingo@610: chart.setSrc(getImgUrl(w, h));
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@610: return right;
ingo@610: }
ingo@538:
ingo@538:
ingo@610: public Canvas getChartImg() {
ingo@610: return chart;
ingo@538: }
ingo@538:
ingo@538:
ingo@552: public ChartInfo getChartInfo() {
ingo@552: return chartInfo;
ingo@552: }
ingo@552:
ingo@552:
ingo@552: protected void setChartInfo(ChartInfo chartInfo) {
ingo@552: this.chartInfo = chartInfo;
ingo@561: }
ingo@561:
ingo@561:
ingo@561: public Transform2D getTransformer() {
ingo@561: if (chartInfo == null) {
ingo@561: return null;
ingo@561: }
ingo@561:
ingo@561: return chartInfo.getTransformer(0);
ingo@552: }
ingo@552:
ingo@552:
ingo@538: /**
ingo@538: * Returns the Transform2D object used to transform image coordinates into
ingo@538: * chart coordinates.
ingo@538: *
ingo@561: * @param pos The index of a specific transformer.
ingo@561: *
ingo@538: * @return the Transform2D object.
ingo@538: */
ingo@561: public Transform2D getTransformer(int pos) {
ingo@561: if (chartInfo == null) {
ingo@561: return null;
ingo@561: }
ingo@538:
ingo@561: return chartInfo.getTransformer(pos);
ingo@534: }
ingo@534:
ingo@534:
ingo@542: /**
felix@2542: * Returns the Transform2D count.
raimund@2477: *
raimund@2477: * @return the Transformer2D count
raimund@2477: */
raimund@2477: public int getTransformerCount() {
raimund@2477: if (chartInfo == null) {
raimund@2477: return 0;
raimund@2477: }
raimund@2477:
raimund@2477: return chartInfo.getTransformerCount();
raimund@2477: }
raimund@2477:
raimund@2477:
raimund@2477: /**
ingo@542: * Creates a new chart panel with default size.
ingo@542: *
ingo@542: * @return the created chart panel.
ingo@542: */
ingo@610: protected Img createChartImg() {
ingo@610: return createChartImg(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@610: protected Img createChartImg(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 += "&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@1597: Number[] zoom = getZoomValues();
ingo@542:
ingo@561: if (zoom != null) {
ingo@1597: if (zoom[0].intValue() != 0 || zoom[1].intValue() != 1) {
ingo@612: // a zoom range of 0-1 means displaying the whole range. In such
ingo@612: // case we don't need to zoom.
ingo@1597: imgUrl += "&minx=" + zoom[0];
ingo@1597: imgUrl += "&maxx=" + zoom[1];
ingo@612: }
ingo@2430:
ingo@1597: if (zoom[2].intValue() != 0 || zoom[3].intValue() != 1) {
ingo@612: // a zoom range of 0-1 means displaying the whole range. In such
ingo@612: // case we don't need to zoom.
ingo@1597: imgUrl += "&miny=" + zoom[2];
ingo@1597: imgUrl += "&maxy=" + zoom[3];
ingo@612: }
ingo@542: }
ingo@542:
ingo@521: return imgUrl;
ingo@521: }
ingo@549:
ingo@549:
felix@2542: /** Get link to export image in given dimension and format. */
ingo@1344: public String getExportUrl(int width, int height, String format) {
ingo@1344: String url = getImgUrl(width, height);
ingo@1344: url += "&format=" + format;
ingo@1344: url += "&export=true";
ingo@1344:
ingo@1344: return url;
ingo@1344: }
ingo@1344:
ingo@1344:
ingo@549: public Map getChartAttributes() {
ingo@549: Map attr = new HashMap();
ingo@549:
ingo@549: Canvas chart = getChartPanel();
felix@1453: attr.put("width", chart.getWidth().toString());
ingo@549: attr.put("height", chart.getHeight().toString());
ingo@549:
ingo@1597: Number[] zoom = getZoomValues();
ingo@549:
ingo@561: if (zoom != null) {
ingo@1597: if (zoom[0].intValue() != 0 || zoom[1].intValue() != 1) {
ingo@612: // a zoom range of 0-1 means displaying the whole range. In such
ingo@612: // case we don't need to zoom.
ingo@1597: attr.put("minx", zoom[0].toString());
ingo@1597: attr.put("maxx", zoom[1].toString());
ingo@612: }
ingo@1597: if (zoom[2].intValue() != 0 || zoom[3].intValue() != 1) {
ingo@612: // a zoom range of 0-1 means displaying the whole range. In such
ingo@612: // case we don't need to zoom.
ingo@1597: attr.put("miny", zoom[2].toString());
ingo@1597: attr.put("maxy", zoom[3].toString());
ingo@612: }
ingo@549: }
ingo@549:
ingo@549: return attr;
ingo@549: }
ingo@561:
ingo@561:
ingo@1597: protected Number[] getZoomValues() {
ingo@561: return zoom;
ingo@561: }
felix@1545:
felix@1545:
felix@1545: /** Return the 'parent' CollectionView. */
felix@1545: public CollectionView getView() {
felix@1545: return this.view;
felix@1545: }
ingo@1597:
ingo@1597:
ingo@1597: public static Number subtract(Number left, Number right) {
ingo@1597: if (left instanceof Double) {
ingo@1597: return new Double(left.doubleValue() - right.doubleValue());
ingo@1597: }
ingo@1597: else if (left instanceof Long) {
ingo@1597: return new Long(left.longValue() - right.longValue());
ingo@1597: }
ingo@1597: else {
ingo@1597: return new Integer(left.intValue() - right.intValue());
ingo@1597: }
ingo@1597: }
ingo@1597:
ingo@1597:
ingo@1597: public static Number add(Number left, Number right) {
ingo@1597: if (left instanceof Double) {
ingo@1597: return new Double(left.doubleValue() + right.doubleValue());
ingo@1597: }
ingo@1597: else if (left instanceof Long) {
ingo@1597: return new Long(left.longValue() + right.longValue());
ingo@1597: }
ingo@1597: else {
ingo@1597: return new Integer(left.intValue() + right.intValue());
ingo@1597: }
ingo@1597: }
ingo@1597:
ingo@1597:
ingo@1597: public static Number divide(Number left, Number right) {
ingo@1597: if (left instanceof Double) {
ingo@1597: return new Double(left.doubleValue() / right.doubleValue());
ingo@1597: }
ingo@1597: else if (left instanceof Long) {
ingo@1597: return new Long(left.longValue() / right.longValue());
ingo@1597: }
ingo@1597: else {
ingo@1597: return new Integer(left.intValue() / right.intValue());
ingo@1597: }
ingo@1597: }
ingo@1597:
ingo@1597:
ingo@1597: public static Number multi(Number left, Number right) {
ingo@1597: if (left instanceof Double) {
ingo@1597: return new Double(left.doubleValue() * right.doubleValue());
ingo@1597: }
ingo@1597: else if (left instanceof Long) {
ingo@1597: return new Long(left.longValue() * right.longValue());
ingo@1597: }
ingo@1597: else {
ingo@1597: return new Integer(left.intValue() * right.intValue());
ingo@1597: }
ingo@1597: }
ingo@1597:
ingo@1597:
ingo@1597: public static boolean isBigger(Number left, Number right) {
ingo@1597: if (left instanceof Double) {
ingo@1597: return left.doubleValue() > right.doubleValue();
ingo@1597: }
ingo@1597: else if (left instanceof Long) {
ingo@1597: return left.longValue() > right.longValue();
ingo@1597: }
ingo@1597: else {
ingo@1597: return left.intValue() > right.intValue();
ingo@1597: }
ingo@1597: }
ingo@521: }
ingo@521: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :