水平滚动的 D3 条形图

问题描述 投票:0回答:1

我正在尝试实现一个条形图,其中有一个选择下拉列表,其中包含 3 个值:按日期、按周、按月(默认情况下为“按日期”)。

“ByDate”后端的数据有很多数据点(大约 50 个)。因此,当我绘制该图时,x 轴点会挤压,并且我无法在其上应用水平滚动。

我尝试在 stackblitz 中创建一个演示,但存在依赖问题,无法解决。虽然所有代码都在这里:Link

实际上我需要像这样的条形图:示例

因此,很抱歉我无法提供有效的演示,但请在此提供帮助。

我的功能:

createGraphData() {
    const margin = { top: 20, right: 30, bottom: 50, left: 60 };
    const width = 800 - margin.left - margin.right;
    const height = 400 - margin.top - margin.bottom;

    d3.select('#bar-chart').select('svg').remove(); // Remove existing chart

    const svg = d3
      .select('#bar-chart')
      .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 + ')');

    // Choose the appropriate dataset based on the selected option
    const dataset =
      this.graphRespId === 1
        ? this.graphDetails.lstByDateList
        : this.graphRespId === 2
          ? this.graphDetails.lstByWeekDateList
          : this.graphDetails.lstByMonthList;

    // Extract x-axis and y-axis values from the dataset
    const xValues = this.getXValues(dataset);
    const yValues = dataset.map((data) => data.CountName);
    // Set up x-axis and y-axis scales
    const xScale = d3.scaleBand().domain(xValues).range([0, width]).padding(0.1);
    const yScale = d3.scaleLinear().domain([0, Math.ceil(d3.max(yValues) / 10) * 10 + 5]).range([height, 0]);

    // Draw x-axis
    svg.append('g')
      .attr('transform', 'translate(0,' + height + ')')
      .call(d3.axisBottom(xScale));

    // Draw y-axis
    svg.append('g').call(d3.axisLeft(yScale));

    // Draw bars
    svg.selectAll('rect')
      .data(dataset)
      .enter()
      .append('rect')
      .attr('x', (data) => xScale(data[this.getXAxisKey()]))
      .attr('y', (data) => yScale(data.CountName))
      .attr('width', xScale.bandwidth())
      .attr('height', (data) => height - yScale(data.CountName))
      .attr('fill', () => this.getRandomColor());
  }

getXAxisKey() {
    return this.graphRespId === 1
      ? 'ByDate'
      : this.graphRespId === 2
        ? 'StartDate'
        : 'ByMonth';
  }

  // Generate a random color for the bars
  getRandomColor() {
    return '#' + Math.floor(Math.random() * 16777215).toString(16);
  }
getXValues(dataset: any[]): any[] {
    if (dataset === this.graphDetails.lstByDateList || dataset === this.graphDetails.lstByWeekDateList) {
      dataset.sort((a, b) => d3.timeParse('%Y-%m-%dT%H:%M:%S')(a[this.getXAxisKey()]).getTime() - d3.timeParse('%Y-%m-%dT%H:%M:%S')(b[this.getXAxisKey()]).getTime());
      return dataset.map((data) => {
        const originalDate = new Date(data[this.getXAxisKey()]);
        return this.datePipe.transform(originalDate, 'MM/dd/yyyy') || '';
      });
    }
    return dataset.map((data) => data[this.getXAxisKey()]);
  }
javascript angular typescript d3.js
1个回答
0
投票

我记得两年前与 D3 合作过,所以我可能不记得所有的事情,但我很确定它与你试图暗示的图表相同。

import { getAllLifecycleHooks } from '@angular/compiler/src/lifecycle_reflector';
import { Component, OnDestroy, Pipe } from '@angular/core';
import { NbColorHelper, NbThemeService } from '@nebular/theme';
import { FactureAdcaisse } from '../../../@core/data/FactureAf';
import { FactureService } from '../../../@core/mock/facture.service';



@Component({
  selector: 'ngx-d3-bar',
  template: `
    <chart echarts [options]="options" class="echart"></chart>

  `,
})
export class D3BarComponent implements OnDestroy {


  listfacture : FactureAf[];
  facture :FactureAf= new FactureAf()

  options: any = {};
  themeSubscription: any;

  totalpric_Y : any[]=[] ;
  totalpric_X : any ;

  constructor(private theme: NbThemeService , private  facttureservice : FactureService) {
  }

  ngAfterViewInit() {
    this.facttureservice.getAllActiveFacture().subscribe((data) => {
      this.listfacture = data;
      console.log("Invoices list",this.listfacture);

      this.totalpric_Y = this.listfacture.map(x=>x.totalprice) ;
      this.totalpric_X = this.listfacture.map(x=>x.name) ;

      console.log("les x",this.totalpric_X)
      console.log("les y",this.totalpric_Y)


      this.themeSubscription = this.theme.getJsTheme().subscribe(config => {




        const colors: any = config.variables;
        const echarts: any = config.variables.echarts;

        this.options = {
          backgroundColor: echarts.bg,
          color: [colors.primaryLight],
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow',
            },
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true,
          },
          xAxis: [
            {
              name: 'Partenaire :',

              type: 'category',
              data:this.totalpric_X,
              axisTick: {
                alignWithLabel: true,
              },
              axisLine: {
                lineStyle: {
                  color: echarts.axisLineColor,
                },
              },
              axisLabel: {
                textStyle: {
                  color: echarts.textColor,
                },
              },
            },
          ],
          yAxis: [
            {
              type: 'value',
              axisLine: {
                lineStyle: {
                  color: echarts.axisLineColor,
                },
              },
              splitLine: {
                lineStyle: {
                  color: echarts.splitLineColor,
                },
              },
              axisLabel: {
                textStyle: {
                  color: echarts.textColor,
                },
              },
            },
          ],
          series: [
            {
              name: 'Total(DT)',
              type: 'bar',
              barWidth: '60%',
              data: this.totalpric_Y,
            },
            console.log('whyyyyyyyyyyyyy',this.totalpric_Y)
          ],
        };
      });


    });
    console.log("les facture active",this.listfacture);


  }

  ngOnDestroy(): void {
    this.themeSubscription.unsubscribe();
  }

}

我认为这个例子很简单,因为您所需要做的就是获取数据并将其映射到 X 和 Y

© www.soinside.com 2019 - 2024. All rights reserved.