Soru D3.js bileşenindeki stiller, açısal 2'de gösterilmez


Angular 2 ve D3.js. kullanıyorum Kırmızı bir dikdörtgen göstermek istiyorum.

Sadece stilleri koyarsam çalışır style.css dosya. Kontrol bu plunkr

Stilleri bileşenime koyduğumda styles: [], İşe yaramıyor. Kontrol bu plunkr

Bileşeni kullandığımda nasıl çalışır styles: []? Teşekkürler

GÜNCELLEŞTİRME: @micronyks bir çözüm sağlar, ancak genel olarak bileşen içindeki stilleri yapar, temelde yazmada fark yoktur style.css dosya. İçinde bu plunkr, bir bileşendeki stilin başka bir bileşenin stillerini geçersiz kılacağını gösterir, bu nedenle yeşil ve kırmızı dikdörtgenler gösteremez.

GÜNCELLEME 2: @ Günter'ın yolu bu sorunu mükemmel bir şekilde çözdü! Günter'ın yolu için sadece bir hatırlatma: en azından Angular beta 10'a ihtiyaç duyar (Benim diğer plunkrs Angular beta 8'i kullanır) Angular beta 12'yi kullanarak yeşil ve bir kırmızı dikdörtgen için çalışma demosu İşte.

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());
  }
}

25
2018-03-25 05:28


Menşei


çalışıyor gibi görünüyor. Kontrol ettin mi? - micronyks
Sadece styes içinde çalışırken @micronyks style.css dosya. - Hongbo Miao
çalışıyor gibi görünüyor clipular.com/c/... - Cyril
@Cyril evet, o sadece styes çalışırken style.css dosya - Hongbo Miao


Cevaplar:


GörünümEncapsulation.Emulated (varsayılan)

Bu tasarım gereğidir. Açısal, bileşenlere özgü sınıf adlarını ekler ve eklenen stiller yalnızca eklendikleri bileşenlere uygulanacak şekilde yeniden yazar.

D3, Angulars bilgisi olmadan HTML'yi dinamik olarak oluşturur ve Açısal, stilleri oluşturulan HTML'de uygulamak için sınıfları uygulayamaz.

Stilleri giriş noktası HTML dosyasına eklerseniz, Angular ayrıca stilleri ve eklenen yardımcı sınıfların yeniden yazılmamasını da yazmaz.

ViewEncapsulation.None

İle encapsulation: ViewEncapsulation.None Açısal, bu yeniden yazma işlemini yapmaz, bu nedenle sonuç HTML’yi eklemeye benzer. index.html.

"Gölge-delme"

Alternatif olarak, yeni piyasaya sunulan gölge delici CSS kombinatorlerini kullanabilirsiniz. >>>, /deep/ ve ::shadow (::shadow sadece bir ile değiştirilir  ve dolayısıyla çok sınırlı). Ayrıca bakınız https://stackoverflow.com/a/36225709/217408 ve Plunker

: host / derin / div {      kırmızı renk;    }

SUKDÖ'nün

/deep/ SASS ama diğer adlarla iyi çalışıyor >>> yapmaz.

Gölge kıstırma CSS kombinatorleri Angular tarafından yeniden yazılır ve tarayıcılar tarafından desteklenmeleri gerekmez. Chrome onları bir süredir destekledi, ancak kullanımdan kaldırıldılar - ancak belirtildiği gibi bu önemli değil çünkü Açısal Kapsül onları enkapsülasyon öykünmesini kullanmaya yeniden yazar.

ViewEncapsulation.Native

Açısal, bu bileşenleri dışardan şekillendirmenin herhangi bir yolunu desteklemez. Sadece tarayıcı CSS değişkenleri gibi destek sağlıyorsa, bunlar kullanılabilir.


32
2018-03-25 18:49



Teşekkür ederim Günter! Şimdi mükemmel çalışıyor! Bu şeyler CSS kombinatorlerin delici gölge >>>, /deep/ ve ::shadow inanılmaz! Öğrenmem gereken birçok şey olduğunu hissediyorum. - Hongbo Miao
Diğer insanlar için sadece bir hatırlatmak: Bu şekilde, en azından Angular beta 10'a ihtiyaç duyar (Benim diğer plunkrs Angular beta 8'i kullanır) Angular beta 12 kullanarak yeşil ve bir kırmızı dikdörtgen için çalışma demosu İşte. - Hongbo Miao
Merhaba Günter, bu CSS kombinatoratörleri kullanımdan kaldırıldı mı? Evet ise, o zaman başka yollar? chromestatus.com/feature/6750456638341120 - Hongbo Miao
"Bu işe yaramıyor", bununla ne yapacağımı düşündüğünüzü bilmiyorum. Muhtemelen yanlış bir şey yaptın ama nasıl bilmeliyiz? - Günter Zöchbauer
Bu, bir çizgi grafikteki veri noktaları için "nokta" göstermeye çalıştı: Aşağıdakileri ekledim: reportgraph.component.css dosya : >>> #reportClubSignupRate .nv-point { fill-opacity: 1 !important; } - Simon_Weaver


ViewEncapsulation senin problemini çözecek.

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: []
})

15
2018-03-25 05:46



vay, çok teşekkür ederim! - Hongbo Miao
Hongbo Miao'ya hoşgeldin! - micronyks
Biraz açıklayabilir misin? Bu daha yararlı olacak. Teşekkürler - Hongbo Miao
egghead.io/lessons/... Sadece bu videoyu bir kez görüp, açısal2'de mevcut olan üç farklı yoldan haberdar olacaksınız. - micronyks
Bu videoyu izledikten sonra, temel olarak stilleri global hale getiriyor, sonra da style.css, lütfen bunu gör plunkrSonra bir kırmızı ve bir yeşil dikdörtgen gösteremiyorum ... Sorun geri geliyor - Hongbo Miao


Muhafazayı Görüntüle

Bunun nedeni, Açısal 2'deki görünüm kapsüllemesidir. Varsayılan olarak, tüm HTML ve CSS dönüştürülür, böylece yalnızca yerel olarak uygulanır. Başka bir deyişle, bu stili bileşeninizin CSS'sine eklerseniz:

h2 { color: red; }

Sadece etkileyecek bileşen içindeki h2 elemanları, tüm uygulamanızda her h2 öğesi değil. Bu mekanizmalar hakkında daha fazla bilgi edinebilirsiniz. Görünüm Encapsulation üzerinde açısal belgeler.

Neden seni etkiliyor?

Açısal, stillerinizi dönüştürür, ancak C3 grafiği henüz çizilmediğinden, HTML / SVG'yi de dönüştürebilir. Bu nedenle, bileşen stilleri C3 grafiğinin içindeki elemanlarla eşleşmez.

Ne yapmalıyım?

Harici stil sayfası

Dış stil sayfaları Görünüm Kapsülleme mekanizmaları tarafından dönüştürülmez, bu yüzden etkili bir şekilde C3 grafiğinizi (ve bu konuyla ilgili başka herhangi bir öğeyi) etkiler.

Angular CLI kullanıyorsanız, harici stil sayfası eklemek gerçekten basittir. Düzenleyin angular-cli.json dosya ve içinde apps mülk bul styles dizi. Buradan başka bir stil sayfası ekle:

{
    …
    "apps": [
        {
            …
            "styles": [
                "styles.scss",
                "c3.scss" // <---- add this or any other file
            ],
        }
    ],
    …
}

Açısal CLI kullanmıyorsanız, harici stil sayfalarını eklemenin bir yolu olmalıdır. Muhtemelen en basit olanı ekliyor <link …> içinde <head> senin içinde index.html dosya.

ViewEncapsulation.None

İlk seçeneğiniz: Grafiğe (ve yalnızca grafiğe) sahip bir bileşen oluşturun ve İçinde View Encapsulation'ı kapatın. Tek Sorumluluk İlkesine uymak da bunu yapmak için iyi bir fikir. Grafiğiniz, tasarım gereği, ayrı bir bileşenle kapsüllenmelidir. View Encapsulation uygulamasının açılması, başka bir özelliği eklemek kadar basittir. @Component dekoratör:

@Component({
    …
    encapsulation: ViewEncapsulation.None
})

/deep/ CSS seçici

Eğer bir sebepten dolayı bunu yapmak istemiyorsan, başka bir olasılık var. Kullanmayı deneyebilirsiniz /deep/ CSS'nizin içindeki seçici, stilleri tüm alt bileşen görünümlerine zorlar. Etkili olarak, bu kapsüllenmeyi kırar ve C3 grafiğinizi etkilemelidir. Yani, örneğin, bunu bileşeninizin CSS dosyasında yapabilirsiniz:

/deep/ .c3-chart-arc path {
    stroke: white;
}

Her iki şekilde de, yukarıda belirtilen belgeleri okumanızı tavsiye ederim. Açısal 2'de Kapsüllenmeyi Görüntüleme Bunun neden olduğunu ve nasıl çalıştığını anlamak için. Bu özellik kod yazmanıza yardımcı olacak, sorunlara neden olmayacaktır :) Bu makale, nasıl çalıştığını anlamanıza yardımcı olabilir: Blog.thoughtram.io'daki Encapsulation'ı görüntüle


3
2018-02-12 14:52





... sonra bir kırmızı ve bir yeşil dikdörtgen gösteremiyorum ... Sorun   geri döner

Sanırım biraz geçersiz, bunun ne kadarının doğru olduğunu bilmiyorum, ama bence sorununuzu çözüyor.

ekle child1-cmp, child1-cmp .bar Örneğin:

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

Not: ek olarak encapsulation: ViewEncapsulation.Nonetarafından belirtildiği gibi micronyks.

Ölçek

Plunker


veya bu:

@Component({
  selector: 'my-app',
  directives: [Child1Cmp, Child2Cmp],
   encapsulation: ViewEncapsulation.None,
   styles: [`
    child1-cmp .bar {
      fill: red;
    }

    child2-cmp .bar {
      fill: yellow;
    }
  `],
   ..//

@Component({
  //encapsulation: ViewEncapsulation.None,
  selector: 'child1-cmp',
  template: `
    <div>
      <svg class="chart1"></svg>
    </div>
  `,
  directives: []
})

@Component({
  //encapsulation: ViewEncapsulation.None,
  selector: 'child2-cmp',
  template: `
    <div>
      <svg class="chart2"></svg>
    </div>
  `,
  directives: []
})

Ölçek

Plunker


veya bu sınıf kullanarak .chart1, .chart2örneğin, isterseniz.

@Component({
  selector: 'my-app',
  directives: [Child1Cmp, Child2Cmp],
   encapsulation: ViewEncapsulation.None,
   styles: [`
    .chart1 .bar {
      fill: red;
    }

    .chart2 .bar {
      fill: yellow;
    }
  `],
   ..//

Ölçek

Plunker


1
2018-03-25 08:48



Teşekkürler, melek meleğim, onlar çok güzel bir yoldan geçiyorlar, ama onlarca bu küçük parçalardan onlarca var, her biri onlarca hatta yüzlerce kez. Stillerini kendi bileşenlerinde sınırlayamazsam sürdürmek oldukça zor. - Hongbo Miao


kullanabilirsiniz

::ng-deep
.bar {
    fill: red;
}

Burada yaklaşımı açıklayan mükemmel makaleyi okuyabilirsiniz.

Ve ... Açısal belgelerden bilgi


1
2018-04-23 21:25



Lütfen bu cevabı, bu soruya cevap verecek şekilde, belirli bir soruya cevap verecek şekilde düzenleyin. - bignose


onu buldum * /deep/ .my-element-class Çalışır, ancak bazı nedenlerle, svg üst öğesi html şablonunda varsa SADECE (svg üst öğesi d3 ile anında oluşturulur).

Örneğin, aşağıdaki durum işe yarayacaktı:

mycomponent.component.html

<svg id="mygraph"></svg> <!-- IMPORTANT!! -->

mycomponent.component.css

* /deep/ .my-element-class {
  /* ... desired styles */
}

mycomponent.component.ts

d3.select("svg#mygraph").append("circle").classed("my-element-class", true)
 ...

0
2017-10-13 19:19