Example #1
0
    private transitionGrouped() {
        let propertyY = this.config.get('propertyY');
        let y = this.y.yAxis.scale();
        let height = this.config.get('height');
        let x = this.x.xAxis.scale();
        let xGroup = scaleBand().domain(this.keys).range([0, x.bandwidth()]);

        this.elementEnter
            .transition()
            .duration(Globals.COMPONENT_ANIMATION_TIME)
            .ease(easeLinear)
            .attr('y', (d: any) => {
                return d[propertyY] > 0 ? y(d[propertyY]) : y(0);
            })
            .attr('height', (d: any) => Math.abs(y(0) - y(d[propertyY])));

        this.elementExit
            .transition()
            .duration(Globals.COMPONENT_ANIMATION_TIME)
            .ease(easeLinear)
            .attr('fill-opacity', 0)
            .remove();

        this.elementUpdate
            .transition()
            .duration(Globals.COMPONENT_ANIMATION_TIME)
            .ease(easeLinear)
            .attr('y', (d: any) => {
                return d[propertyY] > 0 ? y(d[propertyY]) : y(0);
            })
            .attr('width', xGroup.bandwidth())
            .attr('height', (d: any) => Math.abs(y(0) - y(d[propertyY])));
    }
Example #2
0
    private updateGrouped(data: any[]) {
        let propertyKey = this.config.get('propertyKey');
        let propertyX = this.config.get('propertyX');
        let propertyY = this.config.get('propertyY');
        let width = this.config.get('width');

        let keys = map(data, (d) => d[propertyKey]).keys();

        this.keys = keys;

        let colorScale = this.config.get('colorScale'),
            layer: any = null,
            x = this.x.xAxis.scale(),
            y = this.y.yAxis.scale(),
            xGroup = scaleBand().domain(keys).range([0, x.bandwidth()]),

            height = this.config.get('height');

        let nestedData = simple2nested(data, propertyKey);

        // JOIN series
        let serie = this.svg.selectAll(`.${Globals.SELECTOR_SERIE}`)
            .data(nestedData);

        serie.exit().remove();

        // UPDATE series
        serie.attr('class', Globals.SELECTOR_SERIE)
            .attr(Globals.COMPONENT_DATA_KEY_ATTRIBUTE, (d: any) => d[propertyKey]);

        // ENTER + UPDATE series
        serie = serie.enter().append('g')
            .attr('class', Globals.SELECTOR_SERIE)
            .attr(Globals.COMPONENT_DATA_KEY_ATTRIBUTE, (d: any) => d[propertyKey])
            .merge(serie);

        // EXIT series
        serie.exit().remove();

        // JOIN bars
        let bars = serie.selectAll(`.${Globals.SELECTOR_ELEMENT}`)
            .data((d: any) => d.values, (d: any) => d[propertyX]);

        // UPDATE bars
        this.elementUpdate = bars
            .attr('class', Globals.SELECTOR_ELEMENT)
            .attr('fill', (d: any, i: number) => d[propertyKey] !== undefined
                ? colorScale(d[propertyKey])
                : colorScale(i)
            )
            .attr('transform', (d: any) => 'translate(' + xGroup(d[propertyKey]) + ')')
            .attr('x', (d: any) => x(d[propertyX]));

        // ENTER bars
        this.elementEnter = bars.enter()
            .append('rect')
            .attr('data-proteic-element', 'bar')
            .attr('class', Globals.SELECTOR_ELEMENT)
            .attr('fill', (d: any, i: number) => d[propertyKey] !== undefined
                ? colorScale(d[propertyKey])
                : colorScale(i)
            )
            .attr('transform', (d: any) => 'translate(' + xGroup(d[propertyKey]) + ')')
            .attr('height', 0)  // This makes the transition start
            .attr('y', y(0))  // at the bottom of the chart
            .attr('x', (d: any) => x(d[propertyX]))
            .attr('width', xGroup.bandwidth());

        // EXIT bars
        this.elementExit = bars.exit();

        this.svg.select('.baseline').remove();
        this.svg.append('line')
          .attr('class', 'baseline')
          .attr('y1', y(0))
          .attr('y2', y(0))
          .attr('x2', width);

    }
    public update(data: any[]): void {
        let propertyKey = this.config.get('propertyKey');
        let propertyStart = this.config.get('propertyStart');
        let propertyEnd = this.config.get('propertyEnd');
        let propertyZ = this.config.get('propertyZ');
        
        data = data.filter((d) => propertyEnd in d || propertyStart in d);

        let colorScale = this.config.get('colorScale'),
            colorScaleType = this.config.get('colorScaleType'),
            height = this.config.get('height'),
            onDown = this.config.get('onDown'),
            onUp = this.config.get('onUp'),
            onLeave = this.config.get('onLeave'),
            onHover = this.config.get('onHover'),
            onClick = this.config.get('onClick'),
            displayValues = this.config.get('displayValues'),
            valuesFormat = this.config.get('valuesFormat'),
            keys = map(data, (d) => d[propertyKey]).keys(),
            layer = this.svg.selectAll('.serie').data(data),
            layerEnter = null,
            layerMerge = null,
            box = null,
            boxEnter = null,
            boxExit = null,
            boxMerge = null,
            extLanes = null,
            yLanes: any = null,
            yLanesBand = scaleBand().range([0, keys.length + 1]).domain(keys),
            x = this.xyAxes.x.xAxis.scale(),
            y = this.xyAxes.y.yAxis.scale();

        if (colorScaleType === 'sequential') {
            let min = (d3Min(data, (d: any) => +d[propertyZ])),
                max = (d3Max(data, (d: any) => +d[propertyZ]));
            colorScale.domain([min, max]);
        }

        data = simple2nested(data, propertyKey);
        
        extLanes = extent(data, (d, i) => i);
        yLanes = scaleLinear().domain([extLanes[0], extLanes[1] + 1]).range([0, height]);

        layer = this.svg.selectAll('.serie').data(data);
        
        // NOTE: d.key instead of d[propertyKey] because data is d3.Nest
        layerEnter = layer.enter()
            .append('g')
            .attr(Globals.COMPONENT_DATA_KEY_ATTRIBUTE, (d: any) => d.key);

        layerMerge = layer.merge(layerEnter)
            .attr('class', 'serie');
            
            
        box = layerMerge.selectAll('.box')
            .data((d: any) => d.values);
            
        boxExit = layer.exit().remove();

        boxEnter = box.enter()
            .append('g')
            .attr('class', 'box');

        boxEnter.append('rect')
            .attr('data-proteic-element', 'timeBox')
            .attr('width', (d: any) => x(d[propertyEnd]) - x(d[propertyStart]))
            .attr('x', (d: any) => x(d[propertyStart]))
            .attr('y', (d: any) => y(d[propertyKey]))
            .attr('height', () => 0.8 * yLanes(1))
            .style('fill', (d: any) => colorScaleType === 'sequential'
                ? colorScale(d[propertyZ])
                : colorScale(d[propertyKey])
            );

        if (displayValues) {
            boxEnter.append('text')
                .attr('x', (d: any) => x(d[propertyStart]) + (x(d[propertyEnd]) - x(d[propertyStart])) / 2)
                .attr('y', (d: any) => y(d[propertyKey]) + 0.8 * yLanes(1) / 2)
                .attr('dy', '3')
                .attr('text-anchor', 'middle')
                .attr('dominant-baseline', 'middle')
                .text((d: any) => format(valuesFormat)(d[propertyZ]));
        }

        boxMerge = box.merge(boxEnter);

        boxMerge.select('rect')
            .attr('width', (d: any) => x(d[propertyEnd]) - x(d[propertyStart]))
            .attr('x', (d: any) => x(d[propertyStart]))
            .attr('y', (d: any) => y(d[propertyKey]))
            .attr('height', () => 0.8 * yLanes(1))
            .style('fill', (d: any) => colorScaleType === 'sequential'
                ? colorScale(d[propertyZ])
                : colorScale(d[propertyKey])
            );

        if (displayValues) {
            boxMerge.select('text')
                .attr('x', (d: any) => x(d[propertyStart]) + (x(d[propertyEnd]) - x(d[propertyStart])) / 2)
                .attr('y', (d: any) => y(d[propertyKey]) + 0.8 * yLanes(1) / 2)
                .attr('dy', '3')
                .attr('text-anchor', 'middle')
                .attr('dominant-baseline', 'middle');
        }
        
        box = this.svg.selectAll('g.serie rect');

        box
            .on('mousedown.user', onDown)
            .on('mouseup.user', onUp)
            .on('mouseleave.user', onLeave)
            .on('mouseover.user', onHover)
            .on('click.user', onClick);
    }