import { ChartInternal } from './core' import { isFunction, sanitise } from './util' ChartInternal.prototype.isStanfordGraphType = function() { var $$ = this return $$.config.data_type === 'stanford' } ChartInternal.prototype.initStanfordData = function() { var $$ = this, d3 = $$.d3, config = $$.config, target = $$.data.targets[0], epochs, maxEpochs, minEpochs // Make larger values appear on top target.values.sort(compareEpochs) // Get array of epochs epochs = target.values.map(a => a.epochs) minEpochs = !isNaN(config.stanford_scaleMin) ? config.stanford_scaleMin : d3.min(epochs) maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs) if (minEpochs > maxEpochs) { throw Error('Number of minEpochs has to be smaller than maxEpochs') } target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5)) target.colorscale = d3 .scaleSequentialLog(target.colors) .domain([minEpochs, maxEpochs]) target.minEpochs = minEpochs target.maxEpochs = maxEpochs } ChartInternal.prototype.getStanfordPointColor = function(d) { var $$ = this, target = $$.data.targets[0] return target.colorscale(d.epochs) } // http://jsfiddle.net/Xotic750/KtzLq/ ChartInternal.prototype.getCentroid = function(points) { var area = getRegionArea(points) var x = 0, y = 0, i, j, f, point1, point2 for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { point1 = points[i] point2 = points[j] f = point1.x * point2.y - point2.x * point1.y x += (point1.x + point2.x) * f y += (point1.y + point2.y) * f } f = area * 6 return { x: x / f, y: y / f } } ChartInternal.prototype.getStanfordTooltipTitle = function(d) { var $$ = this, labelX = $$.axis.getLabelText('x'), labelY = $$.axis.getLabelText('y') return ` ${labelX ? sanitise(labelX) : 'x'}${ d.x } ${labelY ? sanitise(labelY) : 'y'}${ d.value } ` } ChartInternal.prototype.countEpochsInRegion = function(region) { var $$ = this, target = $$.data.targets[0], total, count total = target.values.reduce( (accumulator, currentValue) => accumulator + Number(currentValue.epochs), 0 ) count = target.values.reduce((accumulator, currentValue) => { if (pointInRegion(currentValue, region)) { return accumulator + Number(currentValue.epochs) } return accumulator }, 0) return { value: count, percentage: count !== 0 ? ((count / total) * 100).toFixed(1) : 0 } } export var getRegionArea = function(points) { // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript var area = 0, i, j, point1, point2 for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) { point1 = points[i] point2 = points[j] area += point1.x * point2.y area -= point1.y * point2.x } area /= 2 return area } export var pointInRegion = function(point, region) { // thanks to: http://bl.ocks.org/bycoffe/5575904 // ray-casting algorithm based on // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html let xi, yi, yj, xj, intersect, x = point.x, y = point.value, inside = false for (let i = 0, j = region.length - 1; i < region.length; j = i++) { xi = region[i].x yi = region[i].y xj = region[j].x yj = region[j].y intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi if (intersect) { inside = !inside } } return inside } export var compareEpochs = function(a, b) { if (a.epochs < b.epochs) { return -1 } if (a.epochs > b.epochs) { return 1 } return 0 }