提交 c29f31a7 编写于 作者: D deqingli

添加snaky view

上级 c9239fe6
define(function (require) {
var echarts = require('../echarts');
require('./sankey/SankeySeries');
require('./sankey/SankeyView');
echarts.registerLayout(require('./sankey/sankeyLayout'));
echarts.registerVisualCoding('chart', require('./sankey/sankeyVisual'));
})
\ No newline at end of file
define(function (require) {
'use strict';
var SeriesModel = require('../../model/Series');
var createGraphFromNodeEdge = require('../helper/createGraphFromNodeEdge');
return SeriesModel.extend({
type: 'series.sankey',
layoutInfo: null,
getInitialData: function (option, ecModel) {
var links = option.edges || option.links;
var nodes = option.data || option.nodes;
if (nodes && links) {
var graph = createGraphFromNodeEdge(nodes, links, this, true);
return graph.data;
}
},
/**
* @return {module:echarts/data/Graph}
*/
getGraph: function () {
return this.getData().graph;
},
/**
* return {module:echarts/data/List}
*/
getEdgeData: function() {
return this.getGraph().edgeData;
},
defaultOption: {
zlevel: 0,
z: 2,
coordinateSystem: 'view',
layout : null,
// the position of the whole view
x: '5%',
y: '5%',
x2: '20%',
y2: '5%',
// the dx of the node
nodeWidth: 20,
// the distance between two nodes
nodeGap: 8,
// the number of iterations to change the position of the node
layoutIterations: 32,
label: {
normal: {
show: true,
textStyle: {
fontSize: 6
}
},
emphasis: {
show: true
}
},
itemStyle: {
normal: {},
emphasis: {}
},
lineStyle: {
normal: {
color: '#000',
opacity: 0.2,
curveness: 0.5
},
emphasis: {
opacity: 0.6
}
},
// colorEncoded: 'node',
color: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b','#ffffbf',
'#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],
animationEasing: 'linear',
animationDuration: 2000
}
});
});
\ No newline at end of file
define(function (require) {
var graphic = require('../../util/graphic');
var modelUtil = require('../../util/model');
return require('../../echarts').extendChartView({
type: 'sankey',
/**
* @private
* @type {module:echarts/chart/sankey/SankeySeries}
*/
_model: null,
render: function(seriesModel, ecModel, api) {
var graph = seriesModel.getGraph();
var group = this.group;
this._model = seriesModel;
group.removeAll();
group.position = [seriesModel.layoutInfo.x, seriesModel.layoutInfo.y];
var textStyle = seriesModel.getModel('label.normal').getModel('textStyle');
var edgeData = graph.edgeData;
var rawOption = seriesModel.option;
var formatModel = modelUtil.createDataFormatModel(
seriesModel, edgeData, rawOption.edges || rawOption.links
);
formatModel.formatTooltip = function (dataIndex) {
var params = this.getDataParams(dataIndex);
var rawDataOpt = params.data;
var html = rawDataOpt.source + ' -- ' + rawDataOpt.target;
if (params.value) {
html += ':' + params.value;
}
return html;
};
// generate a rect for each node
graph.eachNode(function (node) {
var rect = new graphic.Rect({
shape: {
x: node.getLayout().x,
y: node.getLayout().y,
width: node.getLayout().dx,
height: node.getLayout().dy
},
style: {
stroke: '#000',
fill: node.getVisual('color')
}
});
// rect.setHoverStyle(rect, node.inEdges.)
group.add(rect);
var text = new graphic.Text({
style: {
x: node.getLayout().x + node.getLayout().dx + 4,
y: node.getLayout().y + node.getLayout().dy / 2,
text: node.id,
textAlign: 'start',
textBaseline: 'middle',
textFont: textStyle.getFont()
}
});
group.add(text);
});
// generate a bezire Curve for each edge
graph.eachEdge(function (edge) {
var curve = new graphic.BezierCurve();
curve.dataIndex = edge.dataIndex;
curve.hostModel = formatModel;
curve.style.lineWidth = Math.max(1, edge.getLayout().dy);
var lineStyleModel = edge.getModel('lineStyle.normal');
var curvature = lineStyleModel.get('curveness');
var x1 = edge.node1.getLayout().x + edge.node1.getLayout().dx;
var y1 = edge.node1.getLayout().y + edge.getLayout().sy + edge.getLayout().dy / 2;
var x2 = edge.node2.getLayout().x;
var y2 = edge.node2.getLayout().y + edge.getLayout().ty + edge.getLayout().dy /2;
var cpx1 = x1 * (1 - curvature) + x2 * curvature;
var cpy1 = y1;
var cpx2 = x1 * curvature + x2 * (1 - curvature);
var cpy2 = y2;
curve.setShape({
x1: x1,
y1: y1,
x2: x2,
y2: y2,
cpx1: cpx1,
cpy1: cpy1,
cpx2: cpx2,
cpy2: cpy2
});
// 'width' is just for 'lineWidth', lineWidth get from the computation,so user can't set it
curve.setStyle(lineStyleModel.getLineStyle(['width']));
graphic.setHoverStyle(curve, edge.getModel('lineStyle.emphasis').getLineStyle());
group.add(curve);
});
if (!this._data) {
group.setClipPath(createGridClipShape(group.getBoundingRect(), seriesModel, function () {
group.removeClipPath();
}));
}
this._data = seriesModel.getData();
}
});
function createGridClipShape(rect, seriesModel, cb) {
var rectEl = new graphic.Rect({
shape: {
x: rect.x - 10,
y: rect.y - 10,
width: 0,
height: rect.height + 20
}
});
graphic.initProps(rectEl, {
shape: {
width: rect.width + 20,
height: rect.height + 20
}
}, seriesModel, cb);
return rectEl;
}
});
\ No newline at end of file
define(function (require) {
var layout = require('../../util/layout');
var nest = require('../../util/array/nest');
var zrUtil = require('zrender/core/util');
return function (ecModel, api) {
ecModel.eachSeriesByType('sankey', function (seriesModel) {
var nodeWidth = seriesModel.get('nodeWidth');
var nodeGap = seriesModel.get('nodeGap');
var layoutInfo = getViewRect(seriesModel, api);
seriesModel.layoutInfo = layoutInfo;
var width = layoutInfo.width;
var height = layoutInfo.height;
var graph = seriesModel.getGraph();
var nodes = graph.nodes;
var edges = graph.edges;
computeNodeValues(nodes);
var filteredNodes = nodes.filter(function (node) {
return node.getLayout().value === 0;
});
if (filteredNodes.length !== 0) {
var iterations = 0;
}
else {
var iterations = seriesModel.get('layoutIterations');
}
layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations);
});
};
/**
* get the layout position of the whole view.
*/
function getViewRect(seriesModel, api) {
return layout.parsePositionInfo({
x: seriesModel.get('x'),
y: seriesModel.get('y'),
x2: seriesModel.get('x2'),
y2: seriesModel.get('y2'),
width: seriesModel.get('width'),
height: seriesModel.get('height')
},{
width: api.getWidth(),
height: api.getHeight()
});
}
function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations) {
computeNodeBreadths(nodes, nodeWidth, width);
computeNodeDepths(nodes, edges, height, nodeGap, iterations);
computeEdgeDepths(nodes);
}
/**
* compute the value of each node by summing the associated edge's value.
* @param {module:echarts/data/Graph~Node} nodes
*/
function computeNodeValues(nodes) {
zrUtil.each(nodes, function (node) {
var value1 = sum(node.outEdges, getEdgeValue);
var value2 = sum(node.inEdges, getEdgeValue);
var value = Math.max(value1, value2);
node.setLayout({value: value}, true);
});
}
/**
* compute the x-position for each node.
* @param {module:echarts/data/Graph~Node} nodes
* @param {number} nodeWidth
* @param {number} width
*/
function computeNodeBreadths(nodes, nodeWidth, width) {
var remainNodes = nodes;
var nextNode = null;
var x = 0;
var kx = 0;
while (remainNodes.length) {
nextNode = [];
zrUtil.each(remainNodes, function (node) {
node.setLayout({x: x}, true);
node.setLayout({dx: nodeWidth}, true);
zrUtil.each(node.outEdges, function (edge) {
nextNode.push(edge.node2);
});
});
remainNodes = nextNode;
++x;
}
moveSinksRight(nodes, x);
kx = (width - nodeWidth) / (x - 1);
scaleNodeBreadths(nodes, kx);
}
/**
* all the node without outEgdes are assigned maximum breadth and
* be aligned in the last column.
* @param {module:echarts/data/Graph~Node} nodes
* @param {number} x
*/
function moveSinksRight(nodes, x) {
zrUtil.each(nodes, function (node) {
if(!node.outEdges.length) {
node.setLayout({x: x-1}, true);
}
});
}
/**
* scale node x-position to the width.
* @param {module:echarts/data/Graph~Node} nodes
* @param {number} kx
*/
function scaleNodeBreadths(nodes, kx) {
zrUtil.each(nodes, function(node) {
var nodeX = node.getLayout().x * kx;
node.setLayout({x: nodeX}, true);
});
}
/**
* using Gauss-Seidel iterations method to compute the node depth(y-position).
* @param {module:echarts/data/Graph~Node} nodes
* @param {module:echarts/data/Graph~Edge} edges
* @param {number} height
* @param {numbber} nodeGap
* @param {number} iterations
*/
function computeNodeDepths(nodes, edges, height, nodeGap, iterations) {
var nodesByBreadth = nest()
.key(function (d) {
return d.getLayout().x;
})
.sortKeys(ascending)
.entries(nodes)
.map(function (d) {
return d.values;
});
initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap);
resolveCollisions(nodesByBreadth, nodeGap, height);
for (var alpha = 1; iterations > 0; iterations--) {
alpha *= 0.99;
relaxRightToLeft(nodesByBreadth, alpha);
resolveCollisions(nodesByBreadth, nodeGap, height);
relaxLeftToRight(nodesByBreadth, alpha);
resolveCollisions(nodesByBreadth, nodeGap, height);
}
}
/**
* compute the original y-position for each node.
* @param {module:echarts/data/Graph~Node} nodes
* @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
* @param {module:echarts/data/Graph~Edge} edges
* @param {number} height
* @param {number} nodeGap
*/
function initializeNodeDepth(nodes, nodesByBreadth, edges, height, nodeGap) {
var kyArray = [];
zrUtil.each(nodesByBreadth, function (nodes) {
var n = nodes.length;
var sum = 0;
zrUtil.each(nodes, function (node) {
sum += node.getLayout().value;
});
ky = (height - (n-1) * nodeGap) / sum;
kyArray.push(ky);
});
kyArray.sort(function (a, b) {
return a - b;
});
ky0 = kyArray[0];
zrUtil.each(nodesByBreadth, function (nodes) {
zrUtil.each(nodes, function (node, i) {
node.setLayout({y: i}, true);
var nodeDy = node.getLayout().value * ky0;
node.setLayout({dy: nodeDy}, true);
});
});
zrUtil.each(edges, function (edge) {
var edgeDy = +edge.getValue() * ky0;
edge.setLayout({dy: edgeDy}, true);
});
}
/**
* resolve the collision of initialized depth.
* @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
* @param {number} nodeGap
* @param {number} height
*/
function resolveCollisions(nodesByBreadth, nodeGap, height) {
zrUtil.each(nodesByBreadth, function (nodes) {
var node;
var dy;
var y0 = 0;
var n = nodes.length;
var i;
nodes.sort(ascendingDepth);
for (i = 0; i < n; i++) {
node = nodes[i];
dy = y0 - node.getLayout().y;
if(dy > 0) {
var nodeY = node.getLayout().y + dy;
node.setLayout({y: nodeY}, true);
}
y0 = node.getLayout().y + node.getLayout().dy + nodeGap;
}
// if the bottommost node goes outside the biunds, push it back up
dy = y0 - nodeGap - height;
if (dy > 0) {
nodeY = node.getLayout().y -dy;
node.setLayout({y: nodeY}, true);
y0 = node.getLayout().y;
for (i = n - 2; i >= 0; --i) {
node = nodes[i];
dy = node.getLayout().y + node.getLayout().dy + nodeGap - y0;
if (dy > 0) {
nodeY = node.getLayout().y - dy;
node.setLayout({y: nodeY}, true);
}
y0 = node.getLayout().y;
}
}
});
}
/**
* change the y-position of the nodes, except most the right side nodes.
* @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
* @param {number} alpha
*/
function relaxRightToLeft(nodesByBreadth, alpha) {
zrUtil.each(nodesByBreadth.slice().reverse(), function (nodes) {
zrUtil.each(nodes, function (node) {
if (node.outEdges.length) {
var y = sum(node.outEdges, weightedTarget) / sum(node.outEdges, getEdgeValue);
var nodeY = node.getLayout().y + (y - center(node)) * alpha;
node.setLayout({y: nodeY}, true);
}
});
});
}
function weightedTarget(edge) {
return center(edge.node2) * edge.getValue();
}
/**
* change the y-position of the nodes, except most the left side nodes.
* @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
* @param {number} alpha
*/
function relaxLeftToRight(nodesByBreadth, alpha) {
zrUtil.each(nodesByBreadth, function (nodes) {
zrUtil.each(nodes, function (node) {
if (node.inEdges.length) {
var y = sum(node.inEdges, weightedSource) / sum(node.inEdges, getEdgeValue);
var nodeY = node.getLayout().y + (y - center(node)) * alpha;
node.setLayout({y: nodeY}, true);
}
});
});
}
function weightedSource(edge) {
return center(edge.node1) * edge.getValue();
}
/**
* compute the depth(y-position) of each edge.
* @param {module:echarts/data/Graph~Node} nodes
*/
function computeEdgeDepths(nodes) {
zrUtil.each(nodes, function (node) {
node.outEdges.sort(ascendingTargetDepth);
node.inEdges.sort(ascendingSourceDepth);
});
zrUtil.each(nodes, function (node) {
var sy = 0;
var ty = 0;
zrUtil.each(node.outEdges, function (edge) {
edge.setLayout({sy: sy}, true);
sy += edge.getLayout().dy;
});
zrUtil.each(node.inEdges, function (edge) {
edge.setLayout({ty: ty}, true);
ty += edge.getLayout().dy;
});
});
}
function ascendingTargetDepth(a, b) {
return a.node2.getLayout().y - b.node2.getLayout().y;
}
function ascendingSourceDepth(a, b) {
return a.node1.getLayout().y - b.node1.getLayout().y;
}
function sum(array, f) {
var s = 0;
var n = array.length;
var a;
var i = -1;
if (arguments.length === 1) {
while (++i < n) {
a = +array[i];
if (!isNaN(a)) {
s += a;
}
}
}
else {
while (++i < n) {
a = +f.call(array, array[i], i);
if(!isNaN(a)) {
s += a;
}
}
}
return s;
}
function center(node) {
return node.getLayout().y + node.getLayout().dy / 2;
}
function ascendingDepth(a, b) {
return a.getLayout().y - b.getLayout().y;
}
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a == b ? 0 : NaN;
}
function getEdgeValue(edge) {
return edge.getValue();
}
});
\ No newline at end of file
define(function (require) {
var VisualMapping = require('../../visual/VisualMapping');
return function (ecModel, payload) {
ecModel.eachSeriesByType('sankey', function (seriesModel) {
var graph = seriesModel.getGraph();
var nodes = graph.nodes;
nodes.sort(function (a, b) {
return a.getLayout().value - b.getLayout().value;
});
var minValue = nodes[0].getLayout().value;
var maxValue = nodes[nodes.length - 1].getLayout().value;
nodes.forEach(function (node) {
var mapping = new VisualMapping({
type: 'color',
mappingMethod: 'linear',
dataExtent: [minValue, maxValue],
visual: seriesModel.get('color')
});
var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value);
node.setVisual('color', mapValueToColor);
});
}) ;
};
});
\ No newline at end of file
define(function (require) {
var zrUtil = require('zrender/core/util');
/**
* nest helper used to group by the array.
* can specified the keys and sort the keys.
*/
function nest() {
var keysFunction = [];
var sortKeysFunction = [];
/**
* map an Array into the mapObject.
* @param {Array} array
* @param {number} depth
*/
function map(array, depth) {
if (depth >= keysFunction.length) {
return array;
}
var i = -1;
var n = array.length;
var keyFunction = keysFunction[depth++];
var mapObject = {};
var valuesByKey = {};
while (++i < n) {
var keyValue = keyFunction(array[i]);
var values = valuesByKey[keyValue];
if (values) {
values.push(array[i]);
}
else {
valuesByKey[keyValue] = [array[i]];
}
}
zrUtil.each(valuesByKey, function (value, key) {
mapObject[key] = map(value, depth);
});
return mapObject;
}
/**
* transform the Map Object to multidimensional Array
* @param {Object} map
* @param {number} depth
*/
function entriesMap(mapObject, depth) {
if (depth >= keysFunction.length) {
return mapObject;
}
var array = [];
var sortKeyFunction = sortKeysFunction[depth++];
zrUtil.each(mapObject, function (value, key) {
array.push({key: key, values: entriesMap(value, depth)});
});
if (sortKeyFunction) {
return array.sort(function (a, b) {
return sortKeyFunction(a.key, b.key);
});
}
else {
return array;
}
}
return {
/**
* specified the key to groupby the arrays.
* users can specified one more keys.
* @param {Function} d
*/
key: function (d) {
keysFunction.push(d);
return this;
},
/**
* specified the comparator to sort the keys
* @param {Function} order
*/
sortKeys: function (order) {
sortKeysFunction[keysFunction.length - 1] = order;
return this;
},
/**
* the a
* @param {Array} array
*/
entries: function (array) {
return entriesMap(map(array, 0), 0);
}
};
}
return nest;
});
\ No newline at end of file
{"nodes":[
{"name":"Agricultural 'waste'"},
{"name":"Bio-conversion"},
{"name":"Liquid"},
{"name":"Losses"},
{"name":"Solid"},
{"name":"Gas"},
{"name":"Biofuel imports"},
{"name":"Biomass imports"},
{"name":"Coal imports"},
{"name":"Coal"},
{"name":"Coal reserves"},
{"name":"District heating"},
{"name":"Industry"},
{"name":"Heating and cooling - commercial"},
{"name":"Heating and cooling - homes"},
{"name":"Electricity grid"},
{"name":"Over generation / exports"},
{"name":"H2 conversion"},
{"name":"Road transport"},
{"name":"Agriculture"},
{"name":"Rail transport"},
{"name":"Lighting & appliances - commercial"},
{"name":"Lighting & appliances - homes"},
{"name":"Gas imports"},
{"name":"Ngas"},
{"name":"Gas reserves"},
{"name":"Thermal generation"},
{"name":"Geothermal"},
{"name":"H2"},
{"name":"Hydro"},
{"name":"International shipping"},
{"name":"Domestic aviation"},
{"name":"International aviation"},
{"name":"National navigation"},
{"name":"Marine algae"},
{"name":"Nuclear"},
{"name":"Oil imports"},
{"name":"Oil"},
{"name":"Oil reserves"},
{"name":"Other waste"},
{"name":"Pumped heat"},
{"name":"Solar PV"},
{"name":"Solar Thermal"},
{"name":"Solar"},
{"name":"Tidal"},
{"name":"UK land based bioenergy"},
{"name":"Wave"},
{"name":"Wind"}
],
"links":[
{"source": "Agricultural 'waste'", "target": "Bio-conversion", "value": 124.729},
{"source": "Bio-conversion", "target": "Liquid", "value": 0.597},
{"source": "Bio-conversion", "target": "Losses", "value": 26.862},
{"source": "Bio-conversion", "target": "Solid", "value": 280.322},
{"source": "Bio-conversion", "target": "Gas", "value": 81.144},
{"source": "Biofuel imports", "target": "Liquid", "value": 35},
{"source": "Biomass imports", "target": "Solid", "value": 35},
{"source": "Coal imports", "target": "Coal", "value": 11.606},
{"source": "Coal reserves","target": "Coal", "value": 63.965},
{"source": "Coal", "target": "Solid", "value": 75.571},
{"source": "District heating", "target": "Industry", "value": 10.639},
{"source": "District heating", "target": "Heating and cooling - commercial", "value": 22.505},
{"source": "District heating", "target": "Heating and cooling - homes", "value": 46.184},
{"source": "Electricity grid", "target": "Over generation / exports", "value": 104.453},
{"source": "Electricity grid", "target": "Heating and cooling - homes", "value": 113.726},
{"source": "Electricity grid", "target": "H2 conversion", "value": 27.14},
{"source": "Electricity grid", "target": "Industry", "value": 342.165},
{"source": "Electricity grid", "target": "Road transport", "value": 37.797},
{"source": "Electricity grid", "target": "Agriculture", "value": 4.412},
{"source": "Electricity grid", "target": "Heating and cooling - commercial", "value": 40.858},
{"source": "Electricity grid", "target": "Losses", "value": 56.691},
{"source": "Electricity grid", "target": "Rail transport", "value": 7.863},
{"source": "Electricity grid", "target": "Lighting & appliances - commercial", "value": 90.008},
{"source": "Electricity grid", "target": "Lighting & appliances - homes", "value": 93.494},
{"source": "Gas imports", "target": "Ngas", "value": 40.719},
{"source": "Gas reserves", "target": "Ngas", "value": 82.233},
{"source": "Gas", "target": "Heating and cooling - commercial", "value": 0.129},
{"source": "Gas", "target": "Losses", "value": 1.401},
{"source": "Gas", "target": "Thermal generation", "value": 151.891},
{"source": "Gas", "target": "Agriculture", "value": 2.096},
{"source": "Gas", "target": "Industry", "value": 48.58},
{"source": "Geothermal", "target": "Electricity grid", "value": 7.013},
{"source": "H2 conversion", "target": "H2", "value": 20.897},
{"source": "H2 conversion", "target": "Losses", "value": 6.242},
{"source": "H2", "target": "Road transport", "value": 20.897},
{"source": "Hydro", "target": "Electricity grid", "value": 6.995},
{"source": "Liquid", "target": "Industry", "value": 121.066},
{"source": "Liquid", "target": "International shipping", "value": 128.69},
{"source": "Liquid", "target": "Road transport", "value": 135.835},
{"source": "Liquid", "target": "Domestic aviation", "value": 14.458},
{"source": "Liquid", "target": "International aviation", "value": 206.267},
{"source": "Liquid", "target": "Agriculture", "value": 3.64},
{"source": "Liquid", "target": "National navigation", "value": 33.218},
{"source": "Liquid", "target": "Rail transport", "value": 4.413},
{"source": "Marine algae", "target": "Bio-conversion", "value": 4.375},
{"source": "Ngas", "target": "Gas", "value": 122.952},
{"source": "Nuclear", "target": "Thermal generation", "value": 839.978},
{"source": "Oil imports", "target": "Oil", "value": 504.287},
{"source": "Oil reserves", "target": "Oil", "value": 107.703},
{"source": "Oil", "target": "Liquid", "value": 611.99},
{"source": "Other waste", "target": "Solid", "value": 56.587},
{"source": "Other waste", "target": "Bio-conversion", "value": 77.81},
{"source": "Pumped heat", "target": "Heating and cooling - homes", "value": 193.026},
{"source": "Pumped heat", "target": "Heating and cooling - commercial", "value": 70.672},
{"source": "Solar PV", "target": "Electricity grid", "value": 59.901},
{"source": "Solar Thermal", "target": "Heating and cooling - homes", "value": 19.263},
{"source": "Solar", "target": "Solar Thermal", "value": 19.263},
{"source": "Solar", "target": "Solar PV", "value": 59.901},
{"source": "Solid", "target": "Agriculture", "value": 0.882},
{"source": "Solid", "target": "Thermal generation", "value": 400.12},
{"source": "Solid", "target": "Industry", "value": 46.477},
{"source": "Thermal generation", "target": "Electricity grid", "value": 525.531},
{"source": "Thermal generation", "target": "Losses", "value": 787.129},
{"source": "Thermal generation", "target": "District heating", "value": 79.329},
{"source": "Tidal", "target": "Electricity grid", "value": 9.452},
{"source": "UK land based bioenergy", "target": "Bio-conversion", "value": 182.01},
{"source": "Wave", "target": "Electricity grid", "value": 19.013},
{"source": "Wind", "target": "Electricity grid", "value": 289.366}
]}
{"nodes": [
{"name": "Total"},
{"name": "Environment"},
{"name": "Land use"},
{"name": "Cocoa butter (Organic)"},
{"name": "Cocoa mass (Organic)"},
{"name": "Hazelnuts (Organic)"},
{"name": "Cane sugar (Organic)"},
{"name": "Vegetables (Organic)"},
{"name": "Climate change"},
{"name": "Harmful substances"},
{"name": "Water use"},
{"name": "Resource depletion"},
{"name": "Refrigeration"},
{"name": "Packaging"},
{"name": "Human rights"},
{"name": "Child labour"},
{"name": "Coconut oil (Organic)"},
{"name": "Forced labour"},
{"name": "Health safety"},
{"name": "Access to water"},
{"name": "Freedom of association"},
{"name": "Access to land"},
{"name": "Sufficient wage"},
{"name": "Equal rights migrants"},
{"name": "Discrimination"},
{"name": "Working hours"}
],
"links": [
{"source": "Total", "target": "Environment", "value": 0.342284047256003},
{"source": "Environment", "target": "Land use", "value": 0.32322870366987},
{"source": "Land use", "target": "Cocoa butter (Organic)", "value": 0.177682517071359},
{"source": "Land use", "target": "Cocoa mass (Organic)", "value": 0.137241325342711},
{"source": "Land use", "target": "Hazelnuts (Organic)", "value": 0.00433076373512774},
{"source": "Land use", "target": "Cane sugar (Organic)", "value": 0.00296956039863467},
{"source": "Land use", "target": "Vegetables (Organic)", "value": 0.00100453712203756},
{"source": "Environment", "target": "Climate change", "value": 0.0112886157414413},
{"source": "Climate change", "target": "Cocoa butter (Organic)", "value": 0.00676852971933996},
{"source": "Climate change", "target": "Cocoa mass (Organic)", "value": 0.00394686874786743},
{"source": "Climate change", "target": "Cane sugar (Organic)", "value": 0.000315972058711838},
{"source": "Climate change", "target": "Hazelnuts (Organic)", "value": 0.000218969462265292},
{"source": "Climate change", "target": "Vegetables (Organic)", "value": 3.82757532567656e-05},
{"source": "Environment", "target": "Harmful substances", "value": 0.00604275542495656},
{"source": "Harmful substances", "target": "Cocoa mass (Organic)", "value": 0.0055125989240741},
{"source": "Harmful substances", "target": "Cocoa butter (Organic)", "value": 0.000330017607892127},
{"source": "Harmful substances", "target": "Cane sugar (Organic)", "value": 0.000200138892990337},
{"source": "Harmful substances", "target": "Hazelnuts (Organic)", "value": 0},
{"source": "Harmful substances", "target": "Vegetables (Organic)", "value": 0},
{"source": "Environment", "target": "Water use", "value": 0.00148345269044703},
{"source": "Water use", "target": "Cocoa butter (Organic)", "value": 0.00135309891304186},
{"source": "Water use", "target": "Cocoa mass (Organic)", "value": 0.000105714137908639},
{"source": "Water use", "target": "Hazelnuts (Organic)", "value": 1.33452642581887e-05},
{"source": "Water use", "target": "Cane sugar (Organic)", "value": 8.78074837009238e-06},
{"source": "Water use", "target": "Vegetables (Organic)", "value": 2.5136268682477e-06},
{"source": "Environment", "target": "Resource depletion", "value": 0.000240519729288764},
{"source": "Resource depletion", "target": "Cane sugar (Organic)", "value": 0.000226237279345084},
{"source": "Resource depletion", "target": "Vegetables (Organic)", "value": 1.42824499436793e-05},
{"source": "Resource depletion", "target": "Hazelnuts (Organic)", "value": 0},
{"source": "Resource depletion", "target": "Cocoa mass (Organic)", "value": 0},
{"source": "Resource depletion", "target": "Cocoa butter (Organic)", "value": 0},
{"source": "Environment", "target": "Refrigeration", "value": 0},
{"source": "Environment", "target": "Packaging", "value": 0},
{"source": "Total", "target": "Human rights", "value": 0.307574096993239},
{"source": "Human rights", "target": "Child labour", "value": 0.0410641202645833},
{"source": "Child labour", "target": "Hazelnuts (Organic)", "value": 0.0105339381639722},
{"source": "Child labour", "target": "Cocoa mass (Organic)", "value": 0.0105},
{"source": "Child labour", "target": "Cocoa butter (Organic)", "value": 0.0087294420777},
{"source": "Child labour", "target": "Coconut oil (Organic)", "value": 0.00474399974233333},
{"source": "Child labour", "target": "Cane sugar (Organic)", "value": 0.00388226450884445},
{"source": "Child labour", "target": "Vegetables (Organic)", "value": 0.00267447577173333},
{"source": "Human rights", "target": "Forced labour", "value": 0.0365458590642445},
{"source": "Forced labour", "target": "Hazelnuts (Organic)", "value": 0.0114913076376389},
{"source": "Forced labour", "target": "Cocoa butter (Organic)", "value": 0.0081134807347},
{"source": "Forced labour", "target": "Cocoa mass (Organic)", "value": 0.00765230236575},
{"source": "Forced labour", "target": "Cane sugar (Organic)", "value": 0.004},
{"source": "Forced labour", "target": "Vegetables (Organic)", "value": 0.00296668823626667},
{"source": "Forced labour", "target": "Coconut oil (Organic)", "value": 0.00232208008988889},
{"source": "Human rights", "target": "Health safety", "value": 0.0345435327843611},
{"source": "Health safety", "target": "Hazelnuts (Organic)", "value": 0.0121419536385},
{"source": "Health safety", "target": "Cocoa mass (Organic)", "value": 0.00766772850678333},
{"source": "Health safety", "target": "Cocoa butter (Organic)", "value": 0.0056245892061},
{"source": "Health safety", "target": "Coconut oil (Organic)", "value": 0.00361616847688889},
{"source": "Health safety", "target": "Cane sugar (Organic)", "value": 0.00277374682533333},
{"source": "Health safety", "target": "Vegetables (Organic)", "value": 0.00271934613075556},
{"source": "Human rights", "target": "Access to water", "value": 0.0340206659360667},
{"source": "Access to water", "target": "Cocoa mass (Organic)", "value": 0.0105},
{"source": "Access to water", "target": "Cocoa butter (Organic)", "value": 0.0089274160792},
{"source": "Access to water", "target": "Hazelnuts (Organic)", "value": 0.0054148022845},
{"source": "Access to water", "target": "Cane sugar (Organic)", "value": 0.00333938149786667},
{"source": "Access to water", "target": "Vegetables (Organic)", "value": 0.00314663377488889},
{"source": "Access to water", "target": "Coconut oil (Organic)", "value": 0.00269243229961111},
{"source": "Human rights", "target": "Freedom of association", "value": 0.0320571523941667},
{"source": "Freedom of association", "target": "Hazelnuts (Organic)", "value": 0.0132312483463611},
{"source": "Freedom of association", "target": "Cocoa butter (Organic)", "value": 0.0077695200707},
{"source": "Freedom of association", "target": "Cocoa mass (Organic)", "value": 0.00510606573995},
{"source": "Freedom of association", "target": "Vegetables (Organic)", "value": 0.00354321156324444},
{"source": "Freedom of association", "target": "Cane sugar (Organic)", "value": 0.00240710667391111},
{"source": "Freedom of association", "target": "Coconut oil (Organic)", "value": 0},
{"source": "Human rights", "target": "Access to land", "value": 0.0315022209894056},
{"source": "Access to land", "target": "Hazelnuts (Organic)", "value": 0.00964970063322223},
{"source": "Access to land", "target": "Cocoa mass (Organic)", "value": 0.00938530207965},
{"source": "Access to land", "target": "Cocoa butter (Organic)", "value": 0.0060110791848},
{"source": "Access to land", "target": "Cane sugar (Organic)", "value": 0.00380818314608889},
{"source": "Access to land", "target": "Vegetables (Organic)", "value": 0.00264795594564445},
{"source": "Access to land", "target": "Coconut oil (Organic)", "value": 0},
{"source": "Human rights", "target": "Sufficient wage", "value": 0.0287776757227333},
{"source": "Sufficient wage", "target": "Cocoa mass (Organic)", "value": 0.00883512456493333},
{"source": "Sufficient wage", "target": "Cocoa butter (Organic)", "value": 0.0078343367268},
{"source": "Sufficient wage", "target": "Coconut oil (Organic)", "value": 0.00347879026511111},
{"source": "Sufficient wage", "target": "Hazelnuts (Organic)", "value": 0.00316254211388889},
{"source": "Sufficient wage", "target": "Vegetables (Organic)", "value": 0.00281013722808889},
{"source": "Sufficient wage", "target": "Cane sugar (Organic)", "value": 0.00265674482391111},
{"source": "Human rights", "target": "Equal rights migrants", "value" : 0.0271146645119444},
{"source": "Equal rights migrants", "target": "Cocoa butter (Organic)", "value": 0.0071042315061},
{"source": "Equal rights migrants", "target": "Cocoa mass (Organic)", "value": 0.00636673210005},
{"source": "Equal rights migrants", "target": "Hazelnuts (Organic)", "value": 0.00601459775836111},
{"source": "Equal rights migrants", "target": "Coconut oil (Organic)", "value": 0.00429185583138889},
{"source": "Equal rights migrants", "target": "Cane sugar (Organic)", "value": 0.00182647471915556},
{"source": "Equal rights migrants", "target": "Vegetables (Organic)", "value": 0.00151077259688889},
{"source": "Human rights", "target": "Discrimination", "value": 0.0211217763359833},
{"source": "Discrimination", "target": "Cocoa mass (Organic)", "value": 0.00609671700306667},
{"source": "Discrimination", "target": "Cocoa butter (Organic)", "value": 0.0047738806325},
{"source": "Discrimination", "target": "Coconut oil (Organic)", "value": 0.00368119084494444},
{"source": "Discrimination", "target": "Vegetables (Organic)", "value": 0.00286009813604444},
{"source": "Discrimination", "target": "Cane sugar (Organic)", "value": 0.00283706180951111},
{"source": "Discrimination", "target": "Hazelnuts (Organic)", "value": 0.000872827909916666},
{"source": "Human rights", "target": "Working hours", "value": 0.02082642898975},
{"source": "Working hours", "target": "Hazelnuts (Organic)", "value": 0.0107216773848333},
{"source": "Working hours", "target": "Coconut oil (Organic)", "value": 0.00359009052944444},
{"source": "Working hours", "target": "Vegetables (Organic)", "value": 0.00212300379075556},
{"source": "Working hours", "target": "Cocoa butter (Organic)", "value": 0.0018518584356},
{"source": "Working hours", "target": "Cocoa mass (Organic)", "value": 0.00158227069058333},
{"source": "Working hours", "target": "Cane sugar (Organic)", "value": 0.000957528158533333}
]}
<html>
<head>
<meta chartset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="esl.js"></script>
<script src="config.js"></script>
<script src="config.js"></script>
<script src="lib/jquery.min.js"></script>
</head>
<body>
<style>
html, body, #main {
width: 100%;
height: 90%;
/*border: 1px solid #000;*/
}
</style>
<div id="main"><div>
<script>
require([
'echarts',
'echarts/chart/sankey',
'echarts/component/tooltip'
], function (echarts) {
var chart = echarts.init(document.getElementById('main'), null, {
renderer: 'canvas'
});
window.onresize = function () {
chart.resize();
}
$.getJSON('./data/energy.json')
.done(function(data) {
var nodes = [];
var edges = [];
$.each(data.nodes, function (i, node) {
nodes.push(node);
});
$.each(data.links, function (i, edge) {
edges.push(edge);
});
chart.setOption({
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: [
{
type: 'sankey',
layout:'none',
data: nodes,
links: edges,
linestyle: {
normal: {
curveness: 0.5
}
}
}
]
});
});
});
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册