I am trying to display a stacked Column Chart on tooltip (using HighCharter api in R). I was able to get a column chart displayed as the tooltip but the bars are not stacking up.
Here is the code that I am trying :
donutBase2=
donutBase %>%
select(nameTeam,primary_color,Type, Value, Category) %>%
nest(data=c(-nameTeam,-primary_color)) %>%
mutate(
data = map(data, mutate_mapping, hcaes(y = Value, x = Category, group = Type), drop = TRUE) ,
data = map(data, list_parse2)
) %>%
rename(ttdata = data) %>%
mutate(segment = 1)
hchart(
donutBase2,
"pie",
hcaes(name = nameTeam, y = segment, color = primary_color),
innerSize = 500
) %>%
hc_tooltip(
useHTML = TRUE,
headerFormat = "<b>{point.key}</b>",
pointFormatter = tooltip_chart(
accesor = "ttdata",
hc_opts = list(
chart = list(type = "column"),
yAxis = list(title = list(text = "FG3M")),
xAxis = list( title = list(text = "Game #")),
plotOptions = list(area = list(fillOpacity = 0.2),series=list(stacking="percent"))
),
height = 225,
width = 375
)
)
[Output of the above code][1]
Here is the inspiration for the above code:
[HighcharterR api][2]
I am not very familiar with the correct Javascript option, would anyone help me as to how to convert the bars to stacked mode ?
[1]: https://i.stack.imgur.com/OzHCE.png
[2]: https://jkunst.com/blog/posts/2019-02-04-using-tooltips-in-unexpected-ways/
Here you have a configuration of how to set a column series with stacked property inside the tooltip.
Live demo: https://jsfiddle.net/BlackLabel/7ybztdsw/
function renderChart(point) {
Highcharts.chart('hc-tooltip', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true
}
}
},
series: [{
data: point.options.eData,
dataLabels: {
enabled: false
}
},
{
data: point.options.eData,
dataLabels: {
enabled: false
}
}, {
data: point.options.eData,
dataLabels: {
enabled: false
}
}
]
});
}
Highcharts.addEvent(
Highcharts.Tooltip,
'refresh',
function() {
renderChart(this.chart.hoverPoint);
}
);
Highcharts.chart('container', {
title: {
text: 'Chart inside tooltip demo'
},
tooltip: {
useHTML: true,
headerFormat: '',
pointFormat: '<div id="hc-tooltip"></div>'
},
series: [{
type: 'line',
data: [{
y: 10,
eData: [1, 2, 3, 4, 5]
}, {
y: 5,
eData: [-10, 20, 50, 70, 20]
}, {
y: 2,
eData: [103, 11, 12, 54, 68]
}]
}]
});
Related
I have this plot, where I put some markers (stripLines) on minimun and maximum values. I´d like to show the xValue only on the markers, to make the chart more readable.
In this plot I'm using an interval of 50 and my data for xAxis is not set properly. What I wish to do is to show the value on xAxis only where the markers show up. Is there any property that does that? I can't find it on the documentaion.
Here is the code where I generate the chart
const options = {
theme: "light2", // "light1", "dark1", "dark2"
animationEnabled: true,
zoomEnabled: false,
toolTip:{
enabled: false,
},
axisX: [{
crosshair: {
enabled: true
},
stripLines:[
{
value: marker[0],
thickness: 2,
label: ""
},
{
value: marker[1],
thickness: 2,
label: ""
},
],
//title: "X title 1",
//margin: 20,
valueFormatString: "DD/MMM/YY" ,
labelMaxWidth: 70,
//labelWrap: true,
interval: 50,
titleFontColor:"#7680B2",
lineColor:"#7680B2",
tickColor:"#7680B2",
labelFontColor:"#7680B2",
lineThickness: 2,
},
{
//title: "X title 2",
margin: 0,
valueFormatString: "DD/MMM/YY" ,
//zlabelWrap: true,
interval: 50,
titleFontColor:"#62D2A9",
lineColor:"#62D2A9",
tickColor:"#62D2A9",
labelFontColor:"#62D2A9",
lineThickness: 2,
}],
axisY: {
includeZero: false
},
data: [
{
color:"#7680B2",
type: "spline",
axisXIndex: 0,
xValueType: "dateTime",
dataPoints: dataPoints,
},
{
color:"#62D2A9",
type: "spline",
axisXIndex: 1,
xValueType: "dateTime",
dataPoints: dataPoints2,
},
]
}
return (
<div className="ChartWithZoom">
<h1>Longe do pico</h1>
<CanvasJSChart options = {options}
/* onRef={ref => this.chart = ref} */
/>
</div>
);
I think I found a workaround, there is a function that handles that situation, labelFormatter: function ( e ), this is my solution:
var chart = new CanvasJS.Chart("container",
{
.
.
axisX:{
interval: 1,
intervalType: 'day',
labelFormatter: function ( e ) {
let data = CanvasJSReact.CanvasJS.formatDate(e.value, "DD/MMM/YY");
//marker is an array that I get the dates for the marker
let minMarker = CanvasJSReact.CanvasJS.formatDate(marker[0], "DD/MMM/YY");
let maxMarker = CanvasJSReact.CanvasJS.formatDate(marker[1], "DD/MMM/YY");
if ( data === minMarker || data === maxMarker ) {
return CanvasJSReact.CanvasJS.formatDate(e.value, "DD/MMM/YY");
} else {
return "";
}
};
},
.
.
});
chart.render();
e: { // parameter sent to function
chart,
axis,
value,
label
}
This is the result:
I want to access another series row data in series dataLabels. Here is my code.
categoriesarr = [1,2,3,4,5];
noofloandisbursed = [10, 20, 30, 40, 50];
pdo = [9, 18, 27, 40, 49];
var chart = new Highcharts.Chart({
chart: {
renderTo: 'disbursement'
},
title: {
text: ''
},
subtitle: {
text: ''
},
xAxis: {
categories: categoriesarr
},
tooltip: {
pointFormat: '<b>{point.y}</b>'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 0,
floating: true,
borderWidth: 1,
backgroundColor: ((Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#fff'),
shadow: true
},
series: [{
name: 'No. Of Loan Disbursed',
type: 'column',
data: noofloandisbursed
},
{
name: 'Pre-Disbursement Orientation',
type: 'column',
data: pdo,
dataLabels: {
enabled: true,
formatter: function(e) {
//return ((this.point.y/series[0].point.y)*100) + '%';
}
}
}]
});
I want to show the result of (series 2 value / series 1 value) * 100 in the dataLabels concatenation with % only in second series. Unfortunately i can't access the series 1's y point values. When i tried series[0].yData, it returns the whole array, not the specific row matched with second row. I also tried to pass array, but it wasn't working. Need solution of this problem.
You can find the point from the first series by index:
series: [{
...
},
{
...,
dataLabels: {
enabled: true,
formatter: function(e) {
return (
(this.point.y /
this.series.chart.series[0].points[this.point.index].y) *
100) + '%';
}
}
}
]
Live demo: http://jsfiddle.net/BlackLabel/rdwxc382/
API Reference: https://api.highcharts.com/highcharts/series.column.dataLabels.formatter
I am creating a dynamic updated highstock chart with 2 series but at start one series is rendering in wrong place. And when I resize the selection in navigator the series comes back to its correct place.
Here is the config of highstock:
Highcharts.setOptions({
global: {
useUTC: false
}
});
var groupingUnits = [['millisecond', [1, 2, 5, 10, 20, 25, 50, 100, 200, 500]],
['second',[1, 2, 5, 10, 15, 30]],
['minute',[1, 2, 5, 10, 15, 30]],
['day',[1]]
];
// Create the chart
Highcharts.stockChart('container', {
chart: {
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
var series1 = this.series[1];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, false);
series1.addPoint([x, y], true, false);
}, 500);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1min'
},
{
count: 3,
type: 'minute',
text: '3min'
}, {
count: 5,
type: 'minute',
text: '5min'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 3
},
exporting: {
enabled: false
},
title: {
text: 'Live Chart'
},
yAxis: [
{
labels: {
align: 'right',
x: -3
},
title: {
text: 'Line'
},
height: '60%',
lineWidth: 2,
resize: {
enabled: true
}
},
{
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
tooltip: {
split: true
},
series: [
{
type: 'line',
name: 'OHLC',
data: [[]],
dataGrouping: {
units: groupingUnits
}
},
{
type: 'column',
name: 'Volume',
data: [[]],
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}
]
});
I have created a fiddle for the same:
https://jsfiddle.net/xu058sgp/23/
I have tried changing the height and top property of yAxis but nothing seems to fix this issue. I am not sure but it can be due to the frequency in which the data is getting updated.
Can someone point me out what I am doing wrong here.
As a workaround you could initialize the series and then remove the points before adding your own points.
Initialization:
series: [{
type: 'line',
name: 'OHLC',
data: [0], //added this 0
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: [0], //added this 0
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
Then, remove the points before adding new ones:
events: {
load: function () {
// set up the updating of the chart each second
var chart = this
var series = this.series[0];
var series1 = this.series[1];
//Remove 0 data
series.setData([], false); //false to avoid redrawing, so we only redraw once per update
series1.setData([], false);
//update graph
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], false, false);
series1.addPoint([x, y], false, false);
//redraw graph
chart.redraw();
}, 500);
}
}
Working example: https://jsfiddle.net/ewolden/xu058sgp/46/
I wanted to display two labels on bars. I am able to display one label right now. I want something like this.
Instead I am getting like this
The code snippet which I am using to show the labels is
plotOptions: {
column: {
dataLabels: {
enabled: true,
color: "black",
style: {
textOutline: false
}
}
}
}
how Can I show these percentage value on the bars? Thanks in Advance.
For placing label with percentage inside the particular column you should give dataLabels inside that series, for rest of the column use common dataLabels as defined by you in plotOptions. Below code is for idea only Fiddle link
var data = [7, 12, 16, 32];
var dataSum = 0;
for (var i = 0; i < data.length; i++) {
dataSum += data[i]
}
var data2 = [5, 19, 14, 13];
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: ''
},
xAxis: {
type: 'category',
},
yAxis: {
min: 0,
},
legend: {
enabled: false
},
plotOptions: {
column: {
dataLabels: {
enabled: true,
color: "black",
style: {
textOutline: false
}
}
}
},
series: [{
name: 'first',
data: data,
dataLabels: {
y: 20, /*for placeing lables values inside column*/
enabled: true,
formatter: function() {
var pcnt = (this.y / dataSum) * 100;
return Highcharts.numberFormat(this.y , 0) +'<br>'+Highcharts.numberFormat(pcnt) + '%';
}
}
}, {
name: 'Second',
data: data2,
}]
});
I'm using one the official highstock chart demo to create something similar with 2 charts stacked on top of each other. The problem is that the bottom chart (volume) is not displayed jsfiddle
A brief explanation of aapl-ohlc.json file will be helpful.
...
const data = JSON.parse(document.getElementById('ohlc-data').innerHTML);
// split the data set into ohlc and volume
const ohlc = data.map((a) => [a[0], a[1], a[2], a[3], a[4]])
const volume = data.map((a) => [a[0], a[5]])
// set the allowed units for data grouping
const groupingUnits = [
[
'week', // unit name
[1] // allowed multiples
],
[
'month', [1, 2, 3, 4, 6]
]
]
// create the chart
Highcharts.stockChart('container', {
legend: {
enabled: false
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
scrollbar: {
enabled: false
},
rangeSelector: {
selected: 4,
inputEnabled: false
},
title: {
text: ''
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: ''
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: ''
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
tooltip: {
split: true
},
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}],
navigator: {
enabled: false
}
});
This line:
const volume = data.map((a) => [a[0], a[5]])
Points to an element that doesn't exist. a[5] is not defined (there are only five elements to each sub array, no sixth element), therefore you have no y values in your data, and therefore no data series to display.
I don't know what data element is supposed to represent volume, but for reference, just to show that it does work, here is an updated fiddle using
const volume = data.map((a) => [a[0], a[1]])
https://jsfiddle.net/jlbriggs/0t9rq1f7/1/
EDIT:
Note that in the demo example that you based your fiddle on, the file that they use is aapl-ohlcv.json, not aapl-ohlc.json, which does in fact have a 6th data element in each sub array.
https://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json
https://github.com/highcharts/highcharts/blob/master/samples/data/aapl-ohlcv.json