Angular 2とD3.jsを使用しています。赤い長方形を表示したいです。
スタイルをstyle.cssファイルに入れた場合にのみ機能します。チェック this plunkr
コンポーネントにスタイルを配置するとstyles: []
、動作しません。チェック this plunkr
コンポーネントを使用するときに機能させる方法styles: []
?ありがとう
UPDATE:@micronyksはソリューションを提供しますが、コンポーネントのスタイルをグローバルにします。基本的にstyle.cssファイル。 this plunkr では、あるコンポーネントのスタイルが別のコンポーネントのスタイルをオーバーライドすることを示しているため、緑と赤の長方形を表示できません。
UPDATE 2:@Günterの方法はこの問題を完全に解決します!! Günterのやり方を思い出してください。少なくともAngular beta 10が必要です。(他のプランカーはAngular beta 8)を使用します。 Angular beta 12は here です。
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());
}
}
更新
AngularとSASSは、::ng-deep
またはブラウザ標準に準拠するものがすべてのブラウザで使用可能になるまで、>>>
(/deep/
または::slotted
の代わりに)をサポートすることに少し同意しました。
ViewEncapsulation.Emulated(デフォルト)
それは設計によるものです。 Angularは、コンポーネントに固有のクラス名を追加し、追加されたスタイルを、それらが追加されたコンポーネントにのみ適用されるように書き換えます。
D3は、Angularsの知識がなくてもHTMLを動的に生成し、Angularはクラスを適用して、生成されたHTMLにスタイルを適用できません。
エントリポイントのHTMLファイルにスタイルを追加すると、Angularもスタイルを書き換えず、追加されたヘルパークラスは有効になりません。
ViewEncapsulation.None
encapsulation: ViewEncapsulation.None
の場合Angularはこの書き換えを行わないため、結果はHTMLをindex.html
に追加することに似ています。
「シャドウピアス」
または、最近導入されたシャドウピアスCSSコンビネーター>>>
、/deep/
、および::shadow
を使用できます(::shadow
はaに置き換えられているため、非常に制限されています)。 https://stackoverflow.com/a/36225709/217408 および Plunker も参照してください
:Host /deep/ div {
color: red;
}
[〜#〜] sass [〜#〜]
/deep/
はSASSで正常に動作しますが、エイリアス>>>
は動作しません。
シャドウピアスCSSコンビネーターはAngularによって書き換えられ、ブラウザーでサポートされる必要はありません。Chromeしばらくサポートされていますが、非推奨-ただし、前述のとおり、Angularはカプセル化エミュレーションを使用するように書き換えるので、問題ではありません。
ViewEncapsulation.Native
Angularは、そのようなコンポーネントを外部からスタイルする方法をサポートしていません。ブラウザがCSS変数などのサポートを提供する場合にのみ、これらを使用できます。
ViewEncapsulation
は問題を修正します。
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: []
})
これは、ビューのカプセル化がAngular 2.であるためです。デフォルトでは、すべてのHTMLおよびCSSは、ローカルにのみ適用されるように変換されます。つまり、このスタイルをコンポーネントのCSS :
h2 { color: red; }
アプリケーション全体のすべてのh2要素ではなく、コンポーネント内のh2要素のみに影響します。このメカニズムの詳細については、 Angular View Encapsulationのドキュメント を参照してください。
Angularはスタイルを変換しますが、C3グラフはまだ描画されていないため、HTML/SVGも変換できません。そのため、コンポーネントスタイルはC3グラフ内の要素と一致しません。
外部スタイルシートはビューのカプセル化メカニズムによって変換されないため、C3チャート(およびその他の要素)に効果的に影響します。
Angular CLI)を使用している場合、外部スタイルシートの追加は非常に簡単です。angular-cli.json
ファイルとapps
プロパティ内でstyles
配列を検索しますここに別のスタイルシートを追加します。
{
…
"apps": [
{
…
"styles": [
"styles.scss",
"c3.scss" // <---- add this or any other file
],
}
],
…
}
Angular CLIを使用していない場合は、外部スタイルシートを追加する方法が必要です。おそらく最も簡単な方法は、<link …>
内に別の<head>
を追加することです。 index.html
ファイル。
ViewEncapsulation.None
最初のオプションは、チャート(およびチャートのみ)でコンポーネントを作成し、その中のカプセル化の表示をオフにすることです。また、単一の責任原則に従うため、これを行うことをお勧めします。設計上、チャートは別のコンポーネントにカプセル化する必要があります。ビューのカプセル化の有効化は、@Component
デコレータに別のプロパティを追加するのと同じくらい簡単です。
@Component({
…
encapsulation: ViewEncapsulation.None
})
/deep/
CSSセレクター何らかの理由でそれをしたくない場合は、別の可能性があります。 CSS内で/deep/
セレクターを使用して、スタイルをすべての子コンポーネントビューに強制することができます。事実上、これはカプセル化を破壊し、C3チャートに影響するはずです。そのため、たとえば、コンポーネントのCSSファイルでそれを行うことができます。
/deep/ .c3-chart-arc path {
stroke: white;
}
いずれにせよ、これが起こる理由と動作を理解するために、前述の View Encapsulation in Angular 2 の前述のドキュメントを読むことをお勧めします。トラブルを引き起こさないコード:)この記事は、それがどのように機能するかを理解するのに役立つかもしれません: blog.thoughtram.ioでカプセル化を見る
使用できます
::ng-deep
.bar {
fill: red;
}
ここで、アプローチを説明する完璧な記事を読むことができます。
そして... Angular documentation からの情報)==
...その後、1つの赤と1つの緑の長方形を表示できません...問題が再発します
私はそれがいくつかのオーバーライドだと思う、私はこれのどれくらいが真実かわからないが、これはあなたの問題を解決すると思う.
たとえば、child1-cmp
、child1-cmp .bar
を追加します。
@Component({
encapsulation: ViewEncapsulation.None,
selector: 'child1-cmp',
styles: [`
child1-cmp .bar {
fill: red;
}
`],
template: `
<div>
<svg class="chart1"></svg>
</div>
`,
directives: []
})
注: micronyks で述べたように、encapsulation: ViewEncapsulation.None
に加えて。
テスト
またはこれ:
@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: []
})
テスト
または、必要に応じて、クラス.chart1
、.chart2
を使用します。
@Component({
selector: 'my-app',
directives: [Child1Cmp, Child2Cmp],
encapsulation: ViewEncapsulation.None,
styles: [`
.chart1 .bar {
fill: red;
}
.chart2 .bar {
fill: yellow;
}
`],
..//
テスト
見つけた * /deep/ .my-element-class
は動作しますが、何らかの理由で、svg親要素がhtmlテンプレートに存在する場合のみ(d3によってsvg親要素がオンザフライで作成される場合ではありません)。
たとえば、次の状況が機能します。
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)
...