UNPKG

@antv/g2plot

Version:

G2 Plot, a market of plots built with the Grammar of Graphics'

166 lines 6.39 kB
import { __assign } from "tslib"; import { each, deepMix, minBy, maxBy } from '@antv/util'; import { getScale } from '@antv/scale'; import { regressionLinear, regressionExp, regressionLoess, regressionLog, regressionPoly, regressionPow, regressionQuad, } from 'd3-regression'; import { getSplinePath } from '../../../util/path'; var REGRESSION_MAP = { exp: regressionExp, linear: regressionLinear, loess: regressionLoess, log: regressionLog, poly: regressionPoly, pow: regressionPow, quad: regressionQuad, }; function se95(p, n) { return Math.sqrt((p * (1 - p)) / n) * 1.96; } var Quadrant = /** @class */ (function () { function Quadrant(cfg) { var defaultOptions = { type: 'linear', style: { stroke: '#9ba29a', lineWidth: 2, opacity: 0.5, lineJoin: 'round', lineCap: 'round', }, showConfidence: false, confidenceStyle: { fill: '#ccc', opacity: 0.1, }, }; this.options = deepMix({}, defaultOptions, cfg); this.view = this.options.view; this.init(); } Quadrant.prototype.init = function () { // 处理数据 var _a = this.options.plotOptions, xField = _a.xField, yField = _a.yField, data = _a.data; var reg = REGRESSION_MAP[this.options.type]() .x(function (d) { return d[xField]; }) .y(function (d) { return d[yField]; }); this.data = this.processData(reg(data)); // 创建container this.container = this.view.get('backgroundGroup').addGroup(); }; Quadrant.prototype.render = function () { var scales = this.view.get('scales'); var xscale_view = scales[this.options.plotOptions.xField]; var yscale_view = scales[this.options.plotOptions.yField]; var coord = this.view.get('coord'); var trendlineData = this.data.trendlineData; // 创建图形绘制的scale var LinearScale = getScale('linear'); var xRange = this.adjustScale(xscale_view, trendlineData, 'x'); var xScale = new LinearScale({ min: xRange.min, max: xRange.max, nice: xscale_view.nice, }); var yRange = this.adjustScale(yscale_view, trendlineData, 'y'); var yScale = new LinearScale({ min: yRange.min, max: yRange.max, nice: yscale_view.nice, }); // 绘制置信区间曲线 if (this.options.showConfidence) { var confidencePath = this.getConfidencePath(xScale, yScale, coord); this.container.addShape('path', { attrs: __assign({ path: confidencePath }, this.options.confidenceStyle), }); } // 绘制trendline var points = this.getTrendlinePoints(xScale, yScale, coord); var constraint = [ [0, 0], [1, 1], ]; var path = getSplinePath(points, false, constraint); this.shape = this.container.addShape('path', { attrs: __assign({ path: path }, this.options.style), }); }; Quadrant.prototype.clear = function () { if (this.container) { this.container.clear(); } }; Quadrant.prototype.destroy = function () { if (this.container) { this.container.destroy(); } }; Quadrant.prototype.processData = function (data) { var trendline = []; var confidence = []; each(data, function (d) { trendline.push({ x: d[0], y: d[1] }); var conf = se95(data.rSquared, d[1]); confidence.push({ x: d[0], y0: d[1] - conf, y1: d[1] + conf }); }); return { trendlineData: trendline, confidenceData: confidence }; }; Quadrant.prototype.getTrendlinePoints = function (xScale, yScale, coord) { var points = []; each(this.data.trendlineData, function (d) { var xRatio = xScale.scale(d.x); var yRatio = yScale.scale(d.y); var x = coord.start.x + coord.width * xRatio; var y = coord.start.y - coord.height * yRatio; points.push({ x: x, y: y }); }); return points; }; Quadrant.prototype.getConfidencePath = function (xScale, yScale, coord) { var upperPoints = []; var lowerPoints = []; var path = []; each(this.data.confidenceData, function (d) { var xRatio = xScale.scale(d.x); var y0Ratio = yScale.scale(d.y0); var y1Ratio = yScale.scale(d.y1); var x = coord.start.x + coord.width * xRatio; var y0 = coord.start.y - coord.height * y0Ratio; var y1 = coord.start.y - coord.height * y1Ratio; upperPoints.push({ x: x, y: y0 }); lowerPoints.push({ x: x, y: y1 }); }); for (var i = 0; i < upperPoints.length; i++) { var flag = i === 0 ? 'M' : 'L'; var p = upperPoints[i]; if (!isNaN(p.x) && !isNaN(p.y)) { path.push([flag, p.x, p.y]); } } for (var j = lowerPoints.length - 1; j > 0; j--) { var p = lowerPoints[j]; if (!isNaN(p.x) && !isNaN(p.y)) { path.push(['L', p.x, p.y]); } } return path; }; Quadrant.prototype.adjustScale = function (viewScale, trendlineData, dim) { // 处理用户自行配置min max的情况 var min = viewScale.min, max = viewScale.max; var _a = this.options.plotOptions, data = _a.data, xField = _a.xField, yField = _a.yField; var field = dim === 'x' ? xField : yField; var dataMin = minBy(data, field)[field]; var dataMax = maxBy(data, field)[field]; var minRatio = (min - dataMin) / (dataMax - dataMin); var maxRatio = (max - dataMax) / (dataMax - dataMin); var trendMin = minBy(trendlineData, dim)[dim]; var trendMax = maxBy(trendlineData, dim)[dim]; return { min: trendMin + minRatio * (trendMax - trendMin), max: trendMax + maxRatio * (trendMax - trendMin), }; }; return Quadrant; }()); export default Quadrant; //# sourceMappingURL=trendline.js.map