简体   繁体   中英

Angular D3 not displaying line chart

Hi I'm trying to create line chart from here https://bl.ocks.org/d3noob/3c040800ff6457717cca586ae9547dbf and have changed the data in json format and applied the code in my angular project. But d3 neither displays anything nor there is any error on chrome console. I'm new to d3 and unable to figure out the error. Can someone help me with this?

Here's my angular ts file.

import * as D3 from 'd3';
import * as data from './data.json';
@Component({
  selector: 'app-linechart',
  templateUrl: './linechart.component.html',
  styleUrls: ['./linechart.component.scss']
})
export class LinechartComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
    this.createLineChart();
  }
  public createLineChart(): void {
    console.log('in line method');
    console.log(D3);
    console.log(data);
    console.log(data[0]);
    const d3: any = D3;
    // tslint:disable-next-line:one-variable-per-declaration
    const margin = {top: 20, right: 20, bottom: 70, left: 50},
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

// parse the date / time
    const parseTime = d3.timeParse('%d-%b-%y');

// set the ranges
    const x = d3.scaleTime().range([0, width]);
    const y = d3.scaleLinear().range([height, 0]);

// define the line
    const valueLine = d3.line()
      .x(d => d.date)
      .y(d => d.close);

// append the svg object to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
    const svg = d3.select('body').append('svg')
      .attr('width', width + margin.left + margin.right)
      .attr('height', height + margin.top + margin.bottom)
      .append('g')
      .attr('transform',
        'translate(' + margin.left + ',' + margin.top + ')');

      // Scale the range of the data
    x.domain(d3.extent(data, d => d.date));
    y.domain([0, d3.max(data, d => d.close)]);

      // Add the valueline path.
    svg.append('path')
        .data([data])
        .attr('class', 'line')
        .attr('d', valueLine);

      // Add the X Axis
    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(d3.axisBottom(x).ticks(10))
        .selectAll('text')
        .style('text-anchor', 'end')
        .attr('dx', '-.8em')
        .attr('dy', '.15em')
        .attr('transform', 'rotate(-65)');

      // Add the Y Axis
    svg.append('g')
        .attr('class', 'axis')
        .call(d3.axisLeft(y));
  }

}

and data.json

  {
    "date": "1-May-12",
    "close": 58.13
  },
  {
    "date": "30-Apr-12",
    "close": 53.98
  },
  {
    "date": "27-Apr-12",
    "close": 67
  },
  {
    "date": "26-Apr-12",
    "close": 89.7
  },
  {
    "date": "25-Apr-12",
    "close": 99
  },
  {
    "date": "24-Apr-12",
    "close": 130.28
  },
  {
    "date": "23-Apr-12",
    "close": 166.7
  },
  {
    "date": "20-Apr-12",
    "close": 234.98
  },
  {
    "date": "19-Apr-12",
    "close": 345.44
  },
  {
    "date": "18-Apr-12",
    "close": 443.34
  },
  {
    "date": "17-Apr-12",
    "close": 543.7
  },
  {
    "date": "16-Apr-12",
    "close": 580.13
  },
  {
    "date": "13-Apr-12",
    "close": 605.23
  },
  {
    "date": "12-Apr-12",
    "close": 622.77
  },
  {
    "date": "11-Apr-12",
    "close": 626.2
  },
  {
    "date": "10-Apr-12",
    "close": 628.44
  },
  {
    "date": "9-Apr-12",
    "close": 636.23
  },
  {
    "date": "5-Apr-12",
    "close": 633.68
  },
  {
    "date": "4-Apr-12",
    "close": 624.31
  },
  {
    "date": "3-Apr-12",
    "close": 629.32
  },
  {
    "date": "2-Apr-12",
    "close": 618.63
  },
  {
    "date": "30-Mar-12",
    "close": 599.55
  },
  {
    "date": "29-Mar-12",
    "close": 609.86
  },
  {
    "date": "28-Mar-12",
    "close": 617.62
  },
  {
    "date": "27-Mar-12",
    "close": 614.48
  },
  {
    "date": "26-Mar-12",
    "close": 606.98
  }
]
'''




I follewed the same tutorial and I had the same issue.

What I did is that i tried another tutorial. Here is the link . At first nothing displayed but this time it was about the angular lifecycle. In that example I changed the OnChanges by a AfterViewInit and voilà.

The TS

import {Component, OnChanges, OnInit, ViewEncapsulation, SimpleChanges, AfterViewInit, ElementRef, ViewChild} from '@angular/core';

import * as d3 from 'd3';

import {STOCKS} from './stocks';

@Component({
  selector: 'app-sgo-example-feature',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './example.feature.component.html',
  styleUrls: ['./example.feature.component.scss']
})
export class ExampleFeatureComponent  implements OnChanges, AfterViewInit {
  @ViewChild('chart')
  private chartContainer: ElementRef;

  data = STOCKS;

  margin = {top: 20, right: 20, bottom: 30, left: 40};

  constructor() { }

  ngOnChanges(): void {
    console.log(this.data);
    if (!this.data) { return; }

    this.createChart();
    console.log('I made it here');
  }
  ngAfterViewInit(): void {
    console.log(this.data);
    if (!this.data) { return; }

    this.createChart();
    console.log('I made it here');
  }

  private createChart(): void {
    d3.select('svg').remove();

    const element = this.chartContainer.nativeElement;
    const data = this.data;

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

    const contentWidth = element.offsetWidth - this.margin.left - this.margin.right;
    const contentHeight = element.offsetHeight - this.margin.top - this.margin.bottom;

    const x = d3
    .scaleBand()
    .rangeRound([0, contentWidth])
    .padding(0.1)
    .domain(data.map(d => d.letter));

    const y = d3
    .scaleLinear()
    .rangeRound([contentHeight, 0])
    .domain([0, d3.max(data, d => d.value)]);

    const g = svg.append('g')
    .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');

    g.append('g')
    .attr('class', 'axis axis--x')
    .attr('transform', 'translate(0,' + contentHeight + ')')
    .call(d3.axisBottom(x));

    g.append('g')
    .attr('class', 'axis axis--y')
    .call(d3.axisLeft(y).ticks(10, '%'))
    .append('text')
    .attr('transform', 'rotate(-90)')
    .attr('y', 6)
    .attr('dy', '0.71em')
    .attr('text-anchor', 'end')
    .text('Frequency');

    g.selectAll('.bar')
    .data(data)
    .enter().append('rect')
    .attr('class', 'bar')
    .attr('x', d => x(d.letter))
    .attr('y', d => y(d.value))
    .attr('width', x.bandwidth())
    .attr('height', d => contentHeight - y(d.value));
  }
}

The html

<div #chart id="chart"></div>

The SCSS

app-sgo-example-feature {
  #chart {
    height: inherit;
    width: inherit;

    .bar {
      fill: steelblue;
    }

    .bar:hover {
      fill: brown;
    }

    .axis--x path {
      display: none;
    }
  }
}

And the call in the content page

    <app-sgo-example-feature ></app-sgo-example-feature>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM