Related
I am attempting to create the following chart:
However I can't seem to get the plotbands to work in this way; right now, they fill the entire axis:
I am not sure if I should use annotations instead, but so far I haven't gotten it to work. What can I try next?
Highcharts.chart('container',{
credits: {
enabled: false
},
title: {
text: "hello world",
style: {
visibility: 'hidden'
}
},
chart: {
type: 'line',
width: 400,
},
legend: {
enabled: false
},
exporting: {
enabled: true,
allowHTML:true,
chartOptions: {
chart: {
marginLeft: 175,
marginRight: 175
},
plotOptions: {
line: {
dataLabels: {
style: {
fontSize: 14
},
verticalAlign: "top",
useHTML: true
}
}
}
}
},
yAxis: {
startOnTick: false,
endOnTick: false,
gridLineWidth: 2,
tickWidth: 2,
tickLength: 20,
plotBands: [{
color: 'rgba(231, 23, 60, 0.5)', // Color value
from: 5, // Start of the plot band
to: 6.2 // End of the plot band
},
{
color: 'rgba(53, 101, 237, 0.5)', // Color value
from: 1, // Start of the plot band
to: 3 // End of the plot band
}
],
title: {
align: 'high',
offset: -40,
text: 'mmol/L',
style: {
fontWeight: "bold",
fontSize: 15
},
rotation: 0,
y: -20
},
min: 0,
max: 7,
labels: {
x: -10,
y: -3,
formatter: function () {
if (this.value != 0) {
if (this.value < 8) {
return this.value;
}
}
},
style: {
fontWeight: "400",
lineHight: "20",
padding: "0",
fontSize: "13"
}
}
},
annotations: [{
shapes: [{
point: '0',
type: 'circle',
r: 10
}, {
point: '3',
type: 'rect',
width: 20,
height: 20,
x: -10,
y: -25
}, {
fill: 'none',
stroke: 'red',
strokeWidth: 3,
type: 'path',
points: ['0', '1', {
x: 6,
y: 195,
xAxis: 0,
yAxis: 0
}],
markerEnd: 'arrow'
}],
labels: [{
point: {
x: 6,
y: 195,
xAxis: 0,
yAxis: 0
}
}]
}],
xAxis: {
gridLineColor: 'transparent',
accessibility: {
rangeDescription: 'Range: 2010 to 2020'
},
categories: [2018, 2019]
},
plotOptions: {
line: {
dataLabels: {
style: {
fontSize: 14
},
verticalAlign: "top",
useHTML: true,
format: '<div style="max-width: 10ch; text-align: center;">{y}<br/>mmol/L</div>'
}
}
},
series: [{
name: '',
color: "black",
data: [5.4, 3],
showInLegend: false,
dataLabels: {
enabled: true,
useHTML: true,
}
}],
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/annotations.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<figure class="highcharts-figure">
<div id="container"></div>
</figure>
This kind of plotBand shape is not possible from the API level, but you can simulate it in several ways. Example configurations:
SVG Renderer:
chart: {
events: {
render() {
const chart = this;
if (chart.rects) {
chart.rects = chart.rects.destroy();
}
chart.rects = chart.renderer.g('rects').attr({
zIndex: 1
}).add();
let x = chart.xAxis[0].toPixels(1),
y = chart.yAxis[0].toPixels(4),
width = chart.xAxis[0].toPixels(2) - chart.xAxis[0].toPixels(1),
height = chart.yAxis[0].toPixels(2) - chart.yAxis[0].toPixels(4);
chart.rect = chart.renderer.rect(x, y, width, height)
.attr({
fill: 'grey'
}).add(chart.rects)
chart.rect = chart.renderer.rect(chart.xAxis[0].toPixels(3), y, width, height)
.attr({
fill: 'grey'
}).add(chart.rects)
}
}
},
Demo:
https://jsfiddle.net/BlackLabel/wst607ub/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer
Annotations:
annotations: [{
draggable: false,
shapes: [{
points: [{
x: 1,
y: 2,
xAxis: 0, // xAxis reference used, use xAxis value
yAxis: 0 // yAxis reference used, use xAxis value
}, {
x: 2,
y: 2,
xAxis: 0,
yAxis: 0
}, {
x: 2,
y: 4,
xAxis: 0,
yAxis: 0
}, {
x: 1,
y: 4,
xAxis: 0,
yAxis: 0
}],
type: 'path'
}]
}]
Demo:
https://jsfiddle.net/BlackLabel/uvxzp6o7/
API Reference:
https://api.highcharts.com/highcharts/annotations
Polygon series:
series: [{
name: 'Polygons',
type: 'polygon',
color: 'grey',
showInLegend: false,
enableMouseTracking: false,
states: {
inactive: {
opacity: 1,
},
},
data: [
[1, 2],
[2, 2],
[2, 4],
[1, 4],
null, // allows multiple polygons
[3, 2],
[4, 2],
[4, 4],
[3, 4],
]
}]
Demo:
https://jsfiddle.net/BlackLabel/4n7ep3k2/
API Reference:
https://api.highcharts.com/highcharts/series.polygon
Take note that annotations and polygon series require the module to be included.
I have an Echarts (v4.8.0) cartesian2d heatmap and I'd like to use a different continuous visualmap range [min,max] for each row (which I could filter by the second parameter value 'y' of each data). Is there a way to do it? I can only think in using different series, one for each row, but I don't know how to join them into a single chart.
Here is my option configs:
{
tooltip: {
position: 'left',
},
grid: {
left: '7%',
right: '3%',
},
animation: false,
xAxis: {
type: 'category',
data: ['04-10-2020', '05-10-2020'],
splitArea: {
show: false
},
position: 'top'
},
yAxis: {
type: 'category',
data: ['A', 'B'],
splitLine: {
show: true,
lineStyle: {
width: 2
}
}
},
visualMap: {
type: 'continuous',
show: false,
min: [0, 0],
max: [12, 15], //here I tried to have multiples ranged, but It crashes
inRange: {
color: ['#ffffff', '#990000']
},
dimension: '2',
},
series: {
name: "test",
type: 'heatmap',
data: [[0, 0, 2], [0, 1, 5], [1, 0, 9], [1, 1, 12]],
label: {
show: false
},
coordinateSystem: 'cartesian2d',
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
Thank you very much in advanced
The visual map it is component that can be used a several times just like axes, tooltip and so on. Have you tried to make clone visual map with other params?
var option = {
tooltip: {
position: 'left',
},
grid: {
left: '7%',
right: '3%',
},
animation: false,
xAxis: {
type: 'category',
data: ['04-10-2020', '05-10-2020'],
splitArea: {
show: false
},
position: 'top'
},
yAxis: {
type: 'category',
data: ['A', 'B'],
splitLine: {
show: true,
lineStyle: {
width: 2
}
}
},
visualMap: [{
type: 'continuous',
show: false,
min: 0,
max: 7,
inRange: {
color: ['#ffffff', '#990000']
},
dimension: '2',
}, {
type: 'continuous',
show: false,
min: 7,
max: 15,
inRange: {
color: ['#AC33FF', '#FF7C00']
},
dimension: '2',
}
],
series: {
name: "test",
type: 'heatmap',
data: [
[0, 0, 2],
[0, 1, 5],
[1, 0, 9],
[1, 1, 12]
],
label: {
show: false
},
coordinateSystem: 'cartesian2d',
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
}
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>
Thanks to the answer of Sergey Federov I managed to do it by using multiple heatmap series with their corresponding visualmaps, using seriesIndex to link them. Here is an example where each row has 3 items with the same values, the first row (from bottom to top) has a visualMap range of [0, 15], while the second [5, 15]. The data is splitted into two series according to their second cartesian coordinate. For more rows, just split the data into more series and add their corresponding visualMaps.
var option = {
tooltip: {
position: 'left',
},
animation: false,
xAxis: {
type: 'category',
data: ['04-10-2020', '05-10-2020', '06-10-2020'],
splitArea: {
show: false
},
position: 'top'
},
yAxis: {
type: 'category',
data: ['A', 'B'],
splitLine: {
show: true,
lineStyle: {
width: 2
}
}
},
visualMap: [{
type: 'continuous',
show: false,
min: 0,
max: 15,
seriesIndex : 0,
inRange: {
color: ['#ffffff', '#990000']
},
dimension: '2',
}, {
type: 'continuous',
show: false,
min: 5,
max: 15,
seriesIndex: 1,
inRange: {
color: ['#ffffff', '#990000']
},
dimension: '2',
}
],
series: [{
name: "test1",
type: 'heatmap',
data: [
[0, 0, 5],
[1, 0, 10],
[2, 0, 15]
],
label: {
show: false
},
coordinateSystem: 'cartesian2d',
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
{
name: "test2",
type: 'heatmap',
data: [
[0, 1, 5],
[1, 1, 10],
[2, 1, 15]
],
label: {
show: false
},
coordinateSystem: 'cartesian2d',
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>
I am using Highcharts latest version and trying to export a chart on a png and trying to see if there is a way to limit the number of rows shown on the exported png using the horizontal layout up to 2 rows if the legends are breaking into more than 2 rows.
A working export example is here: https://jsfiddle.net/siluok3/085gzjtn/7/
Highcharts.chart('container', {
chart: {
style: {
fontFamily: '"Arial", sans-serif',
color: '#7b797a',
'z-index': 'inherit'
},
resetZoomButton: {
theme: {
fill: '#5cb85c',
stroke: '#4cae4c',
style: {
color: '#fff',
fontSize: '15px'
},
r: 3,
states: {
hover: {
fill: '#449d44',
stroke: '#398439'
}
}
}
}
},
title: {
text: 'Data labels only visible on export'
},
credits: {
enabled: false,
style: {
display: "none"
}
},
legend: {
useHTML: true,
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
y: 32,
itemStyle: {
color: '#7b797a',
fontWeight: "normal"
},
itemHoverStyle: {
color: '#7b797a'
}
},
navigation: {
buttonOptions: {
theme: {
'stroke-width': 0,
r: 0,
fill: null,
states: {
hover: {
fill: null
},
select: {
stroke: null,
fill: null
}
}
}
},
menuItemHoverStyle: {
background: '#008add'
}
},
xAxis: {
labels: {
rotation: 270
},
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Mayfsdfdsfdsf', 'Junfdfsd', 'Julfsdfsdfds', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [6, 4, 2],
name: 'Firfdsfdsst'
}, {
data: [7, 3, 2],
name: 'Secfsdfdsdfond'
}, {
data: [9, 4, 8],
name: 'Third'
}, {
data: [1, 2, 6],
name: 'Fourth'
}, {
data: [4, 6, 4],
name: 'Fifdsfdsfdsfdsfsdfth'
}, {
data: [1, 2, 7],
name: 'Sixth'
}, {
data: [4, 2, 5],
name: 'Sevefdsfdsfdsfsdnth'
}, {
data: [8, 3, 2],
name: 'Efdsfdsfdsfdsighth'
}, {
data: [4, 5, 6],
name: 'Nifdsfdsfdsfdsfdsfnth'
}, {
data: [4, 2, 5],
name: 'Sevefdsfdsfdsfsdnth'
}, {
data: [8, 3, 2],
name: 'Efdsfdsfdsfdsighth'
}, {
data: [4, 5, 6],
name: 'Nifdsfdsfdsfdsfdsfnth'
}],
exporting: {
chartOptions: {
legend: {
title: {
text: '',
},
itemHiddenStyle: {
display: 'none',
},
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
itemDistance: 10,
y: 0,
itemMarginTop: 5,
itemStyle: {
fontSize: '10px',
},
symbolPadding: 2,
alignColumns: false,
},
rangeSelector: {
enabled: false
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
}
}
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
As you can see the legends break into a 3rd row if they are more or larger. Is there an intuitive way to find a workaround?
You can use itemWidth property to limit the width of the item and, as a result, the number of rows. Unfortunately for now there is no built-in solution for dynamically adjusting the number of rows in the legend.
exporting: {
chartOptions: {
legend: {
itemWidth: 90,
...
},
...
}
}
Live demo: https://jsfiddle.net/BlackLabel/gtjewc1v/
API Reference: https://api.highcharts.com/highcharts/legend.itemWidth
Thanks to this helpful post, I was able to re-format the legend so that clicking a legend item shows only that item, rather than hiding it and showing all other items.
Once the user clicks on a legend item, I'd like for the user to be able to click a button and once again see all of the legend items.
Here's the fiddle: http://jsfiddle.net/scheltense/qb13g51u/1/
And the code:
$(function () {
$('#container').highcharts({
credits: {
position: {
align: 'right',
x: -10,
y: -1
},
text: 'Source: Federal Emergency Management Agency',
href: 'http://www.FEMA.gov'
},
chart: {
type: 'area'
},
title: {
text: 'Federal Disaster Declarations: 2001-2013',
align: 'left',
x: 25,
y: 5
},
subtitle: {
text: 'The Federal Emergency Management Agency (FEMA) uses these categories to classify federal disasters delcarations.',
align: 'left',
x: 25,
y: 30
},
legend: {
backgroundColor: '#F5F3F2',
layout: 'vertical',
symbolHeight: 8,
symbolWidth: 10,
align: 'left',
verticalAlign: 'top',
floating: true,
x: 62,
y: 72,
padding: 3,
itemMarginTop: 3,
itemMarginBottom: 3,
itemStyle: {
lineHeight: '8px',
color: '#000000',
fontWeight: 'normal'
},
reversed: true
},
xAxis: {
categories: ['2001', '\'02', '\'03', '\'04', '\'05', '\'06', '\'07', '\'08', '\'09', '\'10', '\'11', '\'12', '\'13', '\'14*'],
tickmarkPlacement: 'on',
title: {
enabled: true
}
},
yAxis: {
title: {
text: 'Declarations'
},
max: 100,
labels: {
formatter: function () {
return this.value;
}
}
},
tooltip: {
shared: false,
valueSuffix: ''
},
plotOptions: {
area: {
events:
{
legendItemClick: function(event)
{
var seriesIndex = this.index;
var series = this.chart.series;
for (var i = 0; i < series.length; i++)
{
if (series[i].index != seriesIndex)
{
series[i].hide();
}
else
{
series[i].show();
}
}
return false;
}
},
stacking: 'normal',
lineColor: '#E5E2E0',
lineWidth: 0,
marker: {
enabled: false
}
}
},
series: [{
name: 'Other',
color: '#9fcad3',
data: [6, 5, 2, 3, 0, 4, 1, 1, 1, 1, 8, 4, 6, 0],
marker: {
symbol: 'circle'
}
}, {
name: 'Hurricane',
color: '#bb6b85',
data: [0, 4, 8, 14, 11, 0, 0, 8, 1, 1, 14, 15, 2, 0],
marker: {
symbol: 'circle'
}
}, {
name: 'Severe Winter Weather',
color: '#bba16b',
data: [4, 5, 6, 1, 2, 1, 5, 5, 5, 12, 5, 0, 3, 11],
marker: {
symbol: 'circle'
}
}, {
name: 'Flood',
color: '#6b85bb',
data: [5, 4, 0, 1, 2, 2, 1, 3, 3, 7, 19, 3, 15, 2],
marker: {
symbol: 'circle'
}
}, {
name: 'Severe Storm and Tornado',
color: '#6bbba1',
data: [27, 25, 35, 42, 30, 45, 56, 56, 48, 55, 50, 25, 36, 15],
marker: {
symbol: 'circle'
}
}]
}, function (chart) {
var point = chart.series[0].data[8],
text = chart.renderer.text(
'*through Aug. 5, 2014',
point.plotX + chart.plotLeft - 280,
point.plotY + chart.plotTop + 316
).attr({
zIndex: 5
})
.css({
color: '#909090',
fontSize: '10px'
})
.add(),
box = text.getBBox();
});
});
This is the portion of the code that shows only the legend item that has been clicked:
plotOptions: {
area: {
events:
{
legendItemClick: function(event)
{
var seriesIndex = this.index;
var series = this.chart.series;
for (var i = 0; i < series.length; i++)
{
if (series[i].index != seriesIndex)
{
series[i].hide();
}
else
{
series[i].show();
}
}
return false;
}
},
This is my first JavaScript project, so I apologize if the question is unclear, and I appreciate any help that can be provided.
Thanks very much.
The series object has a show() function (http://api.highcharts.com/highcharts#Series.show).
Assuming your button has an id of showall:
$('#showall').on('click', function() {
var series = $('#container').highcharts().series;
for(i=0;i<series.length;i++) {
if (!series[i].visible) series[i].show();
}
});
http://jsfiddle.net/qb13g51u/2/
I am trying to customize highcharts
1) I need to change the height of the plotlines
2) Show the marker value inside the marker image itself at a specific place(Inside the white circles at the top)
This is what I have achieved so far
Highcharts.setOptions({
global: {
useUTC: false
}
});
/*function updateData(x,y)
{
var series = chart.series[0];
series.addPoint([x, y], true, true);
}*/
var chart;
$(function () {
var color = '#AA34FF';
$('#container').highcharts({
chart: {
events: {
load: function(event) {
_bindCustomEvents();
}
},
backgroundColor: 'transparent'
},
series: [
{
color:
{
linearGradient:
{
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops:
[
/*[0, '#a83e3e'],
[0.21, '#d34e47'],
[0.40, '#edbb5a'],
[0.57, '#e2e57a'],
[0.76, '#8dcc63'],
[1, '#7ab237']*/
[0, '#7ab237'],
[0.21, '#8dcc63'],
[0.40, '#e2e57a'],
[0.57, '#edbb5a'],
[0.76, '#d34e47'],
[1, '#a83e3e']
]
},
lineWidth: 4,
marker: {
enabled: false,
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null,
},
type: 'spline',
data: [1, 2, 5, 3, 6, 7, 4],
backgroundColor: 'transparent',
plotShadow : false
},
{
name: '',
marker: {
symbol: 'diamond'
},
//same inmage for all points
marker: {
symbol: 'url(http://fc08.deviantart.net/fs71/f/2014/016/b/9/top_marker_by_skyrbe-d72ewk0.png)'
},
data: [8,8,8,8,8,8,8],
type:'scatter'
},
{
name: '',
marker: {
symbol: 'diamond'
},
//same inmage for all points
marker: {
symbol: 'url(http://fc03.deviantart.net/fs71/f/2014/016/f/a/bottom_marker_by_skyrbe-d72ew7w.png)'
},
data: [-1,-1,-1,-1,-1,-1,-1],
type:'scatter'
}
],
xAxis: {
categories: [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
],
title: {
enabled: true,
text: null,
},
labels: {
style: {
fontFamily: 'gestaregular',
fontSize: '16px',
color:'#fff'
}
},
plotLines: [
{ // mark the weekend
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 0,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 1,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 2,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 3,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 4,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 5,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 6,
dashStyle: 'dash',
zIndex:10
}],
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
},
yAxis: {
labels: {
enabled: false
},
title: {
enabled: true,
text: null,
}
},
legend: {
enabled: false
},
minorTickLength: 0,
tickLength: 0
});
});
function _bindCustomEvents()
{
var chart = $('#container').highcharts();
chart.setTitle({ text: ''});
$('.highcharts-axis').hide();
$('.highcharts-grid').hide();
$('.highcharts-axis').find('path').hide();
}
FIDDLE LINK
This is how I want it to look like : Instead of '2' in the top circles , it should be the corresponding value from the center spline [1, 2, 5, 3, 6, 7, 4]
1) The plotLines are infinite. The extend as far as the plot area is. So, to limit this, how about you change your yAxis max:
yAxis: {
max: 8,
labels: {
enabled: false
},
title: {
enabled: true,
text: null
}
},
Or, you could create a column series on the points you want and give them a certain value for the height you want. Making the columns thin to mimic your plotLines will help like so:
series: [{
name: '',
type: 'column',
pointWidth: 1,
borderWidth: 0,
data: [8, 8, 8, 8, 8, 8, 8]
},
...
2) Which values in the circles (I am guessing)? The "Series 1: XX"? Or the whole tooltip?
EDIT:
For question 2 you can do this with a formatter function on the dataLabel for the scatter series (your circles). Here is the function:
var customFormatPoint = function (pointX, seriesIndex) {
var theChart = $('#container').highcharts();
var yValue = null;
var points = theChart.series[seriesIndex].options.data[pointX];
return points;
};
You call this from:
series: [{
name: '',
type: 'column',
pointWidth: 1,
borderWidth: 0,
dataLabels: {
enabled: true,
formatter: function () {
return customFormatPoint(this.point.x, 1);
}
},
data: [7.70, 7.70, 7.70, 7.70, 7.70, 7.70, 7.70]
}, {...
Key element here is that you have this.point.x which is that scatter point's xAxis location. You then need to send in which index the series is that contains the y value you want to show in the dataLabel.
I have also removed the plotLines and created a series that just contains the bars with width of 1 and no border. I had to mess around to get the end of the bar (its max value) to coincide with the scatter circle diameter.
Please see this jsFiddle.