0

I am in the process of porting my ionic 3 app to ionic 4. I use D3 for the creation of a meter.

None of the styling I have in my .scss file is working with the meter. The meter shape is correct but filled with black.

To create a simpler test cast I create a box directly in html with svg. I use a .scss class box to fill the color blue.

I also create a circle with D3 and use the style attribute to fill the circle with the color red.

I finally create another circle with D3 and use the .attr('class', '') to fill in the circle with the color green.

Here is the html:

<ion-header>
  <ion-toolbar>
    <ion-title>meter</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <svg width="50" height="50">
    <rect x="0" y="0" width="50" height="50" class="box" />
  </svg>


  <div id="cir-1"></div>

  <div id="cir-2"></div>

</ion-content>

Here is the code:

const circleOne = d3.select('#cir-1')
  .append('svg')
  .attr('width', 100)
  .attr('height', 100);

circleOne.append('circle')
  .style('stroke', 'gray')
  .style('fill', 'red')
  .attr('r', 40)
  .attr('cx', 50)
  .attr('cy', 50);

const circleTwo = d3.select('#cir-2')
  .append('svg')
  .attr('width', 150)
  .attr('height', 150);

circleTwo.append('circle')
  .attr('class', 'circle-style')
  .attr('r', 40)
  .attr('cx', 100)
  .attr('cy', 100);

Here is the .scss:

  .circle-style {
    fill: green;
  }

  .box {
    fill: blue;
  }

The first two cases work, but the last case (which I am trying to get to work) where I use .attr('class', '') does not. It is black instead of green.

Here is a screenshot showing that the class was attached to the circle.

enter image description here

Any help for be greatly appreciated.

Thanks,

Brent

brent
  • 502
  • 1
  • 7
  • 23
  • your code is just working: https://codepen.io/ya3ya6/pen/PrYrbK – yaya Jun 10 '19 at 17:59
  • Thank you for looking into this. I am quite confused. I am not sure what is different in our environments. The code is exactly the same. Here is my ionic info - so it looks like we are using the same version of Ionic: Ionic CLI : 5.0.1 (/Users/.nvm/versions/node/v12.3.1/lib/node_modules/ionic) Ionic Framework : @ionic/angular 4.4.2 @angular-devkit/build-angular : 0.13.9 @angular-devkit/schematics : 7.3.9 @angular/cli : 7.3.9 @ionic/angular-toolkit : 1.5.1 – brent Jun 11 '19 at 12:18
  • 1
    I just performed the following steps. Maybe you can see something I did wrong. 1) ionic start d3js blank 2) npm install d3 --save 3) copied what you have in ion-contents into the home pages ion-contents 4) copied what you have in your .css to the home.scss 5) copied what you have in js to home.pages ngOnInit(). When I run ionic serve I get what I have shown in my first comment with the bottom circle black, not green. My package.json is using "d3": "^5.9.2" . Any ideas as to why your codepen works and my ionic project does not? – brent Jun 11 '19 at 12:38
  • What is interesting is looking in chrome://inspect I can see that the second circle has the correct class on it. It is just not using it. – brent Jun 11 '19 at 12:42
  • in angular in nodejs, Scss rules wont apply to dynamic added elements (because of Encapsulation). you can see it here: https://github.com/angular/angular/issues/7845 @SergeyRudenko suggested an answer. you can also use `::ng-deep .circle-style` as well. (https://stackoverflow.com/a/36265072/4718434) – yaya Jun 11 '19 at 14:19

1 Answers1

1

Try to set ViewEncapsulation to None in your component using D3. Seems like Angular is not playing nicely with D3 without it.

Import ViewEncapsulation:

import { ViewEncapsulation } from '@angular/core';

Set it to None inside Component decorator:

 @Component({
      selector: 'my-chart',
      templateUrl: './my-chart.component.html',
      styleUrls: ['./my-chart.component.scss'],
      encapsulation: ViewEncapsulation.None
 })
Sergey Rudenko
  • 8,809
  • 2
  • 24
  • 51