HTMLcopy
1
<div id="container"></div>
CSScopy
8
1
html,
2
body,
3
#container {
4
width: 100%;
5
height: 100%;
6
margin: 0;
7
padding: 0;
8
}
JavaScriptcopy
x
1
anychart.onDocumentReady(function () {
2
var stage = anychart.graphics.create('container');
3
4
var chart = anychart.column();
5
chart.title('TV Shows Ad Revenue for Popular Channels');
6
chart.title().margin().bottom(30);
7
8
// The data used in this sample can be obtained from the CDN
9
// https://cdn.anychart.com/samples/custom-drawing/custom-stacked-tooltip/data.js
10
chart.column(getHBOData()).name('HBO'); // eslint-disable-line no-undef
11
chart.column(getABCData()).name('ABC'); // eslint-disable-line no-undef
12
chart.column(getCBSData()).name('CBS'); // eslint-disable-line no-undef
13
chart.column(getFOXData()).name('FOX'); // eslint-disable-line no-undef
14
15
chart.yScale().stackMode('percent');
16
17
chart.tooltip({ displayMode: 'union', enabled: false });
18
chart.legend({
19
position: 'right',
20
itemsLayout: 'vertical',
21
align: 'top'
22
});
23
24
chart.container(stage).draw();
25
26
// distance between right x coordinate of the point and left x coordinate of info bar
27
var dx = 40;
28
29
// distance to widen height of info bar (point top y coord minus dy and bot y coord plus dy)
30
var dy = 20;
31
32
var drawMiniStack = function (path, x, y, width, height) {
33
path
34
.moveTo(x, y)
35
.lineTo(x + width, y)
36
.lineTo(x + width, y + height)
37
.lineTo(x, y + height)
38
.lineTo(x, y)
39
.close();
40
return y + height;
41
};
42
43
var textOffsetX = 5;
44
var textOffsetY = 5;
45
var WIDTH_TOOLTIP = 150;
46
47
var drawText = function (textElement, text, x, y, h) {
48
textElement
49
.htmlText(text)
50
.x(x + textOffsetX)
51
.y(y - textOffsetY)
52
.height(h)
53
.vAlign('middle')
54
.hAlign('center')
55
.width(WIDTH_TOOLTIP)
56
.visible(true);
57
};
58
59
var texts = [
60
chart.container().text().zIndex(110),
61
chart.container().text().zIndex(111),
62
chart.container().text().zIndex(112)
63
];
64
65
// create path and put it high over other elements.
66
var path = chart
67
.container()
68
.path()
69
.stroke('#c1c1c1')
70
.fill('#fff')
71
.zIndex(100);
72
73
var connectorPath = chart
74
.container()
75
.path()
76
.stroke('#cecece')
77
.fill(null)
78
.zIndex(101);
79
80
var connectorRect = chart
81
.container()
82
.path()
83
.stroke(null)
84
.fill('#fff')
85
.zIndex(100);
86
87
chart.listen('pointshover', function (e) {
88
var i;
89
for (i = 0; i < texts.length; i++) {
90
texts[i].visible(false);
91
}
92
path.clear();
93
connectorPath.clear();
94
connectorRect.clear();
95
var point = e.point;
96
// do nothing if point is unhover
97
if (!point.hovered()) return true;
98
99
// fetch meta form point data.
100
var meta = point.get('meta');
101
// if there is no meta then nothing to do here :D
102
if (!meta) return true;
103
104
var series = point.getSeries();
105
106
var pw = series.getPixelPointWidth();
107
108
var topY = series.transformY(point.getStackValue());
109
var botY = series.transformY(point.getStackZero());
110
var rightX = series.transformX(point.get('x'), 0.5) + pw / 2;
111
var leftX = rightX - pw;
112
113
var columnTopY = topY - dy;
114
var columnBotY = botY + dy;
115
116
var columnHeight = columnBotY - columnTopY;
117
118
var columnLeftX = rightX + dx;
119
var columnRightX = leftX - dx - WIDTH_TOOLTIP;
120
121
var values = meta.values;
122
var names = meta.names;
123
var sum = 0;
124
125
for (i = 0; i < values.length; sum += values[i++]);
126
var ratios = values.map(function (item) {
127
return item / sum;
128
});
129
var heights = ratios.map(function (item) {
130
return columnHeight * item;
131
});
132
133
var y = columnTopY;
134
var positionX;
135
var text;
136
for (i = 0; i < heights.length; i++) {
137
text =
138
'<span style="font-size: 16px;font-weight: bold;color:#7c868e;">' +
139
Math.ceil(ratios[i].toFixed(2) * 100) +
140
'%</span><br/>' +
141
'<span style="color:#212121;font-size:12px">"' +
142
names[i] +
143
'"</span>';
144
145
if (isRightPositionTooltip()) {
146
positionX = columnLeftX;
147
} else {
148
positionX = columnRightX;
149
}
150
151
drawText(texts[i], text, positionX, y, heights[i]);
152
y = drawMiniStack(path, positionX, y, WIDTH_TOOLTIP, heights[i]);
153
}
154
155
if (isRightPositionTooltip()) {
156
createConnectorPath(rightX, columnLeftX);
157
} else {
158
createConnectorPath(leftX, columnRightX + WIDTH_TOOLTIP);
159
}
160
161
function createConnectorPath(x, columnX) {
162
connectorPath
163
.moveTo(x, topY)
164
.lineTo(columnX, columnTopY)
165
.close()
166
.moveTo(columnX, columnBotY)
167
.lineTo(x, botY)
168
.close();
169
170
connectorRect
171
.moveTo(x, topY)
172
.lineTo(columnX, columnTopY)
173
.lineTo(columnX, columnBotY)
174
.lineTo(x, botY)
175
.close()
176
.fill('#fff');
177
}
178
179
function isRightPositionTooltip() {
180
return stage.width() >= columnLeftX + WIDTH_TOOLTIP;
181
}
182
});
183
});