VennSeries.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. /* *
  2. *
  3. * Experimental Highcharts module which enables visualization of a Venn
  4. * diagram.
  5. *
  6. * (c) 2016-2021 Highsoft AS
  7. * Authors: Jon Arild Nygard
  8. *
  9. * Layout algorithm by Ben Frederickson:
  10. * https://www.benfrederickson.com/better-venn-diagrams/
  11. *
  12. * License: www.highcharts.com/license
  13. *
  14. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  15. *
  16. * */
  17. 'use strict';
  18. var __extends = (this && this.__extends) || (function () {
  19. var extendStatics = function (d, b) {
  20. extendStatics = Object.setPrototypeOf ||
  21. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  22. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  23. return extendStatics(d, b);
  24. };
  25. return function (d, b) {
  26. extendStatics(d, b);
  27. function __() { this.constructor = d; }
  28. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  29. };
  30. })();
  31. import A from '../../Core/Animation/AnimationUtilities.js';
  32. var animObject = A.animObject;
  33. import Color from '../../Core/Color/Color.js';
  34. var color = Color.parse;
  35. import GeometryMixin from '../../Mixins/Geometry.js';
  36. var getCenterOfPoints = GeometryMixin.getCenterOfPoints, getDistanceBetweenPoints = GeometryMixin.getDistanceBetweenPoints;
  37. import GeometryCirclesModule from '../../Mixins/GeometryCircles.js';
  38. var getAreaOfCircle = GeometryCirclesModule.getAreaOfCircle, getAreaOfIntersectionBetweenCircles = GeometryCirclesModule.getAreaOfIntersectionBetweenCircles, getCircleCircleIntersection = GeometryCirclesModule.getCircleCircleIntersection, getCirclesIntersectionPolygon = GeometryCirclesModule.getCirclesIntersectionPolygon, getOverlapBetweenCirclesByDistance = GeometryCirclesModule.getOverlapBetweenCircles, isCircle1CompletelyOverlappingCircle2 = GeometryCirclesModule.isCircle1CompletelyOverlappingCircle2, isPointInsideAllCircles = GeometryCirclesModule.isPointInsideAllCircles, isPointInsideCircle = GeometryCirclesModule.isPointInsideCircle, isPointOutsideAllCircles = GeometryCirclesModule.isPointOutsideAllCircles;
  39. import NelderMeadMixin from '../../Mixins/NelderMead.js';
  40. var nelderMead = NelderMeadMixin.nelderMead;
  41. import palette from '../../Core/Color/Palette.js';
  42. import SeriesRegistry from '../../Core/Series/SeriesRegistry.js';
  43. var ScatterSeries = SeriesRegistry.seriesTypes.scatter;
  44. import VennPoint from './VennPoint.js';
  45. import VennUtils from './VennUtils.js';
  46. import U from '../../Core/Utilities.js';
  47. var addEvent = U.addEvent, extend = U.extend, isArray = U.isArray, isNumber = U.isNumber, isObject = U.isObject, isString = U.isString, merge = U.merge;
  48. /* *
  49. *
  50. * Class
  51. *
  52. * */
  53. /**
  54. * @private
  55. * @class
  56. * @name Highcharts.seriesTypes.venn
  57. *
  58. * @augments Highcharts.Series
  59. */
  60. var VennSeries = /** @class */ (function (_super) {
  61. __extends(VennSeries, _super);
  62. function VennSeries() {
  63. /* *
  64. *
  65. * Static Properties
  66. *
  67. * */
  68. var _this = _super !== null && _super.apply(this, arguments) || this;
  69. /* *
  70. *
  71. * Properties
  72. *
  73. * */
  74. _this.data = void 0;
  75. _this.mapOfIdToRelation = void 0;
  76. _this.options = void 0;
  77. _this.points = void 0;
  78. return _this;
  79. /* eslint-enable valid-jsdoc */
  80. }
  81. /* *
  82. *
  83. * Static Functions
  84. *
  85. * */
  86. /**
  87. * Finds the optimal label position by looking for a position that has a low
  88. * distance from the internal circles, and as large possible distane to the
  89. * external circles.
  90. * @private
  91. * @todo Optimize the intial position.
  92. * @todo Add unit tests.
  93. * @param {Array<Highcharts.CircleObject>} internal
  94. * Internal circles.
  95. * @param {Array<Highcharts.CircleObject>} external
  96. * External circles.
  97. * @return {Highcharts.PositionObject}
  98. * Returns the found position.
  99. */
  100. VennSeries.getLabelPosition = function (internal, external) {
  101. // Get the best label position within the internal circles.
  102. var best = internal.reduce(function (best, circle) {
  103. var d = circle.r / 2;
  104. // Give a set of points with the circle to evaluate as the best
  105. // label position.
  106. return [
  107. { x: circle.x, y: circle.y },
  108. { x: circle.x + d, y: circle.y },
  109. { x: circle.x - d, y: circle.y },
  110. { x: circle.x, y: circle.y + d },
  111. { x: circle.x, y: circle.y - d }
  112. ]
  113. // Iterate the given points and return the one with the largest
  114. // margin.
  115. .reduce(function (best, point) {
  116. var margin = VennUtils.getMarginFromCircles(point, internal, external);
  117. // If the margin better than the current best, then update
  118. // sbest.
  119. if (best.margin < margin) {
  120. best.point = point;
  121. best.margin = margin;
  122. }
  123. return best;
  124. }, best);
  125. }, {
  126. point: void 0,
  127. margin: -Number.MAX_VALUE
  128. }).point;
  129. // Use nelder mead to optimize the initial label position.
  130. var optimal = nelderMead(function (p) {
  131. return -(VennUtils.getMarginFromCircles({ x: p[0], y: p[1] }, internal, external));
  132. }, [best.x, best.y]);
  133. // Update best to be the point which was found to have the best margin.
  134. best = {
  135. x: optimal[0],
  136. y: optimal[1]
  137. };
  138. if (!(isPointInsideAllCircles(best, internal) &&
  139. isPointOutsideAllCircles(best, external))) {
  140. // If point was either outside one of the internal, or inside one of
  141. // the external, then it was invalid and should use a fallback.
  142. if (internal.length > 1) {
  143. best = getCenterOfPoints(getCirclesIntersectionPolygon(internal));
  144. }
  145. else {
  146. best = {
  147. x: internal[0].x,
  148. y: internal[0].y
  149. };
  150. }
  151. }
  152. // Return the best point.
  153. return best;
  154. };
  155. /**
  156. * Calulates data label values for a given relations object.
  157. *
  158. * @private
  159. * @todo add unit tests
  160. * @param {Highcharts.VennRelationObject} relation A relations object.
  161. * @param {Array<Highcharts.VennRelationObject>} setRelations The list of
  162. * relations that is a set.
  163. * @return {Highcharts.VennLabelValuesObject}
  164. * Returns an object containing position and width of the label.
  165. */
  166. VennSeries.getLabelValues = function (relation, setRelations) {
  167. var sets = relation.sets;
  168. // Create a list of internal and external circles.
  169. var data = setRelations.reduce(function (data, set) {
  170. // If the set exists in this relation, then it is internal,
  171. // otherwise it will be external.
  172. var isInternal = sets.indexOf(set.sets[0]) > -1;
  173. var property = isInternal ? 'internal' : 'external';
  174. // Add the circle to the list.
  175. data[property].push(set.circle);
  176. return data;
  177. }, {
  178. internal: [],
  179. external: []
  180. });
  181. // Filter out external circles that are completely overlapping all
  182. // internal
  183. data.external = data.external.filter(function (externalCircle) {
  184. return data.internal.some(function (internalCircle) {
  185. return !isCircle1CompletelyOverlappingCircle2(externalCircle, internalCircle);
  186. });
  187. });
  188. // Calulate the label position.
  189. var position = VennSeries.getLabelPosition(data.internal, data.external);
  190. // Calculate the label width
  191. var width = VennUtils.getLabelWidth(position, data.internal, data.external);
  192. return {
  193. position: position,
  194. width: width
  195. };
  196. };
  197. /**
  198. * Calculates the positions, and the label values of all the sets in the
  199. * venn diagram.
  200. *
  201. * @private
  202. * @todo Add support for constrained MDS.
  203. * @param {Array<Highchats.VennRelationObject>} relations
  204. * List of the overlap between two or more sets, or the size of a single
  205. * sset.
  206. * @return {Highcharts.Dictionary<*>}
  207. * List of circles and their calculated positions.
  208. */
  209. VennSeries.layout = function (relations) {
  210. var mapOfIdToShape = {};
  211. var mapOfIdToLabelValues = {};
  212. // Calculate best initial positions by using greedy layout.
  213. if (relations.length > 0) {
  214. var mapOfIdToCircles_1 = VennUtils.layoutGreedyVenn(relations);
  215. var setRelations_1 = relations.filter(VennUtils.isSet);
  216. relations
  217. .forEach(function (relation) {
  218. var sets = relation.sets;
  219. var id = sets.join();
  220. // Get shape from map of circles, or calculate intersection.
  221. var shape = VennUtils.isSet(relation) ?
  222. mapOfIdToCircles_1[id] :
  223. getAreaOfIntersectionBetweenCircles(sets.map(function (set) {
  224. return mapOfIdToCircles_1[set];
  225. }));
  226. // Calculate label values if the set has a shape
  227. if (shape) {
  228. mapOfIdToShape[id] = shape;
  229. mapOfIdToLabelValues[id] = VennSeries.getLabelValues(relation, setRelations_1);
  230. }
  231. });
  232. }
  233. return { mapOfIdToShape: mapOfIdToShape, mapOfIdToLabelValues: mapOfIdToLabelValues };
  234. };
  235. /**
  236. * Calculates the proper scale to fit the cloud inside the plotting area.
  237. * @private
  238. * @todo add unit test
  239. * @param {number} targetWidth
  240. * Width of target area.
  241. * @param {number} targetHeight
  242. * Height of target area.
  243. * @param {Highcharts.PolygonBoxObject} field
  244. * The playing field.
  245. * @return {Highcharts.Dictionary<number>}
  246. * Returns the value to scale the playing field up to the size of the target
  247. * area, and center of x and y.
  248. */
  249. VennSeries.getScale = function (targetWidth, targetHeight, field) {
  250. var height = field.bottom - field.top, // top is smaller than bottom
  251. width = field.right - field.left, scaleX = width > 0 ? 1 / width * targetWidth : 1, scaleY = height > 0 ? 1 / height * targetHeight : 1, adjustX = (field.right + field.left) / 2, adjustY = (field.top + field.bottom) / 2, scale = Math.min(scaleX, scaleY);
  252. return {
  253. scale: scale,
  254. centerX: targetWidth / 2 - adjustX * scale,
  255. centerY: targetHeight / 2 - adjustY * scale
  256. };
  257. };
  258. /**
  259. * If a circle is outside a give field, then the boundaries of the field is
  260. * adjusted accordingly. Modifies the field object which is passed as the
  261. * first parameter.
  262. * @private
  263. * @todo NOTE: Copied from wordcloud, can probably be unified.
  264. * @param {Highcharts.PolygonBoxObject} field
  265. * The bounding box of a playing field.
  266. * @param {Highcharts.CircleObject} circle
  267. * The bounding box for a placed point.
  268. * @return {Highcharts.PolygonBoxObject}
  269. * Returns a modified field object.
  270. */
  271. VennSeries.updateFieldBoundaries = function (field, circle) {
  272. var left = circle.x - circle.r, right = circle.x + circle.r, bottom = circle.y + circle.r, top = circle.y - circle.r;
  273. // TODO improve type checking.
  274. if (!isNumber(field.left) || field.left > left) {
  275. field.left = left;
  276. }
  277. if (!isNumber(field.right) || field.right < right) {
  278. field.right = right;
  279. }
  280. if (!isNumber(field.top) || field.top > top) {
  281. field.top = top;
  282. }
  283. if (!isNumber(field.bottom) || field.bottom < bottom) {
  284. field.bottom = bottom;
  285. }
  286. return field;
  287. };
  288. /* *
  289. *
  290. * Functions
  291. *
  292. * */
  293. /* eslint-disable valid-jsdoc */
  294. VennSeries.prototype.animate = function (init) {
  295. if (!init) {
  296. var series = this, animOptions = animObject(series.options.animation);
  297. series.points.forEach(function (point) {
  298. var args = point.shapeArgs;
  299. if (point.graphic && args) {
  300. var attr = {}, animate = {};
  301. if (args.d) {
  302. // If shape is a path, then animate opacity.
  303. attr.opacity = 0.001;
  304. }
  305. else {
  306. // If shape is a circle, then animate radius.
  307. attr.r = 0;
  308. animate.r = args.r;
  309. }
  310. point.graphic
  311. .attr(attr)
  312. .animate(animate, animOptions);
  313. // If shape is path, then fade it in after the circles
  314. // animation
  315. if (args.d) {
  316. setTimeout(function () {
  317. if (point && point.graphic) {
  318. point.graphic.animate({
  319. opacity: 1
  320. });
  321. }
  322. }, animOptions.duration);
  323. }
  324. }
  325. }, series);
  326. }
  327. };
  328. /**
  329. * Draw the graphics for each point.
  330. * @private
  331. */
  332. VennSeries.prototype.drawPoints = function () {
  333. var series = this,
  334. // Series properties
  335. chart = series.chart, group = series.group, points = series.points || [],
  336. // Chart properties
  337. renderer = chart.renderer;
  338. // Iterate all points and calculate and draw their graphics.
  339. points.forEach(function (point) {
  340. var attribs = {
  341. zIndex: isArray(point.sets) ? point.sets.length : 0
  342. }, shapeArgs = point.shapeArgs;
  343. // Add point attribs
  344. if (!chart.styledMode) {
  345. extend(attribs, series.pointAttribs(point, point.state));
  346. }
  347. // Draw the point graphic.
  348. point.draw({
  349. isNew: !point.graphic,
  350. animatableAttribs: shapeArgs,
  351. attribs: attribs,
  352. group: group,
  353. renderer: renderer,
  354. shapeType: shapeArgs && shapeArgs.d ? 'path' : 'circle'
  355. });
  356. });
  357. };
  358. VennSeries.prototype.init = function () {
  359. ScatterSeries.prototype.init.apply(this, arguments);
  360. // Venn's opacity is a different option from other series
  361. delete this.opacity;
  362. };
  363. /**
  364. * Calculates the style attributes for a point. The attributes can vary
  365. * depending on the state of the point.
  366. * @private
  367. * @param {Highcharts.Point} point
  368. * The point which will get the resulting attributes.
  369. * @param {string} [state]
  370. * The state of the point.
  371. * @return {Highcharts.SVGAttributes}
  372. * Returns the calculated attributes.
  373. */
  374. VennSeries.prototype.pointAttribs = function (point, state) {
  375. var series = this, seriesOptions = series.options || {}, pointOptions = point && point.options || {}, stateOptions = (state && seriesOptions.states[state]) || {}, options = merge(seriesOptions, { color: point && point.color }, pointOptions, stateOptions);
  376. // Return resulting values for the attributes.
  377. return {
  378. 'fill': color(options.color)
  379. .brighten(options.brightness)
  380. .get(),
  381. // Set opacity directly to the SVG element, not to pattern #14372.
  382. opacity: options.opacity,
  383. 'stroke': options.borderColor,
  384. 'stroke-width': options.borderWidth,
  385. 'dashstyle': options.borderDashStyle
  386. };
  387. };
  388. VennSeries.prototype.translate = function () {
  389. var chart = this.chart;
  390. this.processedXData = this.xData;
  391. this.generatePoints();
  392. // Process the data before passing it into the layout function.
  393. var relations = VennUtils.processVennData(this.options.data);
  394. // Calculate the positions of each circle.
  395. var _a = VennSeries.layout(relations), mapOfIdToShape = _a.mapOfIdToShape, mapOfIdToLabelValues = _a.mapOfIdToLabelValues;
  396. // Calculate the scale, and center of the plot area.
  397. var field = Object.keys(mapOfIdToShape)
  398. .filter(function (key) {
  399. var shape = mapOfIdToShape[key];
  400. return shape && isNumber(shape.r);
  401. })
  402. .reduce(function (field, key) {
  403. return VennSeries.updateFieldBoundaries(field, mapOfIdToShape[key]);
  404. }, { top: 0, bottom: 0, left: 0, right: 0 }), scaling = VennSeries.getScale(chart.plotWidth, chart.plotHeight, field), scale = scaling.scale, centerX = scaling.centerX, centerY = scaling.centerY;
  405. // Iterate all points and calculate and draw their graphics.
  406. this.points.forEach(function (point) {
  407. var sets = isArray(point.sets) ? point.sets : [], id = sets.join(), shape = mapOfIdToShape[id], shapeArgs, dataLabelValues = mapOfIdToLabelValues[id] || {}, dataLabelWidth = dataLabelValues.width, dataLabelPosition = dataLabelValues.position, dlOptions = point.options && point.options.dataLabels;
  408. if (shape) {
  409. if (shape.r) {
  410. shapeArgs = {
  411. x: centerX + shape.x * scale,
  412. y: centerY + shape.y * scale,
  413. r: shape.r * scale
  414. };
  415. }
  416. else if (shape.d) {
  417. var d = shape.d;
  418. d.forEach(function (seg) {
  419. if (seg[0] === 'M') {
  420. seg[1] = centerX + seg[1] * scale;
  421. seg[2] = centerY + seg[2] * scale;
  422. }
  423. else if (seg[0] === 'A') {
  424. seg[1] = seg[1] * scale;
  425. seg[2] = seg[2] * scale;
  426. seg[6] = centerX + seg[6] * scale;
  427. seg[7] = centerY + seg[7] * scale;
  428. }
  429. });
  430. shapeArgs = { d: d };
  431. }
  432. // Scale the position for the data label.
  433. if (dataLabelPosition) {
  434. dataLabelPosition.x = centerX + dataLabelPosition.x * scale;
  435. dataLabelPosition.y = centerY + dataLabelPosition.y * scale;
  436. }
  437. else {
  438. dataLabelPosition = {};
  439. }
  440. if (isNumber(dataLabelWidth)) {
  441. dataLabelWidth = Math.round(dataLabelWidth * scale);
  442. }
  443. }
  444. point.shapeArgs = shapeArgs;
  445. // Placement for the data labels
  446. if (dataLabelPosition && shapeArgs) {
  447. point.plotX = dataLabelPosition.x;
  448. point.plotY = dataLabelPosition.y;
  449. }
  450. // Add width for the data label
  451. if (dataLabelWidth && shapeArgs) {
  452. point.dlOptions = merge(true, {
  453. style: {
  454. width: dataLabelWidth
  455. }
  456. }, isObject(dlOptions) && dlOptions);
  457. }
  458. // Set name for usage in tooltip and in data label.
  459. point.name = point.options.name || sets.join('∩');
  460. });
  461. };
  462. /**
  463. * A Venn diagram displays all possible logical relations between a
  464. * collection of different sets. The sets are represented by circles, and
  465. * the relation between the sets are displayed by the overlap or lack of
  466. * overlap between them. The venn diagram is a special case of Euler
  467. * diagrams, which can also be displayed by this series type.
  468. *
  469. * @sample {highcharts} highcharts/demo/venn-diagram/
  470. * Venn diagram
  471. * @sample {highcharts} highcharts/demo/euler-diagram/
  472. * Euler diagram
  473. *
  474. * @extends plotOptions.scatter
  475. * @excluding connectEnds, connectNulls, cropThreshold, dragDrop,
  476. * findNearestPointBy, getExtremesFromAll, jitter, label,
  477. * linecap, lineWidth, linkedTo, marker, negativeColor,
  478. * pointInterval, pointIntervalUnit, pointPlacement,
  479. * pointStart, softThreshold, stacking, steps, threshold,
  480. * xAxis, yAxis, zoneAxis, zones, dataSorting, boostThreshold,
  481. * boostBlending
  482. * @product highcharts
  483. * @requires modules/venn
  484. * @optionparent plotOptions.venn
  485. */
  486. VennSeries.defaultOptions = merge(ScatterSeries.defaultOptions, {
  487. borderColor: palette.neutralColor20,
  488. borderDashStyle: 'solid',
  489. borderWidth: 1,
  490. brighten: 0,
  491. clip: false,
  492. colorByPoint: true,
  493. dataLabels: {
  494. enabled: true,
  495. verticalAlign: 'middle',
  496. formatter: function () {
  497. return this.point.name;
  498. }
  499. },
  500. /**
  501. * @ignore-option
  502. * @private
  503. */
  504. inactiveOtherPoints: true,
  505. marker: false,
  506. opacity: 0.75,
  507. showInLegend: false,
  508. states: {
  509. /**
  510. * @excluding halo
  511. */
  512. hover: {
  513. opacity: 1,
  514. borderColor: palette.neutralColor80
  515. },
  516. /**
  517. * @excluding halo
  518. */
  519. select: {
  520. color: palette.neutralColor20,
  521. borderColor: palette.neutralColor100,
  522. animation: false
  523. },
  524. inactive: {
  525. opacity: 0.075
  526. }
  527. },
  528. tooltip: {
  529. pointFormat: '{point.name}: {point.value}'
  530. }
  531. });
  532. return VennSeries;
  533. }(ScatterSeries));
  534. extend(VennSeries.prototype, {
  535. axisTypes: [],
  536. directTouch: true,
  537. isCartesian: false,
  538. pointArrayMap: ['value'],
  539. pointClass: VennPoint,
  540. utils: VennUtils
  541. });
  542. SeriesRegistry.registerSeriesType('venn', VennSeries);
  543. /* *
  544. *
  545. * Default Export
  546. *
  547. * */
  548. export default VennSeries;
  549. /* *
  550. *
  551. * API Options
  552. *
  553. * */
  554. /**
  555. * A `venn` series. If the [type](#series.venn.type) option is
  556. * not specified, it is inherited from [chart.type](#chart.type).
  557. *
  558. * @extends series,plotOptions.venn
  559. * @excluding connectEnds, connectNulls, cropThreshold, dataParser, dataURL,
  560. * findNearestPointBy, getExtremesFromAll, label, linecap, lineWidth,
  561. * linkedTo, marker, negativeColor, pointInterval, pointIntervalUnit,
  562. * pointPlacement, pointStart, softThreshold, stack, stacking, steps,
  563. * threshold, xAxis, yAxis, zoneAxis, zones, dataSorting,
  564. * boostThreshold, boostBlending
  565. * @product highcharts
  566. * @requires modules/venn
  567. * @apioption series.venn
  568. */
  569. /**
  570. * @type {Array<*>}
  571. * @extends series.scatter.data
  572. * @excluding marker, x, y
  573. * @product highcharts
  574. * @apioption series.venn.data
  575. */
  576. /**
  577. * The name of the point. Used in data labels and tooltip. If name is not
  578. * defined then it will default to the joined values in
  579. * [sets](#series.venn.sets).
  580. *
  581. * @sample {highcharts} highcharts/demo/venn-diagram/
  582. * Venn diagram
  583. * @sample {highcharts} highcharts/demo/euler-diagram/
  584. * Euler diagram
  585. *
  586. * @type {number}
  587. * @since 7.0.0
  588. * @product highcharts
  589. * @apioption series.venn.data.name
  590. */
  591. /**
  592. * The value of the point, resulting in a relative area of the circle, or area
  593. * of overlap between two sets in the venn or euler diagram.
  594. *
  595. * @sample {highcharts} highcharts/demo/venn-diagram/
  596. * Venn diagram
  597. * @sample {highcharts} highcharts/demo/euler-diagram/
  598. * Euler diagram
  599. *
  600. * @type {number}
  601. * @since 7.0.0
  602. * @product highcharts
  603. * @apioption series.venn.data.value
  604. */
  605. /**
  606. * The set or sets the options will be applied to. If a single entry is defined,
  607. * then it will create a new set. If more than one entry is defined, then it
  608. * will define the overlap between the sets in the array.
  609. *
  610. * @sample {highcharts} highcharts/demo/venn-diagram/
  611. * Venn diagram
  612. * @sample {highcharts} highcharts/demo/euler-diagram/
  613. * Euler diagram
  614. *
  615. * @type {Array<string>}
  616. * @since 7.0.0
  617. * @product highcharts
  618. * @apioption series.venn.data.sets
  619. */
  620. /**
  621. * @excluding halo
  622. * @apioption series.venn.states.hover
  623. */
  624. /**
  625. * @excluding halo
  626. * @apioption series.venn.states.select
  627. */
  628. ''; // detach doclets above
  629. /* eslint-disable no-invalid-this */
  630. // Modify final series options.
  631. addEvent(VennSeries, 'afterSetOptions', function (e) {
  632. var options = e.options, states = options.states;
  633. if (this.is('venn')) {
  634. // Explicitly disable all halo options.
  635. Object.keys(states).forEach(function (state) {
  636. states[state].halo = false;
  637. });
  638. }
  639. });