HTMLcopy
1
<div id="container"></div>
CSScopy
6
1
html, body, #container {
2
width: 100%;
3
height: 100%;
4
margin: 0;
5
padding: 0;
6
}
JavaScriptcopy
x
1
anychart.onDocumentReady(function() {
2
var rawData = [
3
['x', 'Coal', 'Natural Gas', 'Nuclear', 'Hydroelectric'],
4
[1990, 2500, 1000, 1500, 1000],
5
[1991, 2520, 1150, 1550, 1100],
6
[1992, 2530, 1100, 1540, 1100],
7
[1993, 2540, 1100, 1530, 1000],
8
[1994, 2500, 1150, 1500, 1050],
9
[1995, 2300, 1200, 1600, 1060],
10
[1996, 2250, 1250, 1650, 1070],
11
[1997, 2200, 1200, 1600, 1080],
12
[1998, 2150, 1200, 1500, 1050],
13
[1999, 2100, 1250, 1500, 1010],
14
[2000, 2100, 1250, 1650, 1100],
15
[2001, 2100, 1300, 1600, 1090],
16
[2002, 2100, 1350, 1650, 1050],
17
[2003, 2100, 1300, 1670, 1040],
18
[2004, 2150, 1300, 1680, 1070],
19
[2005, 2200, 1500, 1700, 1030],
20
[2006, 2150, 1500, 1710, 1030],
21
[2007, 2100, 1600, 1710, 1020],
22
[2008, 1700, 1700, 1850, 1010],
23
[2009, 1750, 1700, 1800, 1000],
24
[2010, 1700, 1750, 1800, 1000],
25
[2011, 1650, 1700, 1850, 1010],
26
[2012, 1600, 1750, 1850, 1020],
27
[2013, 1600, 2000, 1750, 1040],
28
[2014, 1500, 2100, 1700, 1050],
29
[2015, 1509, 2050, 1700, 1030],
30
[2016, 1520, 2000, 1650, 1020],
31
[2017, 1510, 2050, 1650, 1010],
32
[2018, 1430, 2100, 1600, 1020]
33
];
34
35
var seriesNames = rawData[0].slice(1);
36
var seriesDatum = preprocessData(rawData);
37
38
// create and setup chart
39
chart = anychart.area();
40
chart.palette(['#67614c', '#e49333', '#9e70c2', '#7ee3e9']);
41
// adjust scales
42
chart.xScale().mode('continuous');
43
chart.yScale().minimum(0);
44
chart.yScale().maximum(100);
45
chart.yAxis().labels().format('{%value}%');
46
chart.tooltip(false);
47
chart.legend(true);
48
49
// create and setup series
50
var series;
51
for (var i = 0; i < seriesDatum.length; i++) {
52
series = chart.rangeSplineArea(seriesDatum[i]);
53
series.stroke('none');
54
series.name(seriesNames[i]);
55
series.hovered().markers(false);
56
series.selected().markers(false);
57
}
58
59
// draw chart to container
60
chart.container('container').draw();
61
});
62
63
function descSort(a, b) {
64
return b.value - a.value;
65
}
66
67
function sum(arr) {
68
var sum = 0;
69
for (var i = 1; i < arr.length; i++) {
70
sum += arr[i];
71
}
72
return sum;
73
}
74
75
var defaultLabelConfig = {
76
enabled: true,
77
fontColor: 'black',
78
format: '{%value}{decimalsCount:2}%'
79
}
80
81
function setLabelConfig(seriesDatum, values, rowIndex, anchor) {
82
for (var j = 0; j < values.length; j++) {
83
originalIndex = values[j].index;
84
seriesDatum[originalIndex][rowIndex]['label'] = {
85
...defaultLabelConfig, anchor
86
};
87
}
88
}
89
90
function preprocessData(rawData) {
91
var x, row, high, low, point;
92
var valuesSum;
93
var seriesDatum = [];
94
var i, j;
95
96
for (i = 1; i < rawData.length; i++) {
97
row = rawData[i];
98
var valuesSum = sum(row);
99
x = row[0];
100
// convert values to object with value and index, to save original index.
101
var values = row.slice(1).map((value, index) => ({value, index}));
102
103
// here we have sorted array, and know original indexes.
104
values.sort(descSort);
105
106
high = 100;
107
108
var originalIndex;
109
for (j = 0; j < values.length; j++) {
110
var valueObj = values[j];
111
var value = valueObj.value;
112
originalIndex = valueObj.index;
113
114
// JS mathematics sometimes calculate low value lower than zero
115
low = Math.max(0, high - 100 * value / valuesSum);
116
point = { x, high, low };
117
high = low;
118
seriesDatum[originalIndex] ? seriesDatum[originalIndex][i - 1] = point : seriesDatum[originalIndex] = [point];
119
}
120
121
if (i === 1) {
122
setLabelConfig(seriesDatum, values, 0, 'left-top')
123
}
124
if (i === rawData.length - 1) {
125
setLabelConfig(seriesDatum, values, i - 1, 'right-top');
126
}
127
}
128
return seriesDatum;
129
}