I am implementing a Sankey charts using Highcharts where I need to display each nodes in specific symbol. I want to implement marker symbol feature for my Sankey graph.
I tried using marker.symbol which is not working.
marker: {
symbol: 'triangle'
}
Is there a way to implement custom symbols for Sankey graph? Also is there a way where I can control the width of links between each nodes? All my nodes have same weight, hence I want a way to fix my width.
Highcharts does not provide options that will allow to modify the marker symbol and the link width for sankey chart type, so it is not possible by default.
Workaround
To modify the links width, set scale and translate attributes.
To change the markers, use Highcharts.SVGRenderer and replace default rects by triangles.
chart: {
height: 200,
events: {
load: function() {
var points = this.series[0].points,
fromNodeBBox,
toNodeBBox,
linkBBox;
points.forEach(function(p) {
fromNodeBBox = p.fromNode.graphic.getBBox();
toNodeBBox = p.toNode.graphic.getBBox();
this.renderer.symbol(
'triangle',
fromNodeBBox.x + this.plotLeft + 10,
fromNodeBBox.y + this.plotTop,
fromNodeBBox.width,
fromNodeBBox.height
).attr({
fill: p.fromNode.color
}).add();
this.renderer.symbol(
'triangle',
toNodeBBox.x + this.plotLeft - 10,
toNodeBBox.y + this.plotTop,
toNodeBBox.width,
toNodeBBox.height
).attr({
fill: p.toNode.color,
zIndex: 3
}).add();
linkBBox = p.graphic.getBBox();
p.graphic.attr({
transform: 'scale(1 0.5) translate(0 ' + (linkBBox.y + fromNodeBBox.height / 2) + ')'
});
p.fromNode.graphic.destroy();
p.toNode.graphic.destroy();
}, this);
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/f4u03qvd/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#symbol
Related
I have a chart with some indicators below it. Each indicator area consists
of a svg renderer button. so when I use resize property to drag and resize
the panes, the series resized perfectly but the button remains in its same
position, Can we move the button with the resizer?
Here I created a sample link to regenerate
https://jsfiddle.net/q0ybpnvx/2/
Any help will be appreciated. I am having great trouble. Thank you
You can add and position the custom button in render event:
chart: {
events: {
render: function() {
var chart = this;
if (chart.customBtn) {
chart.customBtn.attr({
y: chart.yAxis[1].top,
});
} else {
chart.customBtn = chart.renderer.button(
'sometext',
5,
chart.yAxis[1].top,
function() {
console.log('some task')
}).add()
}
}
}
},
Live demo: https://jsfiddle.net/BlackLabel/b7vq4ecy/
API Reference:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I was able to do something by manually changing the x/y attributes of my svgRenderer label, the same should apply to buttons.
I'm in angular and have a listener for screen resizing:
Also Note that you can change the entire SVGRenderer label with the attr.text property.
this.chart = Highcharts.chart(.....);
// I used a helper method to create the label
this.chart.myLabel = this.labelCreationHelperMethod(this.chart, data);
this.windowEventService.resize$.subscribe(dimensions => {
if(dimensions.x < 500) { //this would be your charts resize breakpoint
// here I was using a specific chart series property to tell where to put my x coordinate,
// you can traverse through the chart object to find a similar number,
// or just use a hardcoded number
this.chart.myLabel.attr({ y: 15, x: this.chart.series[0].points[0].plotX + 20 });
} else {
this.chart.myLabel.attr({ y: 100, x: this.chart.series[0].points[0].plotX + 50 });
}
}
//Returns the label object that we keep a reference to in the chart object.
labelCreationHelperMethod() {
const y = screen.width > 500 ? 100 : 15;
const x = screen.width > 500 ? this.chart.series[0].points[0].plotX + 50 :
this.chart.series[0].points[0].plotX + 20
// your label
const label = `<div style="color: blue"...> My Label Stuff</div>`
return chart.renderer.label(label, x, y, 'callout', offset + chart.plotLeft, chart.plotTop + 80, true)
.attr({
fill: '#e8e8e8',
padding: 15,
r: 5,
zIndex: 6
})
.add();
}
I change the color and radius of my spline's marker as soon as it crosses a certain value by using point.update however now I am aggregating the data using dataGrouping and I have lost that ability. How can I color the aggregated data point?
Currently it is not possible to update grouped points. Please check a thread in this github isssue: https://github.com/highcharts/highcharts/issues/5147
However, you can use attr method directly on SVG point elements:
chart: {
events: {
load: function() {
var points = this.series[0].groupedData;
points.forEach(function(point) {
if (point.y > 30) {
point.graphic.attr({
width: 8,
height: 8,
fill: 'red',
translateX: -2
});
}
});
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/58afeL47/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
I have a project using Highcharts 5 . I'm trying to get the chart labels on opposite sides of the donut graph, aligned straight left and straight right on each side, with the connectors spanning the distance appropriately.
Attached is the comp of what it should look like. Any thoughts on how to achieve this?
Thanks!
You can create the legend manually (html label and connector line with dot) using renderer:
var points = this.series[0].points,
renderer = this.renderer;
points.forEach(function(point) {
var labelOptions = point.options.label;
if (labelOptions) {
// text
renderer.text(labelOptions.text, labelOptions.x, labelOptions.y - 30, true).add();
// connector
var path = ['M', labelOptions.x, labelOptions.y].concat(labelOptions.connector.path);
renderer.path(path).attr({
stroke: 'gray',
'stroke-width': 1,
}).add();
// dot
renderer.circle(labelOptions.x, labelOptions.y, 3).attr({
fill: 'gray',
'stroke-width': 1,
}).add();
}
});
Options:
{
name: 'Microsoft Internet Explorer',
y: 56.33,
label: {
x: 400,
y: 100,
connector: {
path: ['l', -50, 0, 'l', 0, 100]
},
text: "<div class='label'><img src='https://wordpress.highcharts.com/blog/wp-content/uploads/2017/08/28160952/highcharts_logo.png' width='30' height='30'></img><div>Label text in HTML</div></div>"
}
}
Live working example (one label created): http://jsfiddle.net/kkulig/wdtpyof1/
This demo is only a good starting point. You should create your own mechanisms responsible for positioning labels.
API reference: http://api.highcharts.com/class-reference/Highcharts.SVGRenderer
This is solution for your issue
you can customize the connectors and get the chart labels on opposite sides of the donut graph.
http://jsfiddle.net/nmtri1101/ogfbxfqd/2/
Code jsfiddle :)
I am looking to add plotbands/zones to my highchart. I am referring to dark yellow bands below the marker points.
I have seen a few examples of how to draw plotBands but none seem to give the option of limit the height of plotBand.
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/members/axis-addplotband/
chart.xAxis[0].addPlotBand({
from: 5.5,
to: 7.5,
color: '#FCFFC5',
id: 'plot-band-1'
});
Any clue will be appreciated.
You should be able to use area series type and add break lines in your load (and redraw) event callback function, using chart.renderer.path:
var breakLines = function(chart) {
var xAxis = chart.xAxis[0],
yAxis = chart.yAxis[0];
$('.breakLines').remove();
Highcharts.each(chart.series[0].data, function(p) {
chart.renderer.path([
'M',
xAxis.toPixels(p.x),
yAxis.toPixels(0),
'L',
xAxis.toPixels(p.x),
yAxis.toPixels(p.y)
]).attr({
'stroke-width': 1,
stroke: 'white',
zIndex: 3
}).addClass('breakLines').add()
});
}
Here you can see an example how it can work: http://jsfiddle.net/jgyxcbxo/1/
The default behavior of the x-axis title alignment is within the bounds of the x-axis. However, the legend alignment is within the bounds of the entire chart. Thus, if you align both center, they have a slight offset. How can I get the legend to base its position off of the x-axis bounds instead? My graph options are dynamic, so I would need to do it dynamically.
Sample JS Fiddle
$('#container').highcharts({
legend: { margin:5, padding:0 },
xAxis:{
title:{
text:'THIS IS MY X-AXIS TITLE',
align:'middle',
},
categories:["A","B","C","D","E","F"]
}
});
Thanks in advance!
Example for you: http://jsfiddle.net/xqag5e72/2/
In short, you can change translation for legend to be similar to xAxis' title:
function moveLegend(e) {
var legend = this.legend,
x = this.plotLeft + (this.xAxis[0].width / 2) - legend.group.getBBox().width / 2,
y = legend.group.translateY;
legend.group.attr({
transform: 'translate(' + x + ',' + y +')'
});
}
Note: I'm using load and redraw events, to translate legend after first initialization and later to make this legend responsive.