I have a chart like this example, and I want to merge vertically some of the first column's cells. in this example, I want to merge the 0, 1, 2 cells in the first column.
How is it possible?
Code of the example:
yAxis: {
type: 'category',
grid: {
borderColor: '#3a5d96',
columns: [{
title: {
text: 'Tasks',
rotation: 45,
y: -15,
x: -15
}
}, {
title: {
text: 'Assignee',
rotation: 45,
y: -15,
x: -15
},
labels: {
format: '{point.assignee}'
}
}, {
title: {
text: 'Duration',
rotation: 45,
y: -15,
x: -15
},
labels: {
formatter: function() {
var point = this.point,
days = (1000 * 60 * 60 * 24),
number = (point.end - point.start) / days;
return Math.round(number * 100) / 100;
}
}
}]
}
}
I am afraid that vertically merging options doesn't exist for the columns treegrid in the Highcharts Gantt, however you can hide those paths between the labels.
Demo: https://jsfiddle.net/BlackLabel/va1fqwd5/
chart: {
events: {
load() {
let chart = this,
ticks = chart.yAxis[0].treeGrid.axis.grid.columns[1].ticks;
ticks[0].mark.hide();
ticks[1].mark.hide();
ticks[2].mark.hide();
}
}
},
Related
Example Chart Image
I want to show tooltip for Approval Count as 0 on hovering anywhere in it's general vicinity, is that possible with highcharts?
You can render this particular column as a dummy point - full range & transparent color to show a tooltip for it.
Highcharts.chart('container', {
chart: {
type: 'bar'
},
yAxis: {
max: 10
},
tooltip: {
formatter(tooltip) {
if (this.point.isEmpty) {
return 'Null';
}
return tooltip.defaultFormatter.call(this, tooltip);
}
},
series: [{
data: [{
x: 0,
y: 2
}, {
x: 1,
y: 3
}, {
x: 2,
y: 10,
color: 'transparent',
isEmpty: true
}, {
x: 3,
y: 8
}, {
x: 4,
y: 2
}]
}]
});
Demo: https://jsfiddle.net/BlackLabel/ef8sj4no/
API: https://api.highcharts.com/highcharts/tooltip.formatter
We are developing some charts using Highcharts.
And we are using the series.events.afterAnimate in combination with an xAxis.max value.
But when we have for example points from Januari until September, but with an xAxis.max value until December the afterAnimate function is called when it reached December we guess..
But we would like have a callback when all the valid points are drawn, and not we it reaches its max value...
is this possible?
That happens because the clipPath width is by default equal width of the plot area. To change it you can overwrite Highcharts.Series.animate method and set clipPath width equal width of the particular series.
EDIT:
Also, note that when the width of the clipPath is shorter and the duration of the animation is the same the animation will be much slower. To make it look better the time has to be shortened - it can be calculated depending on series width and updated in chart load event.
Check demo and code posted below:
Code:
(function(H) {
H.Series.prototype.animate = function(init) {
var series = this,
chart = series.chart,
clipRect,
animation = H.animObject(series.options.animation),
sharedClipKey;
// Initialize the animation. Set up the clipping rectangle.
if (init) {
series.setClip(animation);
// Run the animation
} else {
sharedClipKey = this.sharedClipKey;
clipRect = chart[sharedClipKey];
if (clipRect) {
clipRect.animate({
width: series.group.getBBox().width,
x: 0
}, animation);
}
if (chart[sharedClipKey + 'm']) {
chart[sharedClipKey + 'm'].animate({
width: chart.plotSizeX + 99,
x: 0
}, animation);
}
// Delete this function to allow it only once
series.animate = null;
}
}
})(Highcharts);
Highcharts.setOptions({
chart: {
events: {
load: function() {
var chart = this,
series = chart.series[0],
seriesWidth = series.graph.getBBox().width,
duration = (seriesWidth / chart.plotWidth) * series.options.animation.duration;
chart.series[0].update({
animation: {
duration: duration
}
});
}
}
},
plotOptions: {
series: {
animation: {
duration: 2000
}
}
}
});
Highcharts.chart('container', {
title: {
text: 'Chart with half data but with max data'
},
subtitle: {
text: 'A label should appear when all points are drawn'
},
xAxis: {
type: 'datetime',
min: Date.UTC(2019, 0, 1),
max: Date.UTC(2019, 11, 31),
tickInterval: 2592000000, // month
},
plotOptions: {
series: {
events: {
afterAnimate: function() {
this.chart.renderer.label(this.name + ' has appeared', 100, 70)
.attr({
padding: 10,
fill: Highcharts.getOptions().colors[0]
})
.css({
color: 'white'
})
.add();
}
}
}
},
series: [{
data: [{
x: Date.UTC(2019, 0, 1),
y: 29.9
},
{
x: Date.UTC(2019, 1, 1),
y: 139.9
},
{
x: Date.UTC(2019, 2, 1),
y: 59.9
},
{
x: Date.UTC(2019, 3, 1),
y: 19.9
},
]
}]
});
Highcharts.chart('container2', {
title: {
text: 'Chart with full data'
},
subtitle: {
text: 'A label should appear on the plot area after animate'
},
xAxis: {
type: 'datetime',
min: Date.UTC(2019, 0, 1),
max: Date.UTC(2019, 11, 31),
tickInterval: 2592000000, // month
},
plotOptions: {
series: {
events: {
afterAnimate: function() {
this.chart.renderer.label(this.name + ' has appeared', 100, 70)
.attr({
padding: 10,
fill: Highcharts.getOptions().colors[0]
})
.css({
color: 'white'
})
.add();
}
}
}
},
series: [{
data: [{
x: Date.UTC(2019, 0, 1),
y: 29.9
},
{
x: Date.UTC(2019, 1, 1),
y: 139.9
},
{
x: Date.UTC(2019, 2, 1),
y: 59.9
},
{
x: Date.UTC(2019, 3, 1),
y: 19.9
},
{
x: Date.UTC(2019, 4, 1),
y: 29.9
},
{
x: Date.UTC(2019, 5, 1),
y: 139.9
},
{
x: Date.UTC(2019, 6, 1),
y: 59.9
},
{
x: Date.UTC(2019, 7, 1),
y: 19.9
},
{
x: Date.UTC(2019, 8, 1),
y: 29.9
},
{
x: Date.UTC(2019, 9, 1),
y: 139.9
},
{
x: Date.UTC(2019, 10, 1),
y: 59.9
},
{
x: Date.UTC(2019, 11, 1),
y: 19.9
},
]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
<div id="container2" style="height: 400px"></div>
Demo:
https://jsfiddle.net/BlackLabel/gj7eqkv8/
API reference:
https://api.highcharts.com/highcharts/chart.events.load
I am using Highcharts to create a column chart with two data points. There's only one series. I am using styling to make each column a different color, but I would also like to add a background image behind each column. I've tried using pattern fill, but it repeats the image for the whole area of the column, whereas I just need a single 30x30 image at the bottom of each column. I also tried using chart.renderer.image to add the svg image and managed to position it well, but can't make the image responsive (chart will be viewed on tablets and mobile devices in addition to computer screens).
My chart details are below:
const categoryColors = {
'cat1': '#ff9800',
'cat2': '#8256ce'
};
Highcharts.chart('gap_bar_chart', {
chart: {
type: 'column'
},
title: {
text: null
},
xAxis: {
categories: ['cat1','cat2'],
labels: {
useHTML: true,
formatter: function () {
console.log(this);
return '<span style="color: ' +categoryColors[this.value] + '">'+this.value+'</span>';
}
},
},
yAxis: {
min: 0,
title: {
useHTML: true,
text: '<b>Percent Earning Junior Status</b>'
},
labels: {
format: "{value} %"
},
lineWidth: 0,
minorGridLineWidth: 0,
gridLineWidth: 0,
lineColor: 'transparent'
},
tooltip: {
headerFormat: '<table><tr><th>Percent of Students Earning Junior Status within 2 Years</th></tr><tr><th><hr/></th></tr>',
pointFormat: '<tr><td><b>{point.name}</b>: {point.y: .0f}% ({point.numberStr} students)</td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
legend: {
enabled: false
},
series: [{
data: [
{
y: chartData.p_jun2yr_nongap*100 || 0,
total: chartData.n_jun2yr_nongap,
color: '#FCCA7D',
category: 'Non-URM',
name: 'Non-URM',
numberStr: chartData.n_jun2yr_nongap.toLocaleString()
},
{
y: chartData.p_jun2yr_gap*100 || 0,
total: chartData.n_jun2yr_gap,
color: '#9675CF',
category: 'cat2',
name: 'cat2',
numberStr: chartData.n_jun2yr_gap.toLocaleString()
}
]
}]
});
Here is what I would like to accomplish: https://imgur.com/a/oTG34G6
In render event you can use Highcharts.SVGRenderer.image to add the image and make its position and size dynamically dependent on the column:
events: {
render: function() {
var chart = this,
shape,
points = this.series[0].points;
if (chart.customImages) {
chart.customImages.forEach(function(el) {
el.destroy();
});
chart.customImages.length = 0;
} else {
chart.customImages = [];
}
points.forEach(function(p) {
shape = p.shapeArgs;
chart.customImages.push(
chart.renderer.image(
'https://www.highcharts.com/samples/graphics/sun.png',
shape.x + chart.plotLeft + shape.width / 2 - shape.width / 2,
shape.y + chart.plotTop + shape.height - shape.width,
shape.width,
shape.width
).attr({
zIndex: 3
}).add()
);
});
}
}
Live demo: http://jsfiddle.net/BlackLabel/eLwv9ruh/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image
I have just started exploring highcharts API. I am trying to create a highstock chart where I can select some points from the chart and edit/delete the values. However, even though I have got the selected points, I could not see them marked on the chart. The following code is working fine for highcharts, but not for highstock:
var option = {
chart: {
renderTo: 'container',
defaultSeriesType: 'line',
width: 800,
height:500,
events: {
selection: function(event) {
for (var i = 0; i < this.series[0].data.length; i++) {
var point = this.series[0].data[i];
console.log("Point:",point.y,point.x);
if (point.x >= event.xAxis[0].min &&
point.x <= event.xAxis[0].max &&
point.y >= event.yAxis[0].min &&
point.y <= event.yAxis[0].max) {
console.log("selecting");
this.series[0].data[i].select(true,true);
}
}
return false;
}
},
zoomType: 'xy'
},
title: {
text: "Test",
margin: 100,
backgroundColor: '#FCFFC5'
},
rangeSelector: {
inputBoxStyle: {
right: '-280px'
},
//selected: 0
},
xAxis: {
type: 'datetime',
tickInterval: 14 * 24 * 3600 * 1000, // one week
tickWidth: 0,
gridLineWidth: 1,
labels: {
align: 'left',
x: 3,
y: -3
}
},
yAxis: [{
title: {
text: yAxisTitle
},
labels: {
align: 'left',
x: 3,
y: 16,
formatter: function() {
return Highcharts.numberFormat(this.value, 0);
}
},
showFirstLabel: false
}, {
linkedTo: 0,
gridLineWidth: 0,
opposite: true,
title: {
text: "Target Steps"
},
labels: {
align: 'right',
x: 0,
y: 16,
formatter: function() {
return Highcharts.numberFormat(this.value, 0);
}
},
showFirstLabel: false
}],
legend: {
align: 'left',
verticalAlign: 'top',
y: 20,
floating: true,
borderWidth: 0
},
tooltip: {
shared: true,
crosshairs: true
},
plotOptions: {
series: {
allowPointSelect: true,
cursor: 'pointer',
marker: {
enabled: true,
},
point: {
events: {
click: function() {
(this).select(true,true);
hs.htmlExpand(null, {
pageOrigin: {
x: this.pageX,
y: this.pageY
},
headingText: ''+Highcharts.dateFormat('%e. %b %Y', this.x) +':<br/>',
maincontentText:"Test",
width: 400,
height:220
});
}
}
},
marker: {
lineWidth: 1
}
}
},
series: [{
name: seriesName[0],
lineWidth: 4,
marker: {
radius: 4
}
},{
name: seriesName[1]
}],
};
var series = {
data: []
};
options.series[0].data = myArray[0];
options.series[1].data = myArray[1];
window.historic_chart = new Highcharts.StockChart(options);
I would really appreciate if anyone helps me find out a solution to this problem and explains why the selected points are not marked on the highstock charts.
Thanks.
Most probably you are using sometimes dataGrouping, so you have empty series.data array. In that case use series groupedData to list points, see: http://jsfiddle.net/awGwn/2/
events: {
selection: function (event) {
console.log(this);
var points = this.series[0].data;
if(points.length == 0 ) {
points = this.series[0].groupedData;
}
for (var i in points) {
var point = points[i];
console.log("Point:", point.y, point.x);
if (point.x >= event.xAxis[0].min && point.x <= event.xAxis[0].max && point.y >= event.yAxis[0].min && point.y <= event.yAxis[0].max) {
console.log("selecting");
point.select(true, true);
}
}
return false;
}
},
zoomType: 'xy'
If this won't help, recrate issue by upgrading my jsFiddle, please.
When I try do display flat values using HighStock chart the ticks and labes on Y Axis disappear as you can see in the followin link:
http://jsfiddle.net/garlam/VmwAQ/
$(function() {
var chart = new Highcharts.StockChart({
chart: {
renderTo: 'container'
},
rangeSelector: {
selected: 1
},
yAxis: {
title: {
text: 'test-values'
}
},
series: [{
name: 'test',
data: [ { x: 1361443380000, y: 10}, { x: 1361443410000, y: 10}, { x: 1361443440000, y:10}, {x:1361443470000, y:10} ]
}]
});
});
I would like to avoid set of y axis min value
Any help ?
You can set min / max value
yAxis: {
min:0,
max:20,
title: {
text: 'test-values'
}
},