swimlane / ngx-charts

:bar_chart: Declarative Charting Framework for Angular
https://swimlane.github.io/ngx-charts/
MIT License
4.29k stars 1.15k forks source link

How can I make my ngx-line-chart responsive? #1096

Open nikigarg97 opened 5 years ago

nikigarg97 commented 5 years ago

I have doing Responsive like that:-

onResize(event) method: // view is the variable used to change the chart size (Ex: view = [width, height])

onResize(event) { this.view = [event.target.innerWidth / 1.35, 400]; }

.html <ngx-charts-line-chart (window:resize)="onResize($event)" [scheme]="colorScheme" [results]="multi" [xAxis]="showXAxis" [yAxis]="showYAxis" [showXAxisLabel]="showXAxisLabel" [showYAxisLabel]="showYAxisLabel" [xAxisLabel]="xAxisLabel" [yAxisLabel]="yAxisLabel" [view]="view">

In mobile device not work

Abdullah0991 commented 5 years ago

Have you tried to set the [view] = "" ?

nikigarg97 commented 5 years ago

yes I tried to set [view] = "" then ngx-charts show like that :-

On Tue, Feb 26, 2019 at 7:40 PM AK-47 notifications@github.com wrote:

Have you tried to set the [view] = "" ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/swimlane/ngx-charts/issues/1096#issuecomment-467452180, or mute the thread https://github.com/notifications/unsubscribe-auth/AtDtBdoTISrEY33bgOhj8P_30zrq31FIks5vRUBJgaJpZM4aeR0O .

cole21771 commented 5 years ago

If you don't set a view, it will default to whatever it's parent container's size is. You just need to make sure the parent container has a specific width and height set.

sanisoclem commented 5 years ago

Is it possible to just set an aspect ratio and fill up the container even if doesn't have a fix width set? I have a container that has a fixed width in large screens but percentage widths in smaller ones (100% on mobile).

if I dont set the parent dimensions at all, it seems to just pick an arbitrary size and overflows out of the container. Since I can't set the width, I tried setting height/min-height but it just uses this value whatever the width is. This is especially problematic when the width is big, because I end up with a small pie chart with lots of space on either side.

As a workaround, i created a script that removes the width, height and style attributes and add a viewBox instead with these values. This works well for pie charts because they sort of scale like images and I dont mind the text scaling with it. But its a ugly hack with setTimeout and ElementRefs. There must be a better way to do this.

cole21771 commented 5 years ago

The aspect ratio is your job to figure out in css. You don't need to give the parent a "fixed" width, but just a defined width. So 100% counts as defined and will fill up the space the parent container has.

If you don't give the parents a width/height, the chart will default to 600 x 400 iirc.

sanisoclem commented 5 years ago

The aspect ratio is your job to figure out in css.

Now that never occurred to me. I'm gonna give that a try with this technique: https://stackoverflow.com/questions/1495407/maintain-the-aspect-ratio-of-a-div-with-css

Thanks!

MohamedFarid648 commented 4 years ago

View =[innerWidth/1.2, 400]; check this link please: https://stackoverflow.com/questions/52552815/how-can-i-make-my-ngx-line-chart-responsive

parthdevloper commented 4 years ago

Here is a solution based on wrapper component.html

<div #ContainerRef class="card-body">
  <ngx-charts-bar-vertical-stacked
      [view]="[ContainerRef.offsetWidth, 400]"
      [scheme]="verticalBarChartColor"
      [results]="_vertaclBarChartData">  
  </ngx-charts-bar-vertical-stacked>
</div>
gitalvininfo commented 4 years ago

Hi, I know I'm a bit late but here is my approach when making the chart responsive.

HTML

<div class="w-100 h-300p" #resizedDiv>
    <ngx-charts-line-chart [timeline]="true" [results]="bitcoinData" [xAxis]="true" [scheme]="colorScheme"
        [showGridLines]="true" [xAxis]="true" [yAxis]="true">
    </ngx-charts-line-chart>
</div>

CSS

  1. w-100 = width:100%
  2. h-300p = 300px
  @ViewChild('resizedDiv') resizedDiv: ElementRef;
  public previousWidthOfResizedDiv: number = 0;

  ngAfterViewChecked() {
    if (this.previousWidthOfResizedDiv != this.resizedDiv.nativeElement.clientWidth) {
      //render your data for the chart using spread operator 
      this.bitcoinData = [...this.bitcoinData]
    }
    this.previousWidthOfResizedDiv = this.resizedDiv.nativeElement.clientWidth;
  }

What I'm doing is, im making a reference in the view using the #resizedDiv and in component I'm calling it using ViewChild reference and in the lifecycle hook ngAfterViewChecked(), I need to update the width of the chart container.

Thanks...

Clashsoft commented 2 years ago

Have you tried to set the [view] = "" ?

Since view: [number, number] this will produce a compiler error:

TS2322: Type 'undefined' is not assignable to type '[number, number]'.

HS-Joe commented 2 years ago

[view]="[100, 150]" works

simonlurie1 commented 2 years ago

[view]="[100, 150]" works

the question was todo it reponsive! and not hard coded values

rooby commented 1 year ago

Here is a solution based on wrapper component.html

<div #ContainerRef class="card-body">
  <ngx-charts-bar-vertical-stacked
      [view]="[ContainerRef.offsetWidth, 400]"
      [scheme]="verticalBarChartColor"
      [results]="_vertaclBarChartData">  
  </ngx-charts-bar-vertical-stacked>
</div>

Good idea, however watch out for ExpressionChangedAfterItHasBeenCheckedError errors. An example is if the rendering of the chart causes a scrollbar to appear on the parent, then the width of the container will change and cause ExpressionChangedAfterItHasBeenCheckedError.