D3.js 组件中的样式不以 angular 2 显示 [英] Styles in component for D3.js do not show in angular 2

查看:17
本文介绍了D3.js 组件中的样式不以 angular 2 显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Angular 2 和 D3.js.我想显示一个红色矩形.

仅当我将样式放入 style.css 文件时才有效.检查这个plunkr

当我将样式放入组件 styles: [] 时,它不起作用.检查这个plunkr

当我使用组件 styles: [] 时如何让它工作?谢谢

UPDATE:@micronyks 提供了一个解决方案,但它使组件中的样式具有全局性,与写入style.css 文件基本没有区别.在这个plunkr中,它显示一个组件中的样式将覆盖另一个组件的样式,因此不能显示绿色和红色矩形.

更新 2:@Günter 的方法完美地解决了这个问题!!提醒一下,对于 Günter 的方式:它至少需要 Angular beta 10.(我的其他 plunkrs 使用 Angular beta 8)使用 Angular beta 12 的绿色和一个红色矩形的工作演示是 此处.

从'angular2/core'导入{Component}@成分({选择器:'我的应用',提供者:[],样式:[`/*这不起作用*/.酒吧 {填充:红色;}`],模板:`<div><svg class="chart"></svg>

`,指令:[]})出口类应用{构造函数(){}ngOnInit() {this.draw();}画() {让数据 = [{name: 'A', value: 1}];让宽度= 400,高度= 200;让 x = d3.scale.ordinal().rangeRoundBands([0, width]);让 y = d3.scale.linear().range([height, 0]);让图表 = d3.select(".chart").attr("宽度", 宽度).attr("高度", 高度).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(数据).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("宽度", 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 只是被一个 取代,因此非常有限).另请参阅 https://stackoverflow.com/a/36225709/217408Plunker

:host/deep/div {红色;}

SASS

/deep/ 与 SASS 配合良好,但别名 >>>> 不行.

阴影穿透 CSS 组合器由 Angular 重写,它们不需要浏览器支持.Chrome 支持它们一段时间,但它们已被弃用 - 但如上所述,这无关紧要,因为 Angular 重写它们以使用其封装仿真.

ViewEncapsulation.Native

Angular 不支持任何方式从外部设置此类组件的样式.只有当浏览器提供像 CSS 变量这样的支持时,才可以使用这些.

I am using Angular 2 and D3.js. I want to show a red rectangle.

It only works if I put styles in the style.css file. Check this plunkr

When I put my styles in the component styles: [], it does not work. Check this plunkr

How to let it work when I use the component styles: []? Thanks

UPDATE: @micronyks provides a solution, but it makes the styles in the component global, basically no difference with writing in style.css file. In this plunkr, it shows style in one component will override another component's styles, so cannot show green and red rectangles.

UPDATE 2: @Günter's way perfectly solve this problem!! Just a remind, for Günter's way: it needs at least Angular beta 10. (My other plunkrs use Angular beta 8) The working demo for green and one red rectangle using Angular beta 12 is 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());
  }
}

解决方案

Update

Angular and SASS agreed on supporting ::ng-deep (instead of >>> or /deep/) a while ago until ::slotted or whatever makes it into browser standards becomes available in all browsers.

ViewEncapsulation.Emulated (default)

That's by design. Angular adds class names unique to components and rewrites the added styles to only apply to the components where they were added.

D3 generates HTML dynamically without Angulars knowledge and Angular can't apply the classes to make the styles apply on the generated HTML.

If you add the styles at the entry point HTML file, Angular also doesn't rewrite the styles and the added helper classes don't take effect.

ViewEncapsulation.None

With encapsulation: ViewEncapsulation.None Angular doesn't do this rewriting, therefore the result is similar to adding the HTML to the index.html.

"Shadow-piercing"

Alternatively you can use the recently introduced shadow piercing CSS combinators >>>, /deep/ and ::shadow (::shadow is just replaced by a and thus very limited). See also https://stackoverflow.com/a/36225709/217408 and the Plunker

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

SASS

/deep/ works fine with SASS but the alias >>> doesn't.

The shadow-piersing CSS combinators are rewritten by Angular and they don't need to be supported by the browsers. Chrome supported them for a while but they are deprecated - but as said, that doesn't matter, because Angular rewrites them to use its encapsulation emulation.

ViewEncapsulation.Native

Angular doesn't support any way to style such components from the outside. Only if the browser provides support like CSS variables then these can be used.

这篇关于D3.js 组件中的样式不以 angular 2 显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆