Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在条形图(D3)后面移动网格线_Javascript_Angular_D3.js - Fatal编程技术网

Javascript 如何在条形图(D3)后面移动网格线

Javascript 如何在条形图(D3)后面移动网格线,javascript,angular,d3.js,Javascript,Angular,D3.js,我想把网格线移到条形图的后面,实际上我在upgradeChart()函数的条形图之前打印网格线,有什么建议吗? 我需要网格线:)我不能删除它们。 这是我的代码: import { Component, OnInit, OnChanges, ViewChild, ElementRef, AfterViewInit, ViewEncapsulation, Input } from '@angular/core'; import * as d3 from 'd3'; import * as _

我想把网格线移到条形图的后面,实际上我在upgradeChart()函数的条形图之前打印网格线,有什么建议吗? 我需要网格线:)我不能删除它们。 这是我的代码:

    import { Component, OnInit, OnChanges, ViewChild, ElementRef, AfterViewInit, ViewEncapsulation, Input } from '@angular/core';
import * as d3 from 'd3';
import * as _d3Tip from 'd3-tip';

@Component({
  selector: 'app-histogram',
  templateUrl: './histogram.component.html',
  styleUrls: ['./histogram.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class HistogramComponent implements OnInit, OnChanges {
   @ViewChild('chart') private chartContainer: ElementRef;
   @Input() public config;
    private chart;
    private margin;
    private width;
    private height;
    private xScale;
    private yScale;
    private xAxis;
    private yAxis;
    private element;
    private svg;

  constructor() {
  }

  ngOnInit() {
    console.log(this.config);
    this.createChart( );
    if (this.config.data) {
      this.updateChart();
    }
  }

  ngOnChanges() {
    if (this.chart) {
      this.updateChart();
    }
  }

  public createChart() {

// Traemos el elemento donde estará el gráfico en este caso #chart
this.element = this.chartContainer.nativeElement;

// Guardamos los datos en una constante
const data = this.config.data;

// Declaramos el margen, el ancho y la altura del gráfico según los estilos del div #chart (d3-chart)
this.margin = { top: 40, right: 20, bottom: 30, left: 40 };
this.width = this.element.offsetWidth - this.margin.left - this.margin.right;
this.height = this.element.offsetHeight - this.margin.top - this.margin.bottom;

this.svg = d3.select(this.element).append('svg')
  .attr('width', this.element.offsetWidth)
  .attr('height', this.element.offsetHeight);

// chart plot area
this.chart = this.svg.append('g')
  .attr('class', 'bars')
  .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`);

// Creamos las escalas
this.xScale = d3.scaleBand().range([0, this.width]).padding(0.3);
this.yScale = d3.scaleLinear().range([this.height, 0]);

// Definimos la posicion del eje X en la parte de abajo
this.xAxis = this.svg.append('g')
  .attr('class', 'x axis')
  .attr('transform', `translate(${this.margin.left}, ${this.margin.top + this.height})`)
  .call(d3.axisBottom(this.xScale));

// Definimos la posicion del eje Y en la parte izquierda con su formato..
this.yAxis = this.svg.append('g')
  .attr('class', 'y axis')
  .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`)
  .call(d3.axisLeft(this.yScale));


 }

  public updateChart() {

// Necesario al importar la libreria d3-tip para versiones superiores a 4 en d3.js
const d3Tip = _d3Tip.bind(d3);

// Creamos el tooltip
const tip = d3Tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
  return '<span class="highlight">' + d.valueY + '€' + '</span>';
});

this.svg.call(tip);

// Definimos los datos de las escalas
this.xScale.domain(this.config.data.map( d => d.valueX));
this.yScale.domain([0, d3.max(this.config.data, d => d.valueY)]);
this.xAxis.transition().call(d3.axisBottom(this.xScale));
this.yAxis.transition().call(d3.axisLeft(this.yScale).tickSize(-this.width).ticks(4).tickFormat(d => d + '€'));

const update = this.chart.selectAll('.bar')
  .data(this.config.data);

  // remove exiting bars
  update.exit().remove();

  // update existing bars
  this.chart.selectAll('.bar').transition()
    .attr('x', d => this.xScale(d.valueX))
    .attr('y', d => this.yScale(d.valueY))
    .attr('width', d => this.xScale.bandwidth())
    .attr('height', d => this.height - this.yScale(d.valueY));

    update
    .enter().append('rect')
    .attr('class', 'bar')
    .attr('data-index', function(d, i) { return i; })
    .on('mouseover', tip.show)
    .on('mouseout', tip.hide)
    .attr('x', d => this.xScale(d.valueX))
    .attr('y', d => this.yScale(d.valueY))
    .attr('width', this.xScale.bandwidth())
    .transition()
    .ease(d3.easeLinear)
    .duration(300)
    .delay((d, i) => i * 50)
    .attr('height', d => this.height - this.yScale(d.valueY));


 }

}
这条线表示网格线:

.tickSize(-this.width).ticks(4).tickFormat(d => d + '€')
我让我的柱状图中的一张图片

网格线解决方案:

解决方案是使用以下代码:

    // chart plot area
this.chart = this.svg.append('g')
.attr('class', 'bars')
.attr('transform', `translate(${this.margin.left}, ${this.margin.top})`);
在此之后:

    // Definimos la posicion del eje Y en la parte izquierda con su formato..
this.yAxis = this.svg.append('g')
  .attr('class', 'y axis')
  .attr('transform', `translate(${this.margin.left}, ${this.margin.top})`)
  .call(d3.axisLeft(this.yScale));
编辑:其他问题:

  • 有人知道怎样才能响应我的柱状图
  • 当值为0€时,我需要设置一个最小条,我如何才能做到这一点

  • 我不确定没有小提琴,但是svg最初没有z索引。元素是基于DOM树分层的。所以最后绘制的图显示在顶部。就你而言,我明白了:

    this.xAxis = this.svg.append('g')...
    

    现在,您可以尝试为两个轴创建包装器g,而不是直接在svg上添加它们作为g元素:

    this.wrapper = this.svg.append('g');
    
    然后,代替上述2项,执行以下操作:

    this.xAxis = this.wrapper.append('g')...
    
    确保在添加元素之前添加了包装器g元素。这会缓解问题吗

    关于你的其他问题

    2-有多种方法可以使其响应,最简单的方法之一是在svg上使用preserveSpectratio=“none”属性,然后使用css媒体查询控制div或包装svg的任何元素。如果您的意思是更改轴等的绘制方式,则必须调用更新函数,该函数将在窗口
    “resize”
    事件中更新这些元素

    3-在图表上设置x、y或宽度-高度或变换属性时使用Math.max和Math.min,如

    .attr("height",function(d,i){return Math.min(someMin,someScale(d))})
    

    感谢您的回答我编辑了解决方案:)np,我还为其他问题添加了一些建议我在html上称我的条形图为:如何在您的svg上使用PreserveSpectratio:
    如果分辨率改变,只需调整图形的大小
    
    this.xAxis = this.wrapper.append('g')...
    
    .attr("height",function(d,i){return Math.min(someMin,someScale(d))})