GoogleWebComponents / google-chart

Google Charts API web components
https://www.webcomponents.org/element/@google-web-components/google-chart/elements/google-chart
Apache License 2.0
358 stars 130 forks source link

redraw() doesn't respect changes in containing div's size. #157

Closed runia1 closed 3 years ago

runia1 commented 8 years ago

I set a listener for window resize events. When fired I call redraw() in my google-chart, as I want my chart to be responsive. to make my chart match the width of it's containing div when redrawn I have the following css:

google-chart {
    width: 100%;
}

This works when starting from a small width and getting bigger. The window resizes and the graph is redraw with the appropriate width. However when going from big to small, it will not redraw smaller to what the new 100% if containing div is, so I end up with an overflow of the containing div.

This is very strange behavior and I can only assume it's a bug as the redraw is getting called and it will redraw it larger than current but not smaller.

wesalvaro commented 8 years ago

Yeah, this has been a rather annoying issue for me, as well. The last time I looked into it for a minute, it appeared to be a non-trivial fix but it's definitely possible.

ArthurJahn commented 7 years ago

Any updates here? I'm having problems with this redraw issue.

jukbot commented 6 years ago

For my workaround in Polymer, I'm using iron-resize behavior to detect the size of the chart container.

 class ViewStatistic extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior],
      Polymer.Element) {
      static get is() {
        return 'view-statistic';
      }

   connectedCallback() {
        super.connectedCallback();
        requestAnimationFrame(this._installListeners.bind(this))
      }

      _installListeners() {
         this.addEventListener('iron-resize', this._setChartSize.bind(this))
      }

      _setChartSize() {
        this.width = this.$.chartContainer.offsetWidth;
        this.height = this.$.chartContainer.offsetHeight;
        if (this.width > 0) {
          this.columnOptions = {
            width: this.width - 40,
            height: 500,
          }
          this.$.columnChart.redraw()
        }
      }
}
  customElements.define(ViewDashboardStatistic.is, ViewDashboardStatistic);
bmz1 commented 3 years ago

Any updates?

rslawik commented 3 years ago

This sounds like a problem with charting library itself. It will be harder to fix.

Do you have a repro / demo for this? That would help me investigate. And also help me see how you expect it to work, because for example: what should happen when CSS says 100% but chart options say 500px?

Thanks!

bmz1 commented 3 years ago

https://codepen.io/flopreynat/pen/BfLkA I try to achieve something similar (like the codepen) with the google-charts wc, but it's not redrawing the svgs somehow. It only works if I specify a width in pixels and I change that width with media-queries for an example. So there is no dynamic resize.

import { LitElement, html, css } from 'lit-element';

import '@google-web-components/google-chart';

export default class BaseChart extends LitElement {

  static get styles() {
    return css`
      .chart-wrapper {
        position: relative;
        display: flex;
        justify-content: center;
      }

      google-chart {
        width: 100%;
      }
    `;
  }

  constructor() {
    super();
    this.data = [];
    this.title = '';
    window.addEventListener('resize', this.redraw.bind(this));
  }

  redraw() {
    const chart = this.shadowRoot.querySelector('google-chart');
    if (chart) {
      chart.redraw(); // it gets called, but nothing happens
    }

  render() {
    ....
    }
  }
rslawik commented 3 years ago

Thanks for the demo @bmz1 - very helpful. I edited it to use <google-chart> and it works for me. I created a simplified version https://jsbin.com/bedaqalele/edit?html,output where you can use the slider to set the size for the chart.

Is the simplified version different from your setup? Could it be that width: 100% cannot be measured because it is in a flex container that expects child intrinsic size?

bmz1 commented 3 years ago

@rslawik Thank you for your response. First, I thought it has something to do with shadowRoot, but I also made a demo with LitElement https://jsbin.com/vizuniqacu/edit?html,output and redrawing is working fine.

After that I found out that the flex container was the problem. Since I removed flex, it is working fine. This could be OP's problem as well.

rslawik commented 3 years ago

Great that you have solved it. I will close this issue then.