HighCharts: How to format particular label column? - css

I need to show the label values inside the Highcharts bar chart. It can be implemented using dataLabels.Formatter function.
But when the bar is in consist-able size the labels are shown inside the bar and it is looking good. In some cases, the bar is very small in size comparing to the label.
Please see the code pen here, https://codepen.io/JGSpark/pen/YzzBydv?editors=1010
The last bar is very small and 40 is showing outside. As the color: 'white' is commonly used for all the labels it is showing in white though it is in outside.
How can I change the color of the label if it is showing out?
In this example, I need to change the color of label 40 to black. Any suggestions?

You need to add custom formatter which will check the size of yAxis value and will change the color of label accordingly:
formatter: function() {
var max = this.series.yAxis.max,
color = this.y / max < 0.05 ? 'black' : 'white'; // 5% width
return '<p style="color: ' + color + '">' + this.y + ' M</p>';
},

If your chart is not a dynamically created you can set the dataLabels.color for the particular point.
{
y: 40,
dataLabels: {
color: 'black'
}
}
Demo
API
EDIT
Another solution which I can suggest is to add a functionality inside the chart.events.load which will filter if dataLabels is aligned to left or right and set wanted color - it will work if more labels will be outside the column bar.
events: {
load() {
let chart = this,
series = chart.series;
series[0].points.forEach(p => {
if (p.dataLabel.alignOptions.align === 'left') {
p.dataLabel.css({
color: 'black'
})
}
})
}
}
Demo
API

Related

Highcharts: How to add another(custom) label/ legend/ something else to the top right of the graph?

In my highcharts, I already have a legend at the bottom left of the graph but want to add a custom status indicator for the entire graph. It's going to be a colored oval with a colored dot and a status on it like in the picture.
Should I be trying to use a custom legend or something else? I don't need to hide/show abiliity of the legend so maybe I'm thinking a label is more appropriate but it seems like those only go in the graph. I want something on the top right of the graph. I'm looking through the API to see what else is available but haven't found one that suites my needs.
edit-
seems like I might have to do "chart.renderer.text" but I'm not sure how to convert and make it work in typescript http://jsfiddle.net/phpdeveloperrahul/HW7Rm/
function (chart) {
var point = chart.series[0].data[8],
text = chart.renderer.text(
'Max',
point.plotX + chart.plotLeft + 10,
point.plotY + chart.plotTop - 10
).attr({
zIndex: 5
}).add(),
box = text.getBBox();
chart.renderer.rect(box.x - 5, box.y - 5, box.width + 10, box.height + 10, 5)
.attr({
fill: '#FFFFEF',
stroke: 'gray',
'stroke-width': 1,
zIndex: 4
})
.add();
});
The best way to add a custom element inside the legend is to use the legend.labelFormatter.
events: {
render() {
let chart = this,
legendAttr = chart.legend.box.getBBox(),
padding = 5;
chart.plus = chart.renderer.text('| +', chart.legend.box.parentGroup.alignAttr.translateX + legendAttr.width + padding, chart.spacingBox.height + padding / 2).attr({
cursor: 'pointer',
}).css({
fontSize: 20
}).on(
"click",
function() {
alert('plus was clicked')
}
).add()
}
}
API References:
https://api.highcharts.com/highcharts/legend.labelFormatter,
Demo: https://jsfiddle.net/BlackLabel/yu7qm9jx/1/
I decided to just get rid of the title and add custom css to the top of it.

Adding styling to a portion of a <text> tag depending on the value it contains

In this fiddle what I'm after is giving all the 0s in the YAxis a grey colour without affecting the numbers that are bigger than 0. The issue here is that they are contained in the same SVG tag: <tspan>3000</tspan>. Is there a way I can target a particular text value inside a tag using css? i.e.
tspan[0]{
color: #808080;
}
Or is there a way I can do that using Highcharts' yAxis.labels.formatter ?
This is totally hacky, but I got it to work. Under yaxis:
labels: {
formatter: function () {
var label = this.axis.defaultLabelFormatter.call(this);
label = label.replace(/(0+$)/,'<span style="color: #ccc;">$1</span>');
return label;
}
},

change the legend.y property on browser resize

we use the highchart control with Angular and bootstrap.
To adjust the vertical space between the chart and the legend (both are rendered by highchart as svg elements), we set the y property of the legend on page load (in the controller) like this:
$scope.chartContracts = {
options: {
chart: {
type: 'pie',
marginBottom: 50
},
legend : {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom',
x: 0,
y: 4,
Now in one of the Bootstraps layouts, the spacing (y) should be -10 in stead of 4 because for some reason an extra spacing is added.
So it should be based on media query or something similar I guess?
The question is how to do this... I tried with css but I can't seem to style SVG elements (they are called <g>)?
You can check window width and then return correct value.
var wWidth = $(window).width(),
value;
if(wWidth < 400) {
value = 5;
} else {
value = 10;
}
//scope
y: value

How to fill area with custom color under line in nvd3 linechart ?

I'm working with nvd3 and I'm not much hands-on with its styling (css properties) to customize it. I have a line chart with two data lines on it.
The code for drawing the lines is following:
nv.addGraph(function() {
chart = nv.models.lineChart();
chart.margin({
left : 100,
bottom : 100
}).useInteractiveGuideline(true).showLegend(true).duration(250);
chart.xAxis.axisLabel("Date").tickFormat(function(d) {
var date = new Date(d);
return d3.time.format("%b-%e")(date);
});
chart.yAxis.axisLabel('').tickFormat(d3.format(',.2f'));
chart.showXAxis(true);
d3.select('#startupRiskLineChart').datum(
prepareDataObj(val1_y, val1_x, val2_y, val1_x))
.transition().call(chart);
;
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) {
nv.log('New State:', JSON.stringify(e));
});
return chart;
});
Is there any way to fill the area under data line with a lighter color?
Any help would be highy apperiated.
To get a line chart with a filled area in a specific color:
Add area: true to the data series, as in this example.
Add this CSS: .nv-area { fill: red }
The opacity of the area is set to 0.5, so filling it with red will actually make it pink:
chart.color(["red","yellow","blue"]);
'#00FFFF','#0FF','cyan' all are valid ways to set colors
Another way is set it in data itself
[{
values:[{x:1,y:1},{x:2,y:4},{x:3,y:9},{x:4,y:16}],
key: 'not a Sine Wave',
color: '#ff7f0e' //color - optional: choose your own line color.
}]
duplicate question i guess
Add
classed: "my-custom-approx-line"
to config of specific line and add styling:
&.nv-area {
fill-opacity: 0.2;
}
As of commit #becd772
Use .nv-group{ fill-opacity: 1.0 !important; } to fill the area with the same color as the line

Highcharts styling, Legend & custom fonts

I have a problem with styling legend items in Highcharts, when applying a Custom Font to the legend items. Actually items are so close to each other and itemMarginBottom and itemMarginTop are not working.
Here is part of my Highcharts code:
legend: {
enabled: true,
y: 20,
align: 'right',
verticalAlign: 'top',
margin: 30,
width: 200,
borderWidth: 0,
itemMarginTop: 15,
itemMarginBottom: 15,
itemStyle: {
color: '#000',
fontFamily: 'MuseoS500'
}
},
And here is the legend's screenshot:
My Ugly Solution:
I solved that like below, but sadly hard-coded:
// it is for the text's in the legend, I'll start from 0 and will
// increase by 10, so it's adding 10 pixels extra space to the next one
var z = 0;
// this is for tiny-lines near the texts in legend, they starts from 14
// and increasing by 14 also ...
var p = 14;
// loop through <text> tags, which are texts in the lgened
$('.highcharts-legend > text').each( function (i) {
// they have 'x' and 'y' attribute, I need to work on 'y' obviously
y = parseInt($(this).attr('y'));
// increasing 'y' value ...
$(this).attr('y', y + z);
// next element is <path>, the colorful lines ...
$(this).next().attr('transform', 'translate(30,' + p + ')');
// increasing the values, for the next item in the loop ...
z = z + 10;
p = p + 10 + 14;
});
I know that it's so stupid, but I couldn't solve that in any other ways, and I had to make them works somehow. I would be happy to hear your thoughts also ... :)
The new legends after the patch:
The Highchart documentation says that there is a property called lineHeight but Its deprecated since Highcharts 2.1
The post of official Highcharts forum also confirms the same. So, Either you can hack source code to change the height according to your need or Try to correct item height with javascript after chart render.
Also, There is an attribute called itemStyle which allows to set CSS for legend item.
e.g. paddingBottom: '10px'
Check the example :
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/legend/lineheight/

Resources