GWT Google 图表增长但不缩小

GWT Google Charts grow but don't shrink

我正在使用 GWT(2.7 版)和 Google Charts JavaScript API 在 GWT 应用程序中绘制一系列图表。

我正在尝试在滚动面板中显示多个图表,右侧是数据部分。数据部分是固定宽度,包含图表的滚动面板应占据 window 宽度的其余部分。当 window 大小改变时,图表的大小应该改变。这是一张照片:

我大部分时间都在用这个。当我增加 window、 的大小时,图表会变大,但随着我减小 window![= 的大小,图表区域不会缩小19=]

我希望图表区域根据 window 的大小增减。现在增长部分有效,但收缩部分无效。

示例代码如下:

package com.example.gwtcharttest.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;


public class GwtChartTest implements EntryPoint {

    public void onModuleLoad() {

        final SimplePanel chartDivOne = new SimplePanel();
        chartDivOne.getElement().setId("chartDiv_1");
        chartDivOne.setHeight("300px");
        chartDivOne.setWidth("100%");

        final SimplePanel chartDivTwo = new SimplePanel();
        chartDivTwo.getElement().setId("chartDiv_2");
        chartDivTwo.setHeight("300px");
        chartDivTwo.setWidth("100%");

        final SimplePanel chartDivThree = new SimplePanel();
        chartDivThree.getElement().setId("chartDiv_3");
        chartDivThree.setHeight("300px");
        chartDivThree.setWidth("100%");

        VerticalPanel chartsPanel = new VerticalPanel();
        chartsPanel.setWidth("100%");
        chartsPanel.add(chartDivOne);
        chartsPanel.add(chartDivTwo);
        chartsPanel.add(chartDivThree);

        ScrollPanel chartsScrollPanel = new ScrollPanel(chartsPanel);

        DockLayoutPanel dlp = new DockLayoutPanel(Unit.PX);
        dlp.addEast(new Label("some data here"), 200);
        dlp.add(chartsScrollPanel);

        RootLayoutPanel.get().add(dlp);

        loadLibrary();

        Window.addResizeHandler(new ResizeHandler() {

            @Override
            public void onResize(ResizeEvent event) {
                drawChart("chartDiv_1");
                drawChart("chartDiv_2");
                drawChart("chartDiv_3");
            }
        });
    }

    private native void drawChart(String chartDivId)/*-{

          var data = $wnd.google.visualization.arrayToDataTable([
            ['City', '2010 Population',],
            ['New York City, NY', 8175000],
            ['Los Angeles, CA', 3792000],
            ['Chicago, IL', 2695000],
            ['Houston, TX', 2099000],
            ['Philadelphia, PA', 1526000]
          ]);

          var options = {
            title: 'Population of Largest U.S. Cities',

            hAxis: {
              title: 'Total Population',
              minValue: 0
            },
            vAxis: {
              title: 'City'
            }
          };

          var chart = new $wnd.google.visualization.ColumnChart($wnd.document.getElementById(chartDivId));
          chart.draw(data, options);
    }-*/;

    private native void loadLibrary()/*-{
        $wnd.google.charts.load('current', {
            packages : [ 'corechart' ]
        });
    }-*/;
}

这里是 html 文件。这里唯一需要注意的是,我在 head 部分包含了 Google 图表 JavaScript api:

<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="GwtChartTest.css">
    <title>GWT Chart Test</title>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript" language="javascript" src="gwtcharttest/gwtcharttest.nocache.js"></script>
  </head>

  <body>
  </body>
</html>

我了解到 ScrollPanel 从未减小其大小,即使其父 DockLayoutPanel 减小了大小。 我如何保证图表继续遵守 window 的大小,即使它减小了?

您可能需要将绘制图表的调用包装在 Scheduler 中。它们是在 Window > DockLayoutPanel > ScrollPanel 链有机会调整大小之前制作的。

或者,如果您只支持现代浏览器,我建议您改用 flexbox 布局模型,因为它使用本机浏览器重排而不是 JavaScript,因此更加高效和灵活(双关语意)。

编辑:

解决方案是用 FlowPanel 替换 VerticalPanel。

VerticalPanel 扩展了 CellPanel,后者解析为 HTML 中的 table。它具有与简单 div 不同的布局机制,通常应避免使用它,除非有非常具体的理由使用它并且没有基于 CSS 的解决方案可用。一般来说,出于性能原因和获得 predictable 一致的行为,我们应该尽可能地接近浏览器原生布局机制(FlowPanel、HTMLPanel、CSS)。一旦混合了本机和 JS 强制布局,您必须非常小心事件的顺序,因为 JS 代码所做的更改(例如调整元素的大小)可能会强制浏览器再次 reflow/re-render 整个页面,这可能通过在许多小部件(DockLayoutPanel、ScrollPanel 等)中实现的 ProvidesResize/RequiresResize 机制反过来导致更多的 JS 更改