New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

chartjs-chart-sankey

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chartjs-chart-sankey - npm Package Compare versions

Comparing version 0.7.0 to 0.7.1

types/index.esm.d.ts

232

dist/chartjs-chart-sankey.esm.js
/*!
* chartjs-chart-sankey v0.7.0
* chartjs-chart-sankey v0.7.1
* https://github.com/kurkle/chartjs-chart-sankey#readme

@@ -10,2 +10,7 @@ * (c) 2021 Jukka Kurkela

/**
* @param nodes {Map<string, SankeyNode>}
* @param data {Array<SankeyDataPoint>}
* @return {number}
*/
function calculateX(nodes, data) {

@@ -37,2 +42,7 @@ const to = new Set(data.map(x => x.to));

/**
* @param keys {Array<string>}
* @param to {Set<string>}
* @return {Array<string>}
*/
function nextColumn(keys, to) {

@@ -43,7 +53,32 @@ const columnsNotInTo = keys.filter(key => !to.has(key));

/**
* @param x {any}
* @return {boolean}
*/
const defined = x => x !== undefined;
/**
* @param a {SankeyNode}
* @param b {SankeyNode}
* @return {number}
*/
const nodeByXY = (a, b) => a.x !== b.x ? a.x - b.x : a.y - b.y;
/**
* @param list {Array<FromToElement>}
* @param prop {string}
* @return {number}
*/
const nodeCount = (list, prop) => list.reduce((acc, cur) => acc + cur.node[prop].length + nodeCount(cur.node[prop], prop), 0);
/**
* @param prop {string}
* @return {function(FromToElement, FromToElement): number}
*/
const flowByNodeCount = (prop) => (a, b) => nodeCount(a.node[prop], prop) - nodeCount(b.node[prop], prop);
/**
* @param nodeArray {Array<SankeyNode>}
* @return {SankeyNode}
*/
function findLargestNode(nodeArray) {

@@ -53,2 +88,7 @@ return nodeArray.sort((a, b) => Math.max(b.in, b.out) - Math.max(a.in, a.out))[0];

/**
* @param node {SankeyNode}
* @param y {number}
* @return {number}
*/
function processFrom(node, y) {

@@ -65,2 +105,7 @@ node.from.sort(flowByNodeCount('from')).forEach(flow => {

/**
* @param node {SankeyNode}
* @param y {number}
* @return {number}
*/
function processTo(node, y) {

@@ -77,2 +122,7 @@ node.to.sort(flowByNodeCount('to')).forEach(flow => {

/**
* @param node {SankeyNode}
* @param value {number}
* @return {number}
*/
function setOrGetY(node, value) {

@@ -86,2 +136,7 @@ if (defined(node.y)) {

/**
* @param nodeArray {Array<SankeyNode>}
* @param maxX {number}
* @return {number}
*/
function processRest(nodeArray, maxX) {

@@ -121,2 +176,7 @@ const leftNodes = nodeArray.filter(node => node.x === 0);

/**
* @param nodeArray {Array<SankeyNode>}
* @param maxX {number}
* @return {number}
*/
function calculateY(nodeArray, maxX) {

@@ -131,2 +191,7 @@ const start = findLargestNode(nodeArray);

/**
* @param nodeArray {Array<SankeyNode>}
* @param maxX {number}
* @return {number}
*/
function calculateYUsingPriority(nodeArray, maxX) {

@@ -146,2 +211,7 @@ let maxY = 0;

/**
* @param nodeArray {Array<SankeyNode>}
* @param padding {number}
* @return {number}
*/
function addPadding(nodeArray, padding) {

@@ -179,2 +249,5 @@ let i = 1;

/**
* @param nodeArray {Array<SankeyNode>}
*/
function sortFlows(nodeArray) {

@@ -195,2 +268,8 @@ nodeArray.forEach(node => {

/**
* @param nodes {Map<string, SankeyNode>}
* @param data {Array<SankeyDataPoint>}
* @param priority {boolean}
* @return {{maxY: number, maxX: number}}
*/
function layout(nodes, data, priority) {

@@ -208,19 +287,36 @@ const nodeArray = [...nodes.values()];

function buildNodesFromFlows(data) {
/**
* @param data {Array<SankeyDataPoint>} Array of raw data elements
* @return {Map<string, SankeyNode>}
*/
function buildNodesFromRawData(data) {
const nodes = new Map();
for (let i = 0; i < data.length; i++) {
const d = data[i];
if (!nodes.has(d.from)) {
nodes.set(d.from, {key: d.from, in: 0, out: d.flow, from: [], to: [{key: d.to, flow: d.flow}]});
const {from, to, flow} = data[i];
if (!nodes.has(from)) {
nodes.set(from, {
key: from,
in: 0,
out: flow,
from: [],
to: [{key: to, flow: flow}],
});
} else {
const node = nodes.get(d.from);
node.out += d.flow;
node.to.push({key: d.to, flow: d.flow});
const node = nodes.get(from);
node.out += flow;
node.to.push({key: to, flow: flow});
}
if (!nodes.has(d.to)) {
nodes.set(d.to, {key: d.to, in: d.flow, out: 0, from: [{key: d.from, flow: d.flow}], to: []});
if (!nodes.has(to)) {
nodes.set(to, {
key: to,
in: flow,
out: 0,
from: [{key: from, flow: flow}],
to: [],
});
} else {
const node = nodes.get(d.to);
node.in += d.flow;
node.from.push({key: d.from, flow: d.flow});
const node = nodes.get(to);
node.in += flow;
node.from.push({key: from, flow: flow});
}

@@ -252,3 +348,7 @@ }

/**
* @param arr {Array<FromToElement>}
* @param key {string}
* @return {number}
*/
function getAddY(arr, key) {

@@ -264,3 +364,9 @@ for (let i = 0; i < arr.length; i++) {

class SankeyController extends DatasetController {
/**
* @param meta {ChartMeta<Flow, Element>}
* @param data {Array<SankeyDataPoint>} Array of original data elements
* @param start {number}
* @param count {number}
* @return {Array<SankeyParsedData>}
*/
parseObjectData(meta, data, start, count) {

@@ -273,4 +379,5 @@ // https://github.com/chartjs/Chart.js/pull/8379

const {xScale, yScale} = meta;
const parsed = [];
const nodes = me._nodes = buildNodesFromFlows(data);
const parsed = []; /* Array<SankeyParsedData> */
const nodes = me._nodes = buildNodesFromRawData(data);
/* getDataset() => SankeyControllerDatasetOptions */
const priority = me.getDataset().priority;

@@ -326,2 +433,8 @@ if (priority) {

/**
* @param elems {Array<Flow>}
* @param start {number}
* @param count {number}
* @param mode {"resize" | "reset" | "none" | "hide" | "show" | "normal" | "active"}
*/
updateElements(elems, start, count, mode) {

@@ -337,2 +450,3 @@ const me = this;

for (let i = start; i < start + count; i++) {
/* getParsed(idx: number) => SankeyParsedData */
const parsed = me.getParsed(i);

@@ -365,3 +479,3 @@ const custom = parsed._custom;

const nodes = me._nodes || new Map();
const dataset = me.getDataset();
const dataset = me.getDataset(); /* SankeyControllerDatasetOptions */
const borderWidth = valueOrDefault(dataset.borderWidth, 1);

@@ -395,2 +509,10 @@ const nodeWidth = valueOrDefault(dataset.nodeWidth, 10);

/**
* @param label {string}
* @param y {number}
* @param height {number}
* @param ctx {CanvasRenderingContext2D}
* @param textX {number}
* @private
*/
_drawLabel(label, y, height, ctx, textX) {

@@ -413,6 +535,10 @@ const lines = isNullOrUndef(label) ? [] : this.toTextLines(label);

// @todo move this in Chart.helpers.toTextLines
/**
* @param inputs {string | Array<string>}
* @return {Array<string>}
* @todo move this in Chart.helpers.toTextLines
*/
toTextLines(inputs) {
var lines = [];
var input;
let lines = [];
let input;

@@ -438,3 +564,3 @@ inputs = [].concat(inputs);

const nodes = me._nodes || new Map();
const dataset = me.getDataset();
const dataset = me.getDataset(); /* SankeyControllerDatasetOptions */
const {xScale, yScale} = me._cachedMeta;

@@ -462,9 +588,12 @@ const borderWidth = valueOrDefault(dataset.borderWidth, 1);

/**
* That's where the drawing process happens
*/
draw() {
const me = this;
const ctx = me._ctx;
const data = me.getMeta().data || [];
const data = me.getMeta().data || []; /* Array<Flow> */
for (let i = 0, ilen = data.length; i < ilen; ++i) {
const flow = data[i];
const flow = data[i]; /* Flow at index i */
flow.from.color = flow.options.colorFrom;

@@ -474,4 +603,6 @@ flow.to.color = flow.options.colorTo;

/* draw SankeyNodes on the canvas */
me._drawNodes();
/* draw Flow elements on the canvas */
for (let i = 0, ilen = data.length; i < ilen; ++i) {

@@ -481,2 +612,3 @@ data[i].draw(ctx);

/* draw labels (for SankeyNodes) on the canvas */
me._drawLabels();

@@ -578,2 +710,12 @@ }

/**
* @typedef {{x: number, y: number}} ControlPoint
* @typedef {{cp1: ControlPoint, cp2: ControlPoint}} ControlPoints
*
* @param x {number}
* @param y {number}
* @param x2 {number}
* @param y2 {number}
* @return {ControlPoints}
*/
const controlPoints = (x, y, x2, y2) => x < x2

@@ -589,5 +731,16 @@ ? {

/**
*
* @param p1 {ControlPoint}
* @param p2 {ControlPoint}
* @param t {number}
* @return {ControlPoint}
*/
const pointInLine = (p1, p2, t) => ({x: p1.x + t * (p2.x - p1.x), y: p1.y + t * (p2.y - p1.y)});
class Flow extends Element {
/**
* @param cfg {FlowConfig}
*/
constructor(cfg) {

@@ -608,2 +761,5 @@ super();

/**
* @param ctx {CanvasRenderingContext2D}
*/
draw(ctx) {

@@ -655,2 +811,8 @@ const me = this;

/**
* @param mouseX {number}
* @param mouseY {number}
* @param useFinalPosition {boolean}
* @return {boolean}
*/
inRange(mouseX, mouseY, useFinalPosition) {

@@ -674,2 +836,7 @@ const {x, y, x2, y2, height} = this.getProps(['x', 'y', 'x2', 'y2', 'height'], useFinalPosition);

/**
* @param mouseX {number}
* @param useFinalPosition {boolean}
* @return {boolean}
*/
inXRange(mouseX, useFinalPosition) {

@@ -680,2 +847,7 @@ const {x, x2} = this.getProps(['x', 'x2'], useFinalPosition);

/**
* @param mouseY {number}
* @param useFinalPosition {boolean}
* @return {boolean}
*/
inYRange(mouseY, useFinalPosition) {

@@ -688,2 +860,6 @@ const {y, y2, height} = this.getProps(['y', 'y2', 'height'], useFinalPosition);

/**
* @param useFinalPosition {boolean}
* @return {{x: number, y:number}}
*/
getCenterPoint(useFinalPosition) {

@@ -697,6 +873,10 @@ const {x, y, x2, y2, height} = this.getProps(['x', 'y', 'x2', 'y2', 'height'], useFinalPosition);

tooltipPosition() {
return this.getCenterPoint();
tooltipPosition(useFinalPosition) {
return this.getCenterPoint(useFinalPosition);
}
/**
* @param axis {"x" | "y"}
* @return {number}
*/
getRange(axis) {

@@ -703,0 +883,0 @@ return axis === 'x' ? this.width / 2 : this.height / 2;

/*!
* chartjs-chart-sankey v0.7.0
* chartjs-chart-sankey v0.7.1
* https://github.com/kurkle/chartjs-chart-sankey#readme

@@ -11,8 +11,9 @@ * (c) 2021 Jukka Kurkela

(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Chart, global.Chart.helpers));
}(this, (function (Chart, helpers) { 'use strict';
}(this, (function (chart_js, helpers) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var Chart__default = /*#__PURE__*/_interopDefaultLegacy(Chart);
/**
* @param nodes {Map<string, SankeyNode>}
* @param data {Array<SankeyDataPoint>}
* @return {number}
*/
function calculateX(nodes, data) {

@@ -44,2 +45,7 @@ const to = new Set(data.map(x => x.to));

/**
* @param keys {Array<string>}
* @param to {Set<string>}
* @return {Array<string>}
*/
function nextColumn(keys, to) {

@@ -50,7 +56,32 @@ const columnsNotInTo = keys.filter(key => !to.has(key));

/**
* @param x {any}
* @return {boolean}
*/
const defined = x => x !== undefined;
/**
* @param a {SankeyNode}
* @param b {SankeyNode}
* @return {number}
*/
const nodeByXY = (a, b) => a.x !== b.x ? a.x - b.x : a.y - b.y;
/**
* @param list {Array<FromToElement>}
* @param prop {string}
* @return {number}
*/
const nodeCount = (list, prop) => list.reduce((acc, cur) => acc + cur.node[prop].length + nodeCount(cur.node[prop], prop), 0);
/**
* @param prop {string}
* @return {function(FromToElement, FromToElement): number}
*/
const flowByNodeCount = (prop) => (a, b) => nodeCount(a.node[prop], prop) - nodeCount(b.node[prop], prop);
/**
* @param nodeArray {Array<SankeyNode>}
* @return {SankeyNode}
*/
function findLargestNode(nodeArray) {

@@ -60,2 +91,7 @@ return nodeArray.sort((a, b) => Math.max(b.in, b.out) - Math.max(a.in, a.out))[0];

/**
* @param node {SankeyNode}
* @param y {number}
* @return {number}
*/
function processFrom(node, y) {

@@ -72,2 +108,7 @@ node.from.sort(flowByNodeCount('from')).forEach(flow => {

/**
* @param node {SankeyNode}
* @param y {number}
* @return {number}
*/
function processTo(node, y) {

@@ -84,2 +125,7 @@ node.to.sort(flowByNodeCount('to')).forEach(flow => {

/**
* @param node {SankeyNode}
* @param value {number}
* @return {number}
*/
function setOrGetY(node, value) {

@@ -93,2 +139,7 @@ if (defined(node.y)) {

/**
* @param nodeArray {Array<SankeyNode>}
* @param maxX {number}
* @return {number}
*/
function processRest(nodeArray, maxX) {

@@ -128,2 +179,7 @@ const leftNodes = nodeArray.filter(node => node.x === 0);

/**
* @param nodeArray {Array<SankeyNode>}
* @param maxX {number}
* @return {number}
*/
function calculateY(nodeArray, maxX) {

@@ -138,2 +194,7 @@ const start = findLargestNode(nodeArray);

/**
* @param nodeArray {Array<SankeyNode>}
* @param maxX {number}
* @return {number}
*/
function calculateYUsingPriority(nodeArray, maxX) {

@@ -153,2 +214,7 @@ let maxY = 0;

/**
* @param nodeArray {Array<SankeyNode>}
* @param padding {number}
* @return {number}
*/
function addPadding(nodeArray, padding) {

@@ -186,2 +252,5 @@ let i = 1;

/**
* @param nodeArray {Array<SankeyNode>}
*/
function sortFlows(nodeArray) {

@@ -202,2 +271,8 @@ nodeArray.forEach(node => {

/**
* @param nodes {Map<string, SankeyNode>}
* @param data {Array<SankeyDataPoint>}
* @param priority {boolean}
* @return {{maxY: number, maxX: number}}
*/
function layout(nodes, data, priority) {

@@ -215,19 +290,36 @@ const nodeArray = [...nodes.values()];

function buildNodesFromFlows(data) {
/**
* @param data {Array<SankeyDataPoint>} Array of raw data elements
* @return {Map<string, SankeyNode>}
*/
function buildNodesFromRawData(data) {
const nodes = new Map();
for (let i = 0; i < data.length; i++) {
const d = data[i];
if (!nodes.has(d.from)) {
nodes.set(d.from, {key: d.from, in: 0, out: d.flow, from: [], to: [{key: d.to, flow: d.flow}]});
const {from, to, flow} = data[i];
if (!nodes.has(from)) {
nodes.set(from, {
key: from,
in: 0,
out: flow,
from: [],
to: [{key: to, flow: flow}],
});
} else {
const node = nodes.get(d.from);
node.out += d.flow;
node.to.push({key: d.to, flow: d.flow});
const node = nodes.get(from);
node.out += flow;
node.to.push({key: to, flow: flow});
}
if (!nodes.has(d.to)) {
nodes.set(d.to, {key: d.to, in: d.flow, out: 0, from: [{key: d.from, flow: d.flow}], to: []});
if (!nodes.has(to)) {
nodes.set(to, {
key: to,
in: flow,
out: 0,
from: [{key: from, flow: flow}],
to: [],
});
} else {
const node = nodes.get(d.to);
node.in += d.flow;
node.from.push({key: d.from, flow: d.flow});
const node = nodes.get(to);
node.in += flow;
node.from.push({key: from, flow: flow});
}

@@ -259,3 +351,7 @@ }

/**
* @param arr {Array<FromToElement>}
* @param key {string}
* @return {number}
*/
function getAddY(arr, key) {

@@ -270,4 +366,10 @@ for (let i = 0; i < arr.length; i++) {

class SankeyController extends Chart.DatasetController {
class SankeyController extends chart_js.DatasetController {
/**
* @param meta {ChartMeta<Flow, Element>}
* @param data {Array<SankeyDataPoint>} Array of original data elements
* @param start {number}
* @param count {number}
* @return {Array<SankeyParsedData>}
*/
parseObjectData(meta, data, start, count) {

@@ -280,4 +382,5 @@ // https://github.com/chartjs/Chart.js/pull/8379

const {xScale, yScale} = meta;
const parsed = [];
const nodes = me._nodes = buildNodesFromFlows(data);
const parsed = []; /* Array<SankeyParsedData> */
const nodes = me._nodes = buildNodesFromRawData(data);
/* getDataset() => SankeyControllerDatasetOptions */
const priority = me.getDataset().priority;

@@ -333,2 +436,8 @@ if (priority) {

/**
* @param elems {Array<Flow>}
* @param start {number}
* @param count {number}
* @param mode {"resize" | "reset" | "none" | "hide" | "show" | "normal" | "active"}
*/
updateElements(elems, start, count, mode) {

@@ -344,2 +453,3 @@ const me = this;

for (let i = start; i < start + count; i++) {
/* getParsed(idx: number) => SankeyParsedData */
const parsed = me.getParsed(i);

@@ -372,3 +482,3 @@ const custom = parsed._custom;

const nodes = me._nodes || new Map();
const dataset = me.getDataset();
const dataset = me.getDataset(); /* SankeyControllerDatasetOptions */
const borderWidth = helpers.valueOrDefault(dataset.borderWidth, 1);

@@ -402,2 +512,10 @@ const nodeWidth = helpers.valueOrDefault(dataset.nodeWidth, 10);

/**
* @param label {string}
* @param y {number}
* @param height {number}
* @param ctx {CanvasRenderingContext2D}
* @param textX {number}
* @private
*/
_drawLabel(label, y, height, ctx, textX) {

@@ -420,6 +538,10 @@ const lines = helpers.isNullOrUndef(label) ? [] : this.toTextLines(label);

// @todo move this in Chart.helpers.toTextLines
/**
* @param inputs {string | Array<string>}
* @return {Array<string>}
* @todo move this in Chart.helpers.toTextLines
*/
toTextLines(inputs) {
var lines = [];
var input;
let lines = [];
let input;

@@ -445,3 +567,3 @@ inputs = [].concat(inputs);

const nodes = me._nodes || new Map();
const dataset = me.getDataset();
const dataset = me.getDataset(); /* SankeyControllerDatasetOptions */
const {xScale, yScale} = me._cachedMeta;

@@ -469,9 +591,12 @@ const borderWidth = helpers.valueOrDefault(dataset.borderWidth, 1);

/**
* That's where the drawing process happens
*/
draw() {
const me = this;
const ctx = me._ctx;
const data = me.getMeta().data || [];
const data = me.getMeta().data || []; /* Array<Flow> */
for (let i = 0, ilen = data.length; i < ilen; ++i) {
const flow = data[i];
const flow = data[i]; /* Flow at index i */
flow.from.color = flow.options.colorFrom;

@@ -481,4 +606,6 @@ flow.to.color = flow.options.colorTo;

/* draw SankeyNodes on the canvas */
me._drawNodes();
/* draw Flow elements on the canvas */
for (let i = 0, ilen = data.length; i < ilen; ++i) {

@@ -488,2 +615,3 @@ data[i].draw(ctx);

/* draw labels (for SankeyNodes) on the canvas */
me._drawLabels();

@@ -585,2 +713,12 @@ }

/**
* @typedef {{x: number, y: number}} ControlPoint
* @typedef {{cp1: ControlPoint, cp2: ControlPoint}} ControlPoints
*
* @param x {number}
* @param y {number}
* @param x2 {number}
* @param y2 {number}
* @return {ControlPoints}
*/
const controlPoints = (x, y, x2, y2) => x < x2

@@ -596,5 +734,16 @@ ? {

/**
*
* @param p1 {ControlPoint}
* @param p2 {ControlPoint}
* @param t {number}
* @return {ControlPoint}
*/
const pointInLine = (p1, p2, t) => ({x: p1.x + t * (p2.x - p1.x), y: p1.y + t * (p2.y - p1.y)});
class Flow extends Chart.Element {
class Flow extends chart_js.Element {
/**
* @param cfg {FlowConfig}
*/
constructor(cfg) {

@@ -615,2 +764,5 @@ super();

/**
* @param ctx {CanvasRenderingContext2D}
*/
draw(ctx) {

@@ -662,2 +814,8 @@ const me = this;

/**
* @param mouseX {number}
* @param mouseY {number}
* @param useFinalPosition {boolean}
* @return {boolean}
*/
inRange(mouseX, mouseY, useFinalPosition) {

@@ -681,2 +839,7 @@ const {x, y, x2, y2, height} = this.getProps(['x', 'y', 'x2', 'y2', 'height'], useFinalPosition);

/**
* @param mouseX {number}
* @param useFinalPosition {boolean}
* @return {boolean}
*/
inXRange(mouseX, useFinalPosition) {

@@ -687,2 +850,7 @@ const {x, x2} = this.getProps(['x', 'x2'], useFinalPosition);

/**
* @param mouseY {number}
* @param useFinalPosition {boolean}
* @return {boolean}
*/
inYRange(mouseY, useFinalPosition) {

@@ -695,2 +863,6 @@ const {y, y2, height} = this.getProps(['y', 'y2', 'height'], useFinalPosition);

/**
* @param useFinalPosition {boolean}
* @return {{x: number, y:number}}
*/
getCenterPoint(useFinalPosition) {

@@ -704,6 +876,10 @@ const {x, y, x2, y2, height} = this.getProps(['x', 'y', 'x2', 'y2', 'height'], useFinalPosition);

tooltipPosition() {
return this.getCenterPoint();
tooltipPosition(useFinalPosition) {
return this.getCenterPoint(useFinalPosition);
}
/**
* @param axis {"x" | "y"}
* @return {number}
*/
getRange(axis) {

@@ -721,4 +897,4 @@ return axis === 'x' ? this.width / 2 : this.height / 2;

Chart__default['default'].register(SankeyController, Flow);
chart_js.Chart.register(SankeyController, Flow);
})));

4

dist/chartjs-chart-sankey.min.js
/*!
* chartjs-chart-sankey v0.7.0
* chartjs-chart-sankey v0.7.1
* https://github.com/kurkle/chartjs-chart-sankey#readme

@@ -7,2 +7,2 @@ * (c) 2021 Jukka Kurkela

*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Chart,t.Chart.helpers)}(this,(function(t,e){"use strict";function o(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=o(t);function a(t,e){const o=t.filter((t=>!e.has(t)));return o.length?o:t.slice(0,1)}const n=t=>void 0!==t,s=(t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y,l=(t,e)=>t.reduce(((t,o)=>t+o.node[e].length+l(o.node[e],e)),0),i=t=>(e,o)=>l(e.node[t],t)-l(o.node[t],t);function c(t,e){return t.from.sort(i("from")).forEach((t=>{const o=t.node;n(o.y)||(o.y=e,e=Math.max(e+o.out,c(o,e)))})),e}function f(t,e){return t.to.sort(i("to")).forEach((t=>{const o=t.node;n(o.y)||(o.y=e,e=Math.max(e+o.in,f(o,e)))})),e}function h(t,e){return n(t.y)?t.y:(t.y=e,e)}function d(t,e){const o=function(t){return t.sort(((t,e)=>Math.max(e.in,e.out)-Math.max(t.in,t.out)))[0]}(t);o.y=0;const r=c(o,0),a=f(o,0),s=function(t,e){const o=t.filter((t=>0===t.x)),r=t.filter((t=>t.x===e)),a=o.filter((t=>!n(t.y))),s=r.filter((t=>!n(t.y)));let l=o.reduce(((t,e)=>Math.max(t,e.y+e.out||0)),0),i=r.reduce(((t,e)=>Math.max(t,e.y+e.in||0)),0);return l>=i?(a.forEach((t=>{l=h(t,l),l=Math.max(l+t.out,f(t,l))})),s.forEach((t=>{i=h(t,i),i=Math.max(i+t.in,f(t,i))}))):(s.forEach((t=>{i=h(t,i),i=Math.max(i+t.in,f(t,i))})),a.forEach((t=>{l=h(t,l),l=Math.max(l+t.out,f(t,l))}))),Math.max(l,i)}(t,e);return Math.max(r,a,s)}function u(t,e,o){const r=[...t.values()],n=function(t,e){const o=new Set(e.map((t=>t.to))),r=new Set(e.map((t=>t.from))),n=new Set([...t.keys()]);let s=0;for(;n.size;){const r=a([...n],o);for(let e=0;e<r.length;e++)t.get(r[e]).x=s,n.delete(r[e]);n.size&&(o.clear(),e.filter((t=>n.has(t.from))).forEach((t=>o.add(t.to))),s++)}return[...t.keys()].filter((t=>!r.has(t))).forEach((e=>{t.get(e).x=s})),s}(t,e),l=o?function(t,e){let o=0;for(let r=0;r<=e;r++){let e=0;const a=t.filter((t=>t.x===r)).sort(((t,e)=>t.priority-e.priority));for(const t of a)t.y=e,e+=Math.max(t.out,t.in);o=Math.max(e,o)}return o}(r,n):d(r,n),i=function(t,e){let o=1,r=0,a=0,n=0;const l=[];return t.sort(s).forEach((t=>{if(t.y){if(0===t.x)l.push(t.y);else{for(r!==t.x&&(r=t.x,a=0),o=a+1;o<l.length&&!(l[o]>t.y);o++);a=o}t.y+=o*e,o++}n=Math.max(n,t.y+Math.max(t.in,t.out))})),n}(r,.03*l);return function(t){t.forEach((t=>{let e=0;t.from.sort(((t,e)=>t.node.y+t.node.out/2-(e.node.y+e.node.out/2))).forEach((t=>{t.addY=e,e+=t.flow})),e=0,t.to.sort(((t,e)=>t.node.y+t.node.in/2-(e.node.y+e.node.in/2))).forEach((t=>{t.addY=e,e+=t.flow}))}))}(r),{maxX:n,maxY:i}}function y(t,e){for(let o=0;o<t.length;o++)if(t[o].key===e)return t[o].addY;return 0}class x extends t.DatasetController{parseObjectData(t,e,o,r){if(0===r)return[];const a=this,{xScale:n,yScale:s}=t,l=[],i=a._nodes=function(t){const e=new Map;for(let o=0;o<t.length;o++){const r=t[o];if(e.has(r.from)){const t=e.get(r.from);t.out+=r.flow,t.to.push({key:r.to,flow:r.flow})}else e.set(r.from,{key:r.from,in:0,out:r.flow,from:[],to:[{key:r.to,flow:r.flow}]});if(e.has(r.to)){const t=e.get(r.to);t.in+=r.flow,t.from.push({key:r.from,flow:r.flow})}else e.set(r.to,{key:r.to,in:r.flow,out:0,from:[{key:r.from,flow:r.flow}],to:[]})}const o=(t,e)=>e.flow-t.flow;return[...e.values()].forEach((t=>{let r=0;t.from=t.from.sort(o),t.from.forEach((t=>{t.node=e.get(t.key),t.addY=r,r+=t.flow})),r=0,t.to=t.to.sort(o),t.to.forEach((t=>{t.node=e.get(t.key),t.addY=r,r+=t.flow}))})),e}(e),c=a.getDataset().priority;if(c)for(const t of i.values())t.key in c&&(t.priority=c[t.key]);const{maxX:f,maxY:h}=u(i,e,!!c);a._maxX=f,a._maxY=h;for(let t=0,o=e.length;t<o;++t){const o=e[t],r=i.get(o.from),a=i.get(o.to),c=r.y+y(r.to,o.to),f=a.y+y(a.from,o.from);l.push({x:n.parse(r.x,t),y:s.parse(c,t),_custom:{from:r,to:a,x:n.parse(a.x,t),y:s.parse(f,t),height:s.parse(o.flow,t)}})}return l.slice(o,o+r)}getMinMax(t){return{min:0,max:t===this._cachedMeta.xScale?this._maxX:this._maxY}}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,o,r,a){const n=this,{xScale:s,yScale:l}=n._cachedMeta,i=n.resolveDataElementOptions(o,a),c=n.getSharedOptions(a,t[o],i),f=n.getDataset(),h=e.valueOrDefault(f.borderWidth,1)/2+.5,d=e.valueOrDefault(f.nodeWidth,10);for(let e=o;e<o+r;e++){const o=n.getParsed(e),r=o._custom,i=l.getPixelForValue(o.y);n.updateElement(t[e],e,{x:s.getPixelForValue(o.x)+d+h,y:i,x2:s.getPixelForValue(r.x)-h,y2:l.getPixelForValue(r.y),from:r.from,to:r.to,progress:"reset"===a?0:1,height:Math.abs(l.getPixelForValue(o.y+r.height)-i),options:n.resolveDataElementOptions(e,a)},a)}n.updateSharedOptions(c,a)}_drawLabels(){const t=this,o=t._ctx,r=t._nodes||new Map,a=t.getDataset(),n=e.valueOrDefault(a.borderWidth,1),s=e.valueOrDefault(a.nodeWidth,10),l=a.labels,{xScale:i,yScale:c}=t._cachedMeta;o.save();const f=t.chart.chartArea;for(const t of r.values()){const e=i.getPixelForValue(t.x),r=c.getPixelForValue(t.y),h=Math.max(t.in,t.out),d=Math.abs(c.getPixelForValue(t.y+h)-r),u=l&&l[t.key]||t.key;let y=e;o.fillStyle=a.color||"black",o.textBaseline="middle",e<f.width/2?(o.textAlign="left",y+=s+n+4):(o.textAlign="right",y-=n+4),this._drawLabel(u,r,d,o,y)}o.restore()}_drawLabel(t,o,r,a,n){const s=e.isNullOrUndef(t)?[]:this.toTextLines(t),l=s.length,i=o+r/2;if(l>1){const t=i-15*l/2+7.5;for(let e=0;e<l;e++)a.fillText(s[e],n,t+15*e)}else a.fillText(t,n,i)}toTextLines(t){var o,r=[];for(t=[].concat(t);t.length;)"string"==typeof(o=t.pop())?r.unshift.apply(r,o.split("\n")):Array.isArray(o)?t.push.apply(t,o):e.isNullOrUndef(t)||r.unshift(""+o);return r}_drawNodes(){const t=this,o=t._ctx,r=t._nodes||new Map,a=t.getDataset(),{xScale:n,yScale:s}=t._cachedMeta,l=e.valueOrDefault(a.borderWidth,1),i=e.valueOrDefault(a.nodeWidth,10);o.save(),o.strokeStyle=a.borderColor||"black",o.lineWidth=l;for(const t of r.values()){o.fillStyle=t.color;const e=n.getPixelForValue(t.x),r=s.getPixelForValue(t.y),a=Math.max(t.in,t.out),c=Math.abs(s.getPixelForValue(t.y+a)-r);l&&o.strokeRect(e,r,i,c),o.fillRect(e,r,i,c)}o.restore()}draw(){const t=this,e=t._ctx,o=t.getMeta().data||[];for(let t=0,e=o.length;t<e;++t){const e=o[t];e.from.color=e.options.colorFrom,e.to.color=e.options.colorTo}t._drawNodes();for(let t=0,r=o.length;t<r;++t)o[t].draw(e);t._drawLabels()}}x.id="sankey",x.defaults={dataElementType:"flow",animations:{numbers:{type:"number",properties:["x","y","x2","y2","height"]},progress:{easing:"linear",duration:t=>"data"===t.type?200*(t.parsed._custom.x-t.parsed.x):void 0,delay:t=>"data"===t.type?500*t.parsed.x+20*t.dataIndex:void 0},colors:{type:"color",properties:["colorFrom","colorTo"]}},transitions:{hide:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],to:"transparent"}}},show:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],from:"transparent"}}}}},x.overrides={interaction:{mode:"nearest",intersect:!0},datasets:{color:()=>"#efefef",clip:!1,parsing:!0},plugins:{tooltip:{callbacks:{title:()=>"",label(t){const e=t.dataset.data[t.dataIndex];return e.from+" -> "+e.to+": "+e.flow}}},legend:{display:!1}},scales:{x:{type:"linear",bounds:"data",display:!1,min:0,offset:!1},y:{type:"linear",bounds:"data",display:!1,min:0,reverse:!0,offset:!1}},layout:{padding:{top:3,left:3,right:13,bottom:3}}};const p=(t,e,o,r)=>t<o?{cp1:{x:t+(o-t)/3*2,y:e},cp2:{x:t+(o-t)/3,y:r}}:{cp1:{x:t-(t-o)/3,y:0},cp2:{x:o+(t-o)/3,y:0}},g=(t,e,o)=>({x:t.x+o*(e.x-t.x),y:t.y+o*(e.y-t.y)});class m extends t.Element{constructor(t){super(),this.options=void 0,this.x=void 0,this.y=void 0,this.x2=void 0,this.y2=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const{x:o,x2:r,y:a,y2:n,height:s,progress:l}=this,{cp1:i,cp2:c}=p(o,a,r,n),f=this.options;if(0===l)return;let h;t.save(),l<1&&(t.beginPath(),t.rect(o,Math.min(a,n),(r-o)*l+1,Math.abs(n-a)+s+1),t.clip()),"from"===f.colorMode?h=e.color(f.colorFrom).alpha(.5).rgbString():"to"===f.colorMode?h=e.color(f.colorTo).alpha(.5).rgbString():(h=t.createLinearGradient(o,0,r,0),h.addColorStop(0,e.color(f.colorFrom).alpha(.5).rgbString()),h.addColorStop(1,e.color(f.colorTo).alpha(.5).rgbString())),t.fillStyle=h,t.strokeStyle=h,t.lineWidth=.5,t.beginPath(),t.moveTo(o,a),t.bezierCurveTo(i.x,i.y,c.x,c.y,r,n),t.lineTo(r,n+s),t.bezierCurveTo(c.x,c.y+s,i.x,i.y+s,o,a+s),t.lineTo(o,a),t.stroke(),t.closePath(),t.fill(),t.restore()}inRange(t,e,o){const{x:r,y:a,x2:n,y2:s,height:l}=this.getProps(["x","y","x2","y2","height"],o);if(t<r||t>n)return!1;const{cp1:i,cp2:c}=p(r,a,n,s),f=(t-r)/(n-r),h={x:n,y:s},d=g({x:r,y:a},i,f),u=g(i,c,f),y=g(c,h,f),x=g(d,u,f),m=g(u,y,f),w=g(x,m,f).y;return e>=w&&e<=w+l}inXRange(t,e){const{x:o,x2:r}=this.getProps(["x","x2"],e);return t>=o&&t<=r}inYRange(t,e){const{y:o,y2:r,height:a}=this.getProps(["y","y2","height"],e),n=Math.min(o,r),s=Math.max(o,r)+a;return t>=n&&t<=s}getCenterPoint(t){const{x:e,y:o,x2:r,y2:a,height:n}=this.getProps(["x","y","x2","y2","height"],t);return{x:(e+r)/2,y:(o+a+n)/2}}tooltipPosition(){return this.getCenterPoint()}getRange(t){return"x"===t?this.width/2:this.height/2}}m.id="flow",m.defaults={colorFrom:"red",colorTo:"green",colorMode:"gradient"},r.default.register(x,m)}));
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("chart.js"),require("chart.js/helpers")):"function"==typeof define&&define.amd?define(["chart.js","chart.js/helpers"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Chart,t.Chart.helpers)}(this,(function(t,e){"use strict";function o(t,e){const o=t.filter((t=>!e.has(t)));return o.length?o:t.slice(0,1)}const r=t=>void 0!==t,a=(t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y,n=(t,e)=>t.reduce(((t,o)=>t+o.node[e].length+n(o.node[e],e)),0),s=t=>(e,o)=>n(e.node[t],t)-n(o.node[t],t);function i(t,e){return t.from.sort(s("from")).forEach((t=>{const o=t.node;r(o.y)||(o.y=e,e=Math.max(e+o.out,i(o,e)))})),e}function l(t,e){return t.to.sort(s("to")).forEach((t=>{const o=t.node;r(o.y)||(o.y=e,e=Math.max(e+o.in,l(o,e)))})),e}function c(t,e){return r(t.y)?t.y:(t.y=e,e)}function h(t,e){const o=function(t){return t.sort(((t,e)=>Math.max(e.in,e.out)-Math.max(t.in,t.out)))[0]}(t);o.y=0;const a=i(o,0),n=l(o,0),s=function(t,e){const o=t.filter((t=>0===t.x)),a=t.filter((t=>t.x===e)),n=o.filter((t=>!r(t.y))),s=a.filter((t=>!r(t.y)));let i=o.reduce(((t,e)=>Math.max(t,e.y+e.out||0)),0),h=a.reduce(((t,e)=>Math.max(t,e.y+e.in||0)),0);return i>=h?(n.forEach((t=>{i=c(t,i),i=Math.max(i+t.out,l(t,i))})),s.forEach((t=>{h=c(t,h),h=Math.max(h+t.in,l(t,h))}))):(s.forEach((t=>{h=c(t,h),h=Math.max(h+t.in,l(t,h))})),n.forEach((t=>{i=c(t,i),i=Math.max(i+t.out,l(t,i))}))),Math.max(i,h)}(t,e);return Math.max(a,n,s)}function f(t,e,r){const n=[...t.values()],s=function(t,e){const r=new Set(e.map((t=>t.to))),a=new Set(e.map((t=>t.from))),n=new Set([...t.keys()]);let s=0;for(;n.size;){const a=o([...n],r);for(let e=0;e<a.length;e++)t.get(a[e]).x=s,n.delete(a[e]);n.size&&(r.clear(),e.filter((t=>n.has(t.from))).forEach((t=>r.add(t.to))),s++)}return[...t.keys()].filter((t=>!a.has(t))).forEach((e=>{t.get(e).x=s})),s}(t,e),i=r?function(t,e){let o=0;for(let r=0;r<=e;r++){let e=0;const a=t.filter((t=>t.x===r)).sort(((t,e)=>t.priority-e.priority));for(const t of a)t.y=e,e+=Math.max(t.out,t.in);o=Math.max(e,o)}return o}(n,s):h(n,s),l=function(t,e){let o=1,r=0,n=0,s=0;const i=[];return t.sort(a).forEach((t=>{if(t.y){if(0===t.x)i.push(t.y);else{for(r!==t.x&&(r=t.x,n=0),o=n+1;o<i.length&&!(i[o]>t.y);o++);n=o}t.y+=o*e,o++}s=Math.max(s,t.y+Math.max(t.in,t.out))})),s}(n,.03*i);return function(t){t.forEach((t=>{let e=0;t.from.sort(((t,e)=>t.node.y+t.node.out/2-(e.node.y+e.node.out/2))).forEach((t=>{t.addY=e,e+=t.flow})),e=0,t.to.sort(((t,e)=>t.node.y+t.node.in/2-(e.node.y+e.node.in/2))).forEach((t=>{t.addY=e,e+=t.flow}))}))}(n),{maxX:s,maxY:l}}function d(t,e){for(let o=0;o<t.length;o++)if(t[o].key===e)return t[o].addY;return 0}class u extends t.DatasetController{parseObjectData(t,e,o,r){if(0===r)return[];const a=this,{xScale:n,yScale:s}=t,i=[],l=a._nodes=function(t){const e=new Map;for(let o=0;o<t.length;o++){const{from:r,to:a,flow:n}=t[o];if(e.has(r)){const t=e.get(r);t.out+=n,t.to.push({key:a,flow:n})}else e.set(r,{key:r,in:0,out:n,from:[],to:[{key:a,flow:n}]});if(e.has(a)){const t=e.get(a);t.in+=n,t.from.push({key:r,flow:n})}else e.set(a,{key:a,in:n,out:0,from:[{key:r,flow:n}],to:[]})}const o=(t,e)=>e.flow-t.flow;return[...e.values()].forEach((t=>{let r=0;t.from=t.from.sort(o),t.from.forEach((t=>{t.node=e.get(t.key),t.addY=r,r+=t.flow})),r=0,t.to=t.to.sort(o),t.to.forEach((t=>{t.node=e.get(t.key),t.addY=r,r+=t.flow}))})),e}(e),c=a.getDataset().priority;if(c)for(const t of l.values())t.key in c&&(t.priority=c[t.key]);const{maxX:h,maxY:u}=f(l,e,!!c);a._maxX=h,a._maxY=u;for(let t=0,o=e.length;t<o;++t){const o=e[t],r=l.get(o.from),a=l.get(o.to),c=r.y+d(r.to,o.to),h=a.y+d(a.from,o.from);i.push({x:n.parse(r.x,t),y:s.parse(c,t),_custom:{from:r,to:a,x:n.parse(a.x,t),y:s.parse(h,t),height:s.parse(o.flow,t)}})}return i.slice(o,o+r)}getMinMax(t){return{min:0,max:t===this._cachedMeta.xScale?this._maxX:this._maxY}}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,o,r,a){const n=this,{xScale:s,yScale:i}=n._cachedMeta,l=n.resolveDataElementOptions(o,a),c=n.getSharedOptions(a,t[o],l),h=n.getDataset(),f=e.valueOrDefault(h.borderWidth,1)/2+.5,d=e.valueOrDefault(h.nodeWidth,10);for(let e=o;e<o+r;e++){const o=n.getParsed(e),r=o._custom,l=i.getPixelForValue(o.y);n.updateElement(t[e],e,{x:s.getPixelForValue(o.x)+d+f,y:l,x2:s.getPixelForValue(r.x)-f,y2:i.getPixelForValue(r.y),from:r.from,to:r.to,progress:"reset"===a?0:1,height:Math.abs(i.getPixelForValue(o.y+r.height)-l),options:n.resolveDataElementOptions(e,a)},a)}n.updateSharedOptions(c,a)}_drawLabels(){const t=this,o=t._ctx,r=t._nodes||new Map,a=t.getDataset(),n=e.valueOrDefault(a.borderWidth,1),s=e.valueOrDefault(a.nodeWidth,10),i=a.labels,{xScale:l,yScale:c}=t._cachedMeta;o.save();const h=t.chart.chartArea;for(const t of r.values()){const e=l.getPixelForValue(t.x),r=c.getPixelForValue(t.y),f=Math.max(t.in,t.out),d=Math.abs(c.getPixelForValue(t.y+f)-r),u=i&&i[t.key]||t.key;let y=e;o.fillStyle=a.color||"black",o.textBaseline="middle",e<h.width/2?(o.textAlign="left",y+=s+n+4):(o.textAlign="right",y-=n+4),this._drawLabel(u,r,d,o,y)}o.restore()}_drawLabel(t,o,r,a,n){const s=e.isNullOrUndef(t)?[]:this.toTextLines(t),i=s.length,l=o+r/2;if(i>1){const t=l-15*i/2+7.5;for(let e=0;e<i;e++)a.fillText(s[e],n,t+15*e)}else a.fillText(t,n,l)}toTextLines(t){let o,r=[];for(t=[].concat(t);t.length;)o=t.pop(),"string"==typeof o?r.unshift.apply(r,o.split("\n")):Array.isArray(o)?t.push.apply(t,o):e.isNullOrUndef(t)||r.unshift(""+o);return r}_drawNodes(){const t=this,o=t._ctx,r=t._nodes||new Map,a=t.getDataset(),{xScale:n,yScale:s}=t._cachedMeta,i=e.valueOrDefault(a.borderWidth,1),l=e.valueOrDefault(a.nodeWidth,10);o.save(),o.strokeStyle=a.borderColor||"black",o.lineWidth=i;for(const t of r.values()){o.fillStyle=t.color;const e=n.getPixelForValue(t.x),r=s.getPixelForValue(t.y),a=Math.max(t.in,t.out),c=Math.abs(s.getPixelForValue(t.y+a)-r);i&&o.strokeRect(e,r,l,c),o.fillRect(e,r,l,c)}o.restore()}draw(){const t=this,e=t._ctx,o=t.getMeta().data||[];for(let t=0,e=o.length;t<e;++t){const e=o[t];e.from.color=e.options.colorFrom,e.to.color=e.options.colorTo}t._drawNodes();for(let t=0,r=o.length;t<r;++t)o[t].draw(e);t._drawLabels()}}u.id="sankey",u.defaults={dataElementType:"flow",animations:{numbers:{type:"number",properties:["x","y","x2","y2","height"]},progress:{easing:"linear",duration:t=>"data"===t.type?200*(t.parsed._custom.x-t.parsed.x):void 0,delay:t=>"data"===t.type?500*t.parsed.x+20*t.dataIndex:void 0},colors:{type:"color",properties:["colorFrom","colorTo"]}},transitions:{hide:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],to:"transparent"}}},show:{animations:{colors:{type:"color",properties:["colorFrom","colorTo"],from:"transparent"}}}}},u.overrides={interaction:{mode:"nearest",intersect:!0},datasets:{color:()=>"#efefef",clip:!1,parsing:!0},plugins:{tooltip:{callbacks:{title:()=>"",label(t){const e=t.dataset.data[t.dataIndex];return e.from+" -> "+e.to+": "+e.flow}}},legend:{display:!1}},scales:{x:{type:"linear",bounds:"data",display:!1,min:0,offset:!1},y:{type:"linear",bounds:"data",display:!1,min:0,reverse:!0,offset:!1}},layout:{padding:{top:3,left:3,right:13,bottom:3}}};const y=(t,e,o,r)=>t<o?{cp1:{x:t+(o-t)/3*2,y:e},cp2:{x:t+(o-t)/3,y:r}}:{cp1:{x:t-(t-o)/3,y:0},cp2:{x:o+(t-o)/3,y:0}},x=(t,e,o)=>({x:t.x+o*(e.x-t.x),y:t.y+o*(e.y-t.y)});class p extends t.Element{constructor(t){super(),this.options=void 0,this.x=void 0,this.y=void 0,this.x2=void 0,this.y2=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const{x:o,x2:r,y:a,y2:n,height:s,progress:i}=this,{cp1:l,cp2:c}=y(o,a,r,n),h=this.options;if(0===i)return;let f;t.save(),i<1&&(t.beginPath(),t.rect(o,Math.min(a,n),(r-o)*i+1,Math.abs(n-a)+s+1),t.clip()),"from"===h.colorMode?f=e.color(h.colorFrom).alpha(.5).rgbString():"to"===h.colorMode?f=e.color(h.colorTo).alpha(.5).rgbString():(f=t.createLinearGradient(o,0,r,0),f.addColorStop(0,e.color(h.colorFrom).alpha(.5).rgbString()),f.addColorStop(1,e.color(h.colorTo).alpha(.5).rgbString())),t.fillStyle=f,t.strokeStyle=f,t.lineWidth=.5,t.beginPath(),t.moveTo(o,a),t.bezierCurveTo(l.x,l.y,c.x,c.y,r,n),t.lineTo(r,n+s),t.bezierCurveTo(c.x,c.y+s,l.x,l.y+s,o,a+s),t.lineTo(o,a),t.stroke(),t.closePath(),t.fill(),t.restore()}inRange(t,e,o){const{x:r,y:a,x2:n,y2:s,height:i}=this.getProps(["x","y","x2","y2","height"],o);if(t<r||t>n)return!1;const{cp1:l,cp2:c}=y(r,a,n,s),h=(t-r)/(n-r),f={x:n,y:s},d=x({x:r,y:a},l,h),u=x(l,c,h),p=x(c,f,h),g=x(d,u,h),m=x(u,p,h),M=x(g,m,h).y;return e>=M&&e<=M+i}inXRange(t,e){const{x:o,x2:r}=this.getProps(["x","x2"],e);return t>=o&&t<=r}inYRange(t,e){const{y:o,y2:r,height:a}=this.getProps(["y","y2","height"],e),n=Math.min(o,r),s=Math.max(o,r)+a;return t>=n&&t<=s}getCenterPoint(t){const{x:e,y:o,x2:r,y2:a,height:n}=this.getProps(["x","y","x2","y2","height"],t);return{x:(e+r)/2,y:(o+a+n)/2}}tooltipPosition(t){return this.getCenterPoint(t)}getRange(t){return"x"===t?this.width/2:this.height/2}}p.id="flow",p.defaults={colorFrom:"red",colorTo:"green",colorMode:"gradient"},t.Chart.register(u,p)}));
{
"name": "chartjs-chart-sankey",
"version": "0.7.0",
"version": "0.7.1",
"description": "Chart.js module for creating sankey diagrams",
"main": "dist/chartjs-chart-sankey.js",
"module": "dist/chartjs-chart-sankey.esm.js",
"types": "types/index.esm.d.ts",
"scripts": {
"lint": "eslint --ignore-path .gitignore .",
"build": "rollup -c",
"autobuild": "rollup -c -w",
"dev": "karma start --no-single-run --auto-watch --browsers chrome",
"lint": "concurrently -r \"npm:lint-*\"",
"lint-js": "eslint \"src/**/*.js\" \"test/**/*.js\"",
"lint-md": "eslint \"**/*.md\"",
"lint-types": "eslint \"types/**/*.ts\" && tsc -p types/tests/",
"test": "cross-env NODE_ENV=test concurrently \"npm:test-*\"",

@@ -26,3 +30,4 @@ "test-lint": "npm run lint",

"files": [
"dist/*.js"
"dist/*.js",
"types/index.esm.d.ts"
],

@@ -37,2 +42,4 @@ "author": "Jukka Kurkela",

"@rollup/plugin-node-resolve": "^13.0.0",
"@typescript-eslint/eslint-plugin": "^4.26.1",
"@typescript-eslint/parser": "^4.26.1",
"chart.js": "^3.0.0",

@@ -48,2 +55,3 @@ "chartjs-adapter-date-fns": "^2.0.0",

"eslint-plugin-html": "^6.1.2",
"eslint-plugin-markdown": "^2.2.0",
"jasmine-core": "^3.7.1",

@@ -58,6 +66,6 @@ "karma": "^6.2.0",

"karma-spec-reporter": "0.0.32",
"merge2": "^1.4.1",
"rollup": "^2.42.1",
"rollup-plugin-istanbul": "^3.0.0",
"rollup-plugin-terser": "^7.0.2"
"rollup-plugin-terser": "^7.0.2",
"typescript": "^4.3.2"
},

@@ -64,0 +72,0 @@ "peerDependencies": {

# chartjs-chart-sankey
[Chart.js](https://www.chartjs.org/) **v3.0.0-beta.10** module for creating sankey diagrams
[Chart.js](https://www.chartjs.org/) **v3.3.x** module for creating sankey diagrams

@@ -22,10 +22,24 @@ [![npm](https://img.shields.io/npm/v/chartjs-chart-sankey.svg)](https://www.npmjs.com/package/chartjs-chart-sankey)

## Typescript
Typescript 3.x and higher is supported.
## Documentation
To create a sankey chart, include chartjs-chart-sankey.js after chart.js and then create the chart by setting the `type` attribute to `'sankey'`
You can use **chartjs-chart-sankey.js** as ES module. You'll need to manually register two components
```js
new Chart(ctx, {
type: 'sankey',
data: dataObject
import {Chart} from 'chart.js';
import {SankeyController, Flow} from 'chartjs-chart-sankey/dist/chartjs-chart-sankey.esm';
Chart.register(SankeyController, Flow);
```
To create a sankey chart, include chartjs-chart-sankey.js after chart.js and then create the chart by setting the `type`
attribute to `'sankey'`
```js
const chart = new Chart(ctx, {
type: 'sankey',
data: dataObject
});

@@ -39,17 +53,23 @@ ```

```js
new Chart(ctx, {
type: 'sankey',
data: {
datasets: [{
label: 'My sankey',
data: [
{ from: 'a', to: 'b', flow: 10 },
{ from: 'a', to: 'c', flow: 5},
{ from: 'b', to: 'c', flow: 10 }
],
colorFrom: (c) => getColor(c.dataset.data[c.dataIndex].from),
colorTo: (c) => getColor(c.dataset.data[c.dataIndex].to),
colorMode: 'gradient' // or 'from' or 'to'
}]
},
const chart = new Chart(ctx, {
type: 'sankey',
data: {
datasets: [{
label: 'My sankey',
data: [
{from: 'a', to: 'b', flow: 10},
{from: 'a', to: 'c', flow: 5},
{from: 'b', to: 'c', flow: 10}
],
colorFrom: (c) => getColor(c.dataset.data[c.dataIndex].from),
colorTo: (c) => getColor(c.dataset.data[c.dataIndex].to),
colorMode: 'gradient', // or 'from' or 'to'
/* optional labels */
labels: {
a: 'Label A',
b: 'Label B',
c: 'Label C'
}
}]
},
});

@@ -56,0 +76,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc