I'm trying to make some visualisations using the HighCharts javascript library, mainly I'm hoping to make something very similar to what these guys have on their page:
Research Affiliates - 10Yr Expected Risk & Return
Mainly, I'm trying to work out how they managed to get the 2 solid linear areas on the scatter graph that represent the different Sharpe Ratio levels. Is it just a background image, or have they somehow underlayed an area chart under the scatter chart?
Has anybody got any experience with this, or how to code it?
On the web page you are referring to area type series are used to generate triangular shapes in the background.
Area chart demo: http://www.highcharts.com/demo/area-basic
Area chart API reference: http://api.highcharts.com/highcharts#plotOptions.area
Basically, you can combine any kind of chart type.
See their demo of a scatter plot with a regression line.
As an example of a scatter plot combined with a stacked area chart, see the following code and fiddle:
var Y_MAX = 6;
var X_MAX = 5;
$(function () {
$('#container').highcharts({
title: {
text: 'Scatter plot with stacked area ratio chart'
},
plotOptions: {
area: {
stacking: 'normal'
}
},
xAxis: {
min: 0,
max: X_MAX
},
yAxis: {
min: 0,
max: Y_MAX
},
series: [{
type: 'area',
name: 'Ratio',
data: [{x: 0, y: 0}, {x: X_MAX, y: 0.4*Y_MAX}]
}, {
type: 'area',
name: 'Ratio',
data: [{x: 0, y: 0}, {x: X_MAX, y: 0.6*Y_MAX}]
}, {
type: 'scatter',
name: 'Observations',
data: [1, 0.5, 3.8, 5.5, 3.9, 2.2],
marker: {
radius: 8
}
}]
});
});
Fiddle
Thanks for the heads up on how to combine two charts.
What I actually ended up using was the Polygon Plot type rather than an Area Chart.
I also rendered the labels using Chart.renderer.label.
Still tweaking this, but as a whole reference this is my code (minus data taken out)
$(function () {
$('#scatter-plot').highcharts({
chart: {
type: 'scatter',
zoomType: 'xy'
},
title: {
text: 'Expected Asset Return Against Volatility'
},
legend: {
enabled: false
},
xAxis: {
title: {
text: 'Volatility',
enabled: true,
style: {
fontWeight: 'bold',
fontSize: '18px',
fontFamily: 'PT Sans',
}
},
min: 0,
lineWidth: 0,
lineColor: '#bfbfbf',
gridLineWidth: 0,
tickWidth: 0,
labels: {
format: '{value} %',
style: {
fontSize: '14px',
fontFamily: 'Arial',
}
}
},
yAxis: {
title: {
text: 'Real Expected Returns',
style: {
fontWeight: 'bold',
fontSize: '18px',
fontFamily: 'PT Sans',
},
enabled: true
},
gridLineWidth: 0,
lineWidth: 1,
endOnTick: true,
maxPadding: 0,
startOnTick: true,
minPadding: 0,
lineColor: '#bfbfbf',
minRange: 2,
plotLines: [{
color: '#bfbfbf',
width: 1,
value: 0,
zIndex: 5
}],
labels: {
format: '{value} %',
style: {
fontSize: '14px',
fontFamily: 'Arial',
}
}
},
series: [
{
type: 'polygon',
color: 'rgba(100,100,100, 0.1)',
data: [[0, 0], [20, 10], [20, 0]]
},
{
type: 'polygon',
color: 'rgba(100,100,100, 0.1)',
data: [[0, 0], [20, 20], [20, 0]]
},
{type: 'scatter',
marker: {
radius: 10,
symbol: 'circle',
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
dataLabels: {
enabled: true,
x: -8,
y: -8,
fontFamily: 'PT Sans',
color: 'rgba(50, 50, 50, 0.8)',
format: '{series.name}'
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: 'Volatility: {point.x}%<br>Exp. Return: {point.y}%'
},name: 'United-States',color: 'rgba(215, 40, 40, 0.6)',data: [[15.8,5.9]]},
//Rest of the data here, repeating in the same format as above^^
},
function (chart) { // on complete
chart.renderer.label('<div style="font-size:18px;">0.1 Sharpe Ratio</div>',
$(chart.container).width() - 200,
$(chart.container).height() - 150,
true)
.css({
color: 'rgba(0,0,0,0.5)'
})
.add();
chart.renderer.label('<div style="font-size:18px;">0.2 Sharpe Ratio</div>',
$(chart.container).width() - 200,
$(chart.container).height() - 250,
true)
.css({
color: 'rgba(0,0,0,0.5)'
})
.add();
});
});
And it produced this result:
Thanks again for the tips!
Related
this is my polar area chart. - https://ibb.co/H7gJ5DH.
i want to change above polar area chart to look like this - https://ibb.co/ScNwXFB.
jsfiddle - https://jsfiddle.net/isurumahesh/2n3jh8xs/48/
could you please help me to show the legend values inside the polar area chart ?
You can use only one series, disable legend and add another x-axis with the below options:
xAxis: [{
type: 'category',
uniqueNames: false,
gridLineColor: 'black',
gridZIndex: 5,
lineWidth: 3,
labels: {
staggerLines: 2,
allowOverlap: true,
distance: 15,
align: 'center',
style: {
fontSize: '9px',
width: '70px'
}
}
}, {
categories: mainCategories,
min: -0.5,
max: 3.5,
offset: -30,
lineWidth: 0,
gridLineColor: 'black',
gridLineWidth: 3,
gridZIndex: 5,
showLastLabel: true,
labels: {
allowOverlap: true,
align: 'center',
staggerLines: 0,
style: {
fontSize: '14px'
}
}
}],
pane: {
size: '75%'
},
yAxis: {
tickInterval: 1,
gridZIndex: 5,
gridLineWidth: 1,
gridLineColor: 'black',
labels: {
enabled: false
}
},
legend: {
enabled: false
}
Live demo: https://jsfiddle.net/BlackLabel/za1mq3gc/
API Reference: https://api.highcharts.com/highcharts/xAxis
I want to achieve something like this.
this is what I have so far:
Highcharts.chart('container', {
chart: {
type: 'pie'
},
title: {
text: 'Browser market share, January, 2018'
},
subtitle: {
text: `<div>80%</div> of Total`,
align: "center",
verticalAlign: "middle",
style: {
"fontSize": "7px",
"textAlign": "center"
},
x: 0,
y: -2,
useHTML: true
},
plotOptions: {
pie: {
shadow: false,
center: ["50%", "50%"],
dataLabels: {
enabled: false
},
states: {
hover: {
enabled: false
}
},
size: "45%",
innerSize: "95%",
borderColor: null,
borderWidth: 8
}
},
tooltip: {
valueSuffix: '%'
},
series: [{
y: 80,
color: {
linearGradient: {
x1: 0,
x2: 0,
y1: 0,
y2: 1
},
stops: [
[0, "#000"],
[1, "#b0bfc6"]
]
},
name: "Speed"
},
{
y: 20,
color: "#000",
name: "Non Prioritised"
}],
});
here is the fiddle:
https://jsfiddle.net/gm8krq9L/
however I'm not able to get the different colors to show the progress effect on the chart. I see that there is a type called: chart: solidgauge, however my app does not support as I'll have to include the solidgauge file to load this kind of chart. Is there a way I can achieve this with chart type as pie?
thanks
What you want is called a donut chart. I already made an example for a such chart, is it something like this example you want?
Anyway, here's a working example with your fiddle.
The data is like the one you used:
series: [{
innerSize: '80%',
data: [{
name: 'Speed',
y: 80,
color: '#e7eaeb'
}, {
name: 'Non Prioritised',
y: 20,
}]
}],
Yes, you can create that type of chart by using pie series type, for example:
series: [{
type: 'pie',
enableMouseTracking: false,
innerSize: '80%',
dataLabels: {
enabled: false
},
data: [{
y: 10
}, {
y: 90,
color: '#e3e3e3'
}]
}]
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4791/
API Refernece: https://api.highcharts.com/highcharts/series.pie.innerSize
I want to get a gauge like this with the black marker for setting threshold value and inner "blue" data as load.
I have used Highcharts (of which I don't have much knowledge) in my code to obtain the required gauge as close as possible, however what I am getting is something like below which is just load without "marker":
with the code as below:
var gaugeOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || '#EEE',
innerRadius: '80%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.6, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
var chartSpeed = Highcharts.chart('container-speed', Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 100
},
credits: {
enabled: false
},
series: [{
name: 'Load',
data: [{
radius: '100%',
innerRadius: '80%',
y: Number($scope.user.threshold)
}],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:25px;color:' +
('black') + '">{y}</span><br/>' +
'<span style="font-size:12px;color:silver">%</span></div>'
},
tooltip: {
valueSuffix: ' %'
}
}]
}));
Any idea about how can I get the first gauge? Also it should be able to tell when the load crosses the threshold value.
EDIT (Solved):
yAxis: {
plotBands: [{
from: 60,
to: 61,
color: 'black',
thickness: '45%',
outerRadius: '105%',
zIndex: 5
}], .... }
Added this to my code which made it work.
You can achieve this by using plot bands:
yAxis: {
plotBands: {
from: 70,
to: 71,
color: '#DF5353',
thickness: '40%'
},
...
}
Where thickness is the length of the radius on your marker (easier to understand by looking at the graph).
There is a lot of configuration options here, it should be possible to figure out by looking at the API.
Working example: http://jsfiddle.net/ewolden/6rL9u37d/2/
API on yAxis.plotBands: https://api.highcharts.com/highcharts/yAxis.plotBands
I am very new to Highcharts. I am trying to use the solid gauge. The problem is that the percentage text is not present in the center. Is there anyway to put the percentage in the center of the chart?
Here is the code:
$(function () {
Highcharts.chart('container', {
chart: {
type: 'solidgauge'
},
title: {
text: ''
},
tooltip: {
borderWidth: 0,
backgroundColor: 'none',
shadow: false,
style: {
fontSize: '16px'
},
pointFormat: '{series.name}<br><span style="font-size:2em; color: {point.color}; font-weight: bold">{point.y}%</span>',
positioner: function (labelWidth, labelHeight) {
return {
x: 200 - labelWidth / 2,
y: 180
};
}
},
pane: {
center: ['50%', '27%'],
startAngle: 0,
endAngle: 360,
background: [{ // Track for Stand
outerRadius: '62%',
innerRadius: '38%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[2]).setOpacity(0.3).get(),
borderWidth: 0,
}],
},
yAxis: {
min: 0,
max: 100,
lineWidth: 0,
tickPositions: []
},
plotOptions: {
solidgauge: {
borderWidth: '34px',
dataLabels: {
enabled: false
},
linecap: 'round',
stickyTracking: false
}
},
series: [{
name: 'Stand',
borderColor: Highcharts.getOptions().colors[2],
data: [{
color: Highcharts.getOptions().colors[2],
radius: '50%',
innerRadius: '50%',
y: 50
}]
}]
},
});
The x and y in the label option can set the position but I want it to be dynamic.
Secondly I want it to be always shown. Here is the result of the code above.
I am using Highcharts with Area graph.
How can I customize xAxis label as hourly basis with suffix as 1st, 2nd, 3rd etc...?
Online Demo
Current format:
01th hour, 02th hour, 03th hour ....
This has to be changed as below:
1st hour, 2nd hour, 3rd hour....
I have tried to convert as above by using ordinal method, but not working though...
May be placing the ordinal script is wrong?
var s=["th","st","nd","rd"],
v=n%100;
return n+(s[(v-20)%10]||s[v]||s[0]);
Full Code:
$(function (n) {
// Everything in common between the charts
var commonOptions = {
colors: ['#fe5758', '#99cc03', '#33b5e6', '#fd8f40', '#e7ca60', '#40abaf', '#f6f7f8', '#e9e9eb'],
chart: {
style: {
fontFamily: 'Roboto Light',
fontWeight: 'normal',
fontSize: '12px',
color: '#585858',
}
},
title: {
text: null
},
subtitle: {
text: null
},
credits: {
enabled: false
},
exporting: {
enabled: false
},
xAxis: {
title: {
style: {
fontFamily: 'Roboto',
color: "#000",
}
},
labels: {
style:{ color: '#000' }
},
lineColor: '#e4e4e4',
lineWidth: 1,
tickLength: 0,
},
yAxis: {
title: {
style: {
fontFamily: 'Roboto',
color: "#000",
}
},
offset:-6,
labels: {
style:{ color: '#bbb' }
},
tickInterval: 100,
lineColor: '#e4e4e4',
lineWidth: 1,
gridLineDashStyle: 'dash',
},
series: [{
backgroundColor: "rgba(0 ,0, 0, 0.5)",
}],
// Area Chart
plotOptions: {
area: {
stacking: 'normal',
lineWidth: 1,
fillOpacity: 0.1,
marker: {
lineWidth: 1.5,
symbol: 'circle',
fillColor: 'white',
},
legend: {
radius: 2,
}
}
},
tooltip: {
useHTML: true,
shared: true,
backgroundColor: '#5f5f5f',
borderWidth: 0,
style: {
padding:10,
color: '#fefefe',
}
},
legend: {
itemStyle: {
fontFamily: 'Roboto Light',
fontWeight: 'normal',
fontSize: '12',
color: '#666666',
},
marker: {
symbol: 'square',
verticalAlign: 'middle',
radius: '4',
},
symbolHeight: 6,
symbolWidth: 6,
},
};
$('#areaChartTwoWay-time').highcharts(Highcharts.merge(commonOptions, {
chart: { type: 'area' },
xAxis: {
title: { text: 'Hours', },
type: 'datetime',
min:Date.UTC(2016,04,16,1,0,0,0),
minRange: 12 * 3600 * 500,
dateTimeLabelFormats: {
hour: '%Hth hour',
},
},
yAxis: {
tickInterval: 30,
title: { text: 'Total views', },
offset:0,
},
series: [{
name: 'Unique open',
lineColor: '#fb8b4b',
marker: { lineColor: '#fb8b4b', fillColor: 'white', },
data: [88, 68, 79, 39, 48, 69, 69, 18, 40, 62, 91, 61, 39],
legendIndex:1,
pointInterval: 3600 * 500,
pointStart:Date.UTC(2016,04,16,1,0,0,0),
}, {
name: 'Forwards',
lineColor: '#99cc03',
marker: { lineColor: '#99cc03', fillColor: 'white', },
data: [3, 8, 15, 12, 61, 32, 43, 18, 9, 12, 22, 18, 12],
legendIndex:0,
pointInterval: 3600 * 500,
pointStart:Date.UTC(2016,04,16,1,0,0,0),
}]
}));
var s=["th","st","nd","rd"],
v=n%100;
return n+(s[(v-20)%10]||s[v]||s[0]);
$('.highcharts-grid > path:last-child').remove();
$('.highcharts-markers > path:last-child').remove();
});
You could call another function to get the ordinal. A quick google found this method:
function getGetOrdinal(n) {
var s=["th","st","nd","rd"],
v=n%100;
return n+(s[(v-20)%10]||s[v]||s[0]);
}
This takes a number and returns a string, which is made up of the number with he correct ordinal appended.
This won't work with dateTimeLabelFormats though. For your use, you could use a simple label formatter.
I've updated your online demo here also:
http://jsfiddle.net/6nz0sod1/2/
Hope this helps
Source: https://ecommerce.shopify.com/c/ecommerce-design/t/ordinal-number-in-javascript-1st-2nd-3rd-4th-29259