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]))); }
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); }