Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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
Angular d3js使缩放在折线图上工作_Angular_Typescript_D3.js_Charts_Zooming - Fatal编程技术网

Angular d3js使缩放在折线图上工作

Angular d3js使缩放在折线图上工作,angular,typescript,d3.js,charts,zooming,Angular,Typescript,D3.js,Charts,Zooming,我正在尝试在Angular 4应用程序中构建d3js V4图表。图表将多组数据显示为单独的行 我不知道如何使缩放仅在X轴上正确工作 在“缩放”功能中,我已经尝试了所有内容,并给出了解释为什么它不起作用的注释 createChart() { const element = this.chartContainer.nativeElement; this.width = element.offsetWidth - this.margin.left - this.margin.right

我正在尝试在Angular 4应用程序中构建d3js V4图表。图表将多组数据显示为单独的行

我不知道如何使缩放仅在X轴上正确工作

在“缩放”功能中,我已经尝试了所有内容,并给出了解释为什么它不起作用的注释

createChart() {
    const element = this.chartContainer.nativeElement;
    this.width = element.offsetWidth - this.margin.left - this.margin.right;
    this.height = element.offsetHeight - this.margin.top - this.margin.bottom;

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

    // chart plot area
    this.chart = svg.append('g')
                .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');

    // domains
    const xDomain = [this.from, this.to];
    const yDomain = [0, 100];

    // scales
    this.xScale = d3.scaleTime().domain(xDomain).range([0, this.width]);
    this.yScale = d3.scaleLinear().domain(yDomain).range([this.height, 0]);

    // "data" function to draw lines
    this.valueline = d3.line<TimeValueObject>()
        .curve(d3.curveStepBefore)
        .x((d) => this.xScale(d.time))
        .y((d) => this.yScale(d.value));

    // X Axis
    this.xAxis = this.chart.append('g')
        .attr('class', 'xaxis')
        .attr('transform', 'translate(0,' + this.height + ')')
        .call(d3.axisBottom(this.xScale)
            .ticks(this.xTicks)
            .tickFormat(function (d) { return moment.utc(d).format(this.timeFormat); }));

    // Y Axis
    this.yAxis = this.chart.append('g')
        .attr('class', 'yaxis')
        .call(d3.axisLeft(this.yScale)
            .ticks(this.yTicks));

    // zoom
    const zoom = d3.zoom()
                .on('zoom', this.zoomed.bind(this));

    this.chart.call(zoom);
}

addData(myDataObject) {
    // Add a data valueline path
    this.chart.append('path')
        .attr('class', 'line')
        .attr('stroke', myDataObject.strokeStyle)
        .attr('id', myDataObject.name)
        .attr('d', this.valueline(myDataObject.data));
}

zoomed() {
    //KO: Zoom applied to whole graph in every direction. 
    //this.chart.attr('transform', d3.event.transform);

    //KO: Zoom applied to whole graph
    // this.chart
    //     .attr('transform', 'translate(' + d3.event.transform.x + ',0) scale(' + d3.event.transform.k + ',1)');

    //KO: Zoom applied to data but data not redrawn. Shows pixellated garbage at high zoom
    //Besides: when zoomed, the data expands beyond chart limits (Y axis on the left and chart right edge)
    //for (let [key, value] of this.dataObjects) {
    //    this.chart.select('#' + key + '')
    //        .attr('transform', 'translate(' + d3.event.transform.x + ',0) scale(' + d3.event.transform.k + ',1)');
    //}

    //KO: zoom is "elastic": 
    //    - On first mousewheel, nothing happens
    //    - On second mousewheel, graph zooms in the direction of previous mousewheel
    //    - Example: If I 'mousewheelup' 3 times in a row, I will have to 'mousewheeldown' 8 times to get back to zero zoom. The graph will keep zooming instead of unzooming on the 3 first 'mousewheeldown'
    //Besides: when zoomed, the data expands beyond chart limits (Y axis on the left and chart right edge)
    //for (let [key, value] of this.dataObjects) {
    //    this.chart.select('#' + key + '')
    //        .attr('d', this.valueline(value.data));
    //}

    //X Axis zoom
    const t = d3.event.transform;
    this.xScale = t.rescaleX(this.xScale);  //if I comment this line, no zoom occurs whatsoever
    //this.xAxis.call(d3.axisBottom(this.xScale)); //will cause 'elastic' axis zoom
}
不同的代码尝试基于官方示例:
终于找到了解决办法

诀窍在于d3缩放事件值始终针对初始缩放而不是前一次缩放给出

因此,首先,必须通过变换原始比例来调整比例:

→ 必须创建原始比例的副本 然后,可以重新绘制X轴:

this.xAxisElement.call(this.xAxis);
for (let [key, value] of this.dataObjects) {
    this.chart.select('#' + key + '')
        .attr('d', this.valueline(value.data));
}
→ 必须将项目存储在单独的变量中:xAxis用于d3.axisBottom函数结果,xAxisElement用于附加的axis元素 最后,可以重新绘制数据行:

this.xAxisElement.call(this.xAxis);
for (let [key, value] of this.dataObjects) {
    this.chart.select('#' + key + '')
        .attr('d', this.valueline(value.data));
}

→ 这是未经修改的

终于找到了解决方案

诀窍在于d3缩放事件值始终针对初始缩放而不是前一次缩放给出

因此,首先,必须通过变换原始比例来调整比例:

→ 必须创建原始比例的副本 然后,可以重新绘制X轴:

this.xAxisElement.call(this.xAxis);
for (let [key, value] of this.dataObjects) {
    this.chart.select('#' + key + '')
        .attr('d', this.valueline(value.data));
}
→ 必须将项目存储在单独的变量中:xAxis用于d3.axisBottom函数结果,xAxisElement用于附加的axis元素 最后,可以重新绘制数据行:

this.xAxisElement.call(this.xAxis);
for (let [key, value] of this.dataObjects) {
    this.chart.select('#' + key + '')
        .attr('d', this.valueline(value.data));
}
→ 这是未经修改的