import CLASS from './class' import { ChartInternal } from './core' import { isValue } from './util' ChartInternal.prototype.initGrid = function() { var $$ = this, config = $$.config, d3 = $$.d3 $$.grid = $$.main .append('g') .attr('clip-path', $$.clipPathForGrid) .attr('class', CLASS.grid) if (config.grid_x_show) { $$.grid.append('g').attr('class', CLASS.xgrids) } if (config.grid_y_show) { $$.grid.append('g').attr('class', CLASS.ygrids) } if (config.grid_focus_show) { $$.grid .append('g') .attr('class', CLASS.xgridFocus) .append('line') .attr('class', CLASS.xgridFocus) } $$.xgrid = d3.selectAll([]) if (!config.grid_lines_front) { $$.initGridLines() } } ChartInternal.prototype.initGridLines = function() { var $$ = this, d3 = $$.d3 $$.gridLines = $$.main .append('g') .attr('clip-path', $$.clipPathForGrid) .attr('class', CLASS.grid + ' ' + CLASS.gridLines) $$.gridLines.append('g').attr('class', CLASS.xgridLines) $$.gridLines.append('g').attr('class', CLASS.ygridLines) $$.xgridLines = d3.selectAll([]) } ChartInternal.prototype.updateXGrid = function(withoutUpdate) { var $$ = this, config = $$.config, d3 = $$.d3, xgridData = $$.generateGridData(config.grid_x_type, $$.x), tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0 $$.xgridAttr = config.axis_rotated ? { x1: 0, x2: $$.width, y1: function(d) { return $$.x(d) - tickOffset }, y2: function(d) { return $$.x(d) - tickOffset } } : { x1: function(d) { return $$.x(d) + tickOffset }, x2: function(d) { return $$.x(d) + tickOffset }, y1: 0, y2: $$.height } $$.xgridAttr.opacity = function() { var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1') return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1 } var xgrid = $$.main .select('.' + CLASS.xgrids) .selectAll('.' + CLASS.xgrid) .data(xgridData) var xgridEnter = xgrid .enter() .append('line') .attr('class', CLASS.xgrid) .attr('x1', $$.xgridAttr.x1) .attr('x2', $$.xgridAttr.x2) .attr('y1', $$.xgridAttr.y1) .attr('y2', $$.xgridAttr.y2) .style('opacity', 0) $$.xgrid = xgridEnter.merge(xgrid) if (!withoutUpdate) { $$.xgrid .attr('x1', $$.xgridAttr.x1) .attr('x2', $$.xgridAttr.x2) .attr('y1', $$.xgridAttr.y1) .attr('y2', $$.xgridAttr.y2) .style('opacity', $$.xgridAttr.opacity) } xgrid.exit().remove() } ChartInternal.prototype.updateYGrid = function() { var $$ = this, config = $$.config, gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks) var ygrid = $$.main .select('.' + CLASS.ygrids) .selectAll('.' + CLASS.ygrid) .data(gridValues) var ygridEnter = ygrid .enter() .append('line') // TODO: x1, x2, y1, y2, opacity need to be set here maybe .attr('class', CLASS.ygrid) $$.ygrid = ygridEnter.merge(ygrid) $$.ygrid .attr('x1', config.axis_rotated ? $$.y : 0) .attr('x2', config.axis_rotated ? $$.y : $$.width) .attr('y1', config.axis_rotated ? 0 : $$.y) .attr('y2', config.axis_rotated ? $$.height : $$.y) ygrid.exit().remove() $$.smoothLines($$.ygrid, 'grid') } ChartInternal.prototype.gridTextAnchor = function(d) { return d.position ? d.position : 'end' } ChartInternal.prototype.gridTextDx = function(d) { return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4 } ChartInternal.prototype.xGridTextX = function(d) { return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0 } ChartInternal.prototype.yGridTextX = function(d) { return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width } ChartInternal.prototype.updateGrid = function(duration) { var $$ = this, main = $$.main, config = $$.config, xgridLine, xgridLineEnter, ygridLine, ygridLineEnter, xv = $$.xv.bind($$), yv = $$.yv.bind($$), xGridTextX = $$.xGridTextX.bind($$), yGridTextX = $$.yGridTextX.bind($$) // hide if arc type $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible') main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden') if (config.grid_x_show) { $$.updateXGrid() } xgridLine = main .select('.' + CLASS.xgridLines) .selectAll('.' + CLASS.xgridLine) .data(config.grid_x_lines) // enter xgridLineEnter = xgridLine .enter() .append('g') .attr('class', function(d) { return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '') }) xgridLineEnter .append('line') .attr('x1', config.axis_rotated ? 0 : xv) .attr('x2', config.axis_rotated ? $$.width : xv) .attr('y1', config.axis_rotated ? xv : 0) .attr('y2', config.axis_rotated ? xv : $$.height) .style('opacity', 0) xgridLineEnter .append('text') .attr('text-anchor', $$.gridTextAnchor) .attr('transform', config.axis_rotated ? '' : 'rotate(-90)') .attr('x', config.axis_rotated ? yGridTextX : xGridTextX) .attr('y', xv) .attr('dx', $$.gridTextDx) .attr('dy', -5) .style('opacity', 0) // udpate $$.xgridLines = xgridLineEnter.merge(xgridLine) // done in d3.transition() of the end of this function // exit xgridLine .exit() .transition() .duration(duration) .style('opacity', 0) .remove() // Y-Grid if (config.grid_y_show) { $$.updateYGrid() } ygridLine = main .select('.' + CLASS.ygridLines) .selectAll('.' + CLASS.ygridLine) .data(config.grid_y_lines) // enter ygridLineEnter = ygridLine .enter() .append('g') .attr('class', function(d) { return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '') }) ygridLineEnter .append('line') .attr('x1', config.axis_rotated ? yv : 0) .attr('x2', config.axis_rotated ? yv : $$.width) .attr('y1', config.axis_rotated ? 0 : yv) .attr('y2', config.axis_rotated ? $$.height : yv) .style('opacity', 0) ygridLineEnter .append('text') .attr('text-anchor', $$.gridTextAnchor) .attr('transform', config.axis_rotated ? 'rotate(-90)' : '') .attr('x', config.axis_rotated ? xGridTextX : yGridTextX) .attr('y', yv) .attr('dx', $$.gridTextDx) .attr('dy', -5) .style('opacity', 0) // update $$.ygridLines = ygridLineEnter.merge(ygridLine) $$.ygridLines .select('line') .transition() .duration(duration) .attr('x1', config.axis_rotated ? yv : 0) .attr('x2', config.axis_rotated ? yv : $$.width) .attr('y1', config.axis_rotated ? 0 : yv) .attr('y2', config.axis_rotated ? $$.height : yv) .style('opacity', 1) $$.ygridLines .select('text') .transition() .duration(duration) .attr( 'x', config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$) ) .attr('y', yv) .text(function(d) { return d.text }) .style('opacity', 1) // exit ygridLine .exit() .transition() .duration(duration) .style('opacity', 0) .remove() } ChartInternal.prototype.redrawGrid = function(withTransition, transition) { var $$ = this, config = $$.config, xv = $$.xv.bind($$), lines = $$.xgridLines.select('line'), texts = $$.xgridLines.select('text') return [ (withTransition ? lines.transition(transition) : lines) .attr('x1', config.axis_rotated ? 0 : xv) .attr('x2', config.axis_rotated ? $$.width : xv) .attr('y1', config.axis_rotated ? xv : 0) .attr('y2', config.axis_rotated ? xv : $$.height) .style('opacity', 1), (withTransition ? texts.transition(transition) : texts) .attr( 'x', config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$) ) .attr('y', xv) .text(function(d) { return d.text }) .style('opacity', 1) ] } ChartInternal.prototype.showXGridFocus = function(selectedData) { var $$ = this, config = $$.config, dataToShow = selectedData.filter(function(d) { return d && isValue(d.value) }), focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus), xx = $$.xx.bind($$) if (!config.tooltip_show) { return } // Hide when stanford plot exists if ($$.hasType('stanford') || $$.hasArcType()) { return } focusEl .style('visibility', 'visible') .data([dataToShow[0]]) .attr(config.axis_rotated ? 'y1' : 'x1', xx) .attr(config.axis_rotated ? 'y2' : 'x2', xx) $$.smoothLines(focusEl, 'grid') } ChartInternal.prototype.hideXGridFocus = function() { this.main.select('line.' + CLASS.xgridFocus).style('visibility', 'hidden') } ChartInternal.prototype.updateXgridFocus = function() { var $$ = this, config = $$.config $$.main .select('line.' + CLASS.xgridFocus) .attr('x1', config.axis_rotated ? 0 : -10) .attr('x2', config.axis_rotated ? $$.width : -10) .attr('y1', config.axis_rotated ? -10 : 0) .attr('y2', config.axis_rotated ? -10 : $$.height) } ChartInternal.prototype.generateGridData = function(type, scale) { var $$ = this, gridData = [], xDomain, firstYear, lastYear, i, tickNum = $$.main .select('.' + CLASS.axisX) .selectAll('.tick') .size() if (type === 'year') { xDomain = $$.getXDomain() firstYear = xDomain[0].getFullYear() lastYear = xDomain[1].getFullYear() for (i = firstYear; i <= lastYear; i++) { gridData.push(new Date(i + '-01-01 00:00:00')) } } else { gridData = scale.ticks(10) if (gridData.length > tickNum) { // use only int gridData = gridData.filter(function(d) { return ('' + d).indexOf('.') < 0 }) } } return gridData } ChartInternal.prototype.getGridFilterToRemove = function(params) { return params ? function(line) { var found = false ;[].concat(params).forEach(function(param) { if ( ('value' in param && line.value === param.value) || ('class' in param && line['class'] === param['class']) ) { found = true } }) return found } : function() { return true } } ChartInternal.prototype.removeGridLines = function(params, forX) { var $$ = this, config = $$.config, toRemove = $$.getGridFilterToRemove(params), toShow = function(line) { return !toRemove(line) }, classLines = forX ? CLASS.xgridLines : CLASS.ygridLines, classLine = forX ? CLASS.xgridLine : CLASS.ygridLine $$.main .select('.' + classLines) .selectAll('.' + classLine) .filter(toRemove) .transition() .duration(config.transition_duration) .style('opacity', 0) .remove() if (forX) { config.grid_x_lines = config.grid_x_lines.filter(toShow) } else { config.grid_y_lines = config.grid_y_lines.filter(toShow) } }