Búsqueda de sitios web

typescript - Los estilos en el componente para D3.js no se muestran en Angular 2


Estoy usando Angular 2 y D3.js. Quiero mostrar un rectángulo rojo.

Solo funciona si pongo los estilos en el archivo style.css. Comprueba este plunkr

Cuando pongo mis estilos en el componente styles: [], no funciona. Revisa este plunkr

¿Cómo hacer que funcione cuando uso el componente styles: []? Gracias

ACTUALIZACIÓN: @micronyks proporciona una solución, pero hace que los estilos en el componente sean globales, básicamente no hay diferencia con escribir en el archivo style.css. En este plunkr, se muestra que el estilo en un componente sobrescribirá los estilos de otro componente, por lo que no se pueden mostrar rectángulos verdes y rojos.

ACTUALIZACIÓN 2: ¡La forma de @Günter resuelve perfectamente este problema! Solo un recordatorio, para la forma de Günter: se necesita al menos Angular beta 10. (Mis otros plunkrs usan Angular beta 8) La demostración funcionando para un rectángulo verde y uno rojo usando Angular beta 12 está aquí.

import {Component} from 'angular2/core'
@Component({
  selector: 'my-app',
  providers: [],
   styles: [`
    /*this does not work*/
    .bar {
      fill: red;
    }
  `],
  template: `
    <div>
      <svg class="chart"></svg>
    </div>
  `,
  directives: []
})
export class App {
  constructor() {}

  ngOnInit() {
    this.draw();
  }

  draw() {
    let data = [{name: 'A', value: 1}];
    let width = 400, height = 200;

    let x = d3.scale.ordinal().rangeRoundBands([0, width]);
    let y = d3.scale.linear().range([height, 0]);

    let chart = d3.select(".chart")
      .attr("width", width)
      .attr("height", height)
      .append("g");

    x.domain(data.map(function(d) { return d.name; }));
    y.domain([0, d3.max(data, function(d) { return d.value; })]);

    chart.selectAll(".bar")
      .data(data)
      .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.name); })
      .attr("y", function(d) { return y(d.value); })
      .attr("height", function(d) { return height - y(d.value); })
      .attr("width", x.rangeBand());
  }
}

Respuesta #1

Actualizar

Angular y SASS acordaron apoyar ::ng-deep (en lugar de >>> o /deep/) hace un tiempo, hasta que ::slotted o lo que sea que llegue a los estándares del navegador esté disponible en todos los navegadores.

ViewEncapsulation.Emulado (predeterminado)

Eso es por diseño. Angular agrega nombres de clase únicos a los componentes y reescribe los estilos añadidos para que solo se apliquen a los componentes donde fueron añadidos.

D3 genera HTML dinámicamente sin el conocimiento de Angular y Angular no puede aplicar las clases para que los estilos se apliquen en el HTML generado.

Si agregas los estilos en el archivo HTML del punto de entrada, Angular tampoco reescribe los estilos y las clases auxiliares agregadas no surten efecto.

ViewEncapsulation.None

Con encapsulation: ViewEncapsulation.None Angular no realiza esta reescritura, por lo tanto el resultado es similar a agregar el HTML en el index.html.

«Que atraviesa la sombra»

Alternativamente, puedes usar los combinadores CSS de penetración de sombras recientemente introducidos >>>, /deep/ y ::shadow (::shadow simplemente se reemplaza por un y por lo tanto es muy limitado). Consulta también https://stackoverflow.com/a/36225709/217408 y el Plunker

:host /deep/ div {
  color: red;
}

SASS

/deep/ funciona bien con SASS, pero el alias >>> no.

Los combinadores CSS que atraviesan sombras son reescritos por Angular y no necesitan ser soportados por los navegadores. Chrome los soportó por un tiempo pero están obsoletos; pero como se dijo, eso no importa, porque Angular los reescribe para usar su emulación de encapsulación.

ViewEncapsulation.Native

Angular no admite ninguna forma de estilizar tales componentes desde el exterior. Solo si el navegador proporciona soporte como las variables CSS, entonces se pueden usar.

Respuesta #2

ViewEncapsulation solucionará tu problema.

import {Component,ViewEncapsulation} from 'angular2/core'

@Component({
  selector: 'my-app',
  encapsulation: ViewEncapsulation.None,
  providers: [],
   styles: [`
     .bar {
       fill: red;
    }
  `],
  template: `
    <div>
      <svg class="chart"></svg>
    </div>
  `,
  directives: []
})

Artículos relacionados