How to size a chartjs chart inside an ion-slide

I wish to use a chartjs chart (a pie chart and a line chart) within an ion-slide (will one chart in each slide), but am having problems getting the size correct. If I have the chart directly inside the ion-content, then all is fine, it draws the correct size and resizes when I change the orientation etc. However, as soon as I introduce the slide I get problems (I also want a select box above the chart)

As an example, I have the following markup…

	<ion-header>
	  <ion-navbar>
		<ion-title>Home</ion-title>
	  </ion-navbar>
	</ion-header>

	<ion-content  (window:resize)="onResize()">
	  <ion-slides pager>

	  <ion-slide >
		<ion-list id='select-list'>
			<ion-item>
			   <ion-label >select me</ion-label>
			   <ion-select  >
				  
			   </ion-select>
			</ion-item>
			<ion-item>  
			  <button ion-button >Click me</button>
			</ion-item>
		  </ion-list>
		<canvas style='height:100%;width:100%' (click)='pieCanvasClick($event)' #pie></canvas>
	  </ion-slide>

	  <ion-slide style="background-color: blue">
		<h2>Slide 2</h2>
	  </ion-slide>
	  
	</ion-slides> 
	</ion-content>

The code to create is…

	private createPie(): void {
		Chart.defaults.global.tooltips.enabled = false;
		Chart.defaults.global.legend.position = 'bottom';
		this.pieChart = new Chart(this.pieCanvas.nativeElement, {
		  type: 'pie',
		  options: {
			responsive: true,
			maintainAspectRatio: false,        
		  },
		  data: {
			labels: ["Red", "Blue", "Yellow" ],
			datasets: [{
			  label: '# of Votes',
			  data: [12, 19, 3 ],
			  backgroundColor: [
				"#FF6384",
				"#36A2EB",
				"#FFCE56"            
			  ],
			}]
		  }
		});
	  }

II have attempted to resize in the window.size event handler…

	public onResize() {     
		  let chart = this.content.getContentDimensions();
		  let h = chart.contentHeight - 100; 
		  let w = chart.contentWidth - 100;  
		  let el : HTMLCanvasElement = this.pieCanvas.nativeElement;
		  if (this.pieChart != undefined) {
			if (h < w) {
			  el.height = h - 130;
			  el.width = w - 130;
			} else {
			  el.height = h;
			  el.width = w;
			}        
		  }        
	  }

Below is how it looks (screen shot running in chrome)

And when I rotate it is even worse…

image

The code in the onResize() does not seem to do anything.

Does anyone have a way to use this chart inside the slide so I get all the resizing correct?

Thanks in advance for any suggestions.

I think I am close, but was a bit of trial and error. It seems to be the canvas that doesn’t size properly. Using the ion-grid and a padding div at the bottom seems to work, but not sure how correct the method here is (so may not work correct on other devices…

  <ion-header>
	   <ion-navbar>
		  <ion-title>Home</ion-title>
	   </ion-navbar>
	</ion-header>
	<ion-content  (window:resize)="onResize()">
	   <ion-slides pager>
		  <ion-slide >
			 <ion-grid style='height:100%'>
				<ion-row>
				   <ion-col>
					  <ion-list id='select-list'>
						 <ion-item>
							<ion-label >select me</ion-label>
							<ion-select >              
							</ion-select>
						 </ion-item>
						 <ion-item>  
							<button ion-button >Click me</button>
						 </ion-item>
					  </ion-list>
				   </ion-col>
				</ion-row>
				<ion-row style='flex-grow:4'>
				   <ion-col>
					  <canvas style='height:100%;background-color: greenyellow' (click)='pieCanvasClick($event)' #pie></canvas>
				   </ion-col>
				</ion-row>
				<ion-row style='flex-shrink:1'>
				   <ion-col>
					  <div style="height: 20px"></div>
				   </ion-col>
				</ion-row>
			 </ion-grid>
		  </ion-slide>
		  <ion-slide style="background-color: blue">
			 <h2>Slide 2</h2>
		  </ion-slide>
	   </ion-slides>
	</ion-content>

Results are…
image

Any better ideas are welcome?

[EDIT]

Forgot I also had to add

.slide-zoom {
height: 100%;
}

I haven’t used chart.js, but if you want your html to render well on multiple devices, it’s best to use out-of-the-box Ionic solutions, instead of changing a lot of CSS. The first thing I would try would be:

<ion-slide>
   <ion-item>
        <your-slide-component item-content></your-slide-component>
   </ion-item>
</ion-slide>

If you tell me what that does, I can be more precise. Note the item-content directive. It’s similar to ion-content but inside an ion-item.

Ok, yes I need something else. My layout did not work on the ios device (the canvas did not resize when I rotate to landscape).

I have modified to use ion-items as follows… (I’ve used a list since I have multiple items stacked…

[EDIT]
( I still need the .slide-zoom height otherwise the first item is not aligned to the top)

   .slide-zoom {
      height: 100%;
     }

[EDIT END]

<ion-content>
	  <ion-slides pager>
		<ion-slide >
		  <ion-list id='select-list'>
			
			  <ion-item>
				<ion-label >select me</ion-label>
				  <ion-select >              
				  </ion-select>
			  </ion-item>
			
				<ion-item>  
				  <button ion-button>Click me</button>
				</ion-item>

				<ion-item>
					<canvas style='height:100%;background-color: greenyellow' (click)='pieCanvasClick($event)' #pie></canvas>
				</ion-item>

			 </ion-list>
		</ion-slide>
		<ion-slide style="background-color: blue">
		  <h2>Slide 2</h2>
		</ion-slide>
	  </ion-slides>
	</ion-content>

In Chrome (ionic serve), this renders as below.

I’ve highlighted the item with the canvas, we can see this height is not stretching to fill the page

image

Interesting if I remove the 100% from the canvas, it gets closer.

Ie I now have

     <ion-item>
            <canvas style='background-color: greenyellow' (click)='pieCanvasClick($event)' #pie></canvas>
        </ion-item>

Looks ok in portrait, just not sizing in landscape

image

Have you tested it without a list and it works fine? I’d start there. You don’t necessarily need a list. To replicate your screenshot fullscreen, I’d use an ion-card with no padding.

Also, you aren’t using an item directive for your canvas. You need item-left, item-right or item-content per docs.

Ahh yes I did miss the item-content. So if I use the following…

		<ion-content>
	  <ion-slides pager>
		<ion-slide >           
		  <ion-item>
			<ion-label >select me</ion-label>
			<ion-select ></ion-select>
		  </ion-item>
		  <ion-item>
			<button ion-button>Click me</button>
		  </ion-item>
			  <ion-item>
			   <canvas item-content  style='background-color: greenyellow' (click)='pieCanvasClick($event)' #pie></canvas>
			 </ion-item>        
		</ion-slide>

It looks ok in portrait (except I want the select and button top aligned), but still does not size for landscape…


image

The problem seems to be because I want to stack a few items vertically. If I just use nothing but the canvas, it just displays in the middle. But if we want a couple of items on top, there just seem to be no way to control the vertical layout

The layout I am after here is just

select me

I thought a list would work here, but it doesn’t seem to :sob: