I am using the Highcharts synchronized charts to display three different variables. However, in order to render cleaner graphs, I'd like to display the x-axis (which is the same for all three graphs) only for the bottom graph.
For that, I presume, I need to cycle at the end of the generation process through the charts and suppress the first two x-axis, kind like
for (i = 0; i < (Highcharts.charts.length - 1); i = i + 1)
{
chart = Highcharts.charts[i];
chart.xAxis.labels.enabled = false;
}
Here is the default fiddle.
I don't succeed in getting this to work. Can anyone help me out on this?
You can set the xAxis.visible property depending on the chart index:
success: function (activity) {
activity = JSON.parse(activity);
activity.datasets.forEach(function (dataset, i) {
...
Highcharts.chart(chartDiv, {
xAxis: {
visible: i === 2,
...
},
...
});
});
}
Live demo: https://jsfiddle.net/BlackLabel/cmdb5at0/
API Reference: https://api.highcharts.com/highcharts/xAxis.visible
Related
I have a set of interconnected charts with Highcharts and callback functions. Specifically, put together a scatter plot with an x-axis range selection, which connects to a bar chart that reflects the average y-value of the points selected, by category.
It uses the 'events' key when creating the chart to call a function that edits and redraws the bar chart.
Please click on this sandbox link to see the example that I have put together: https://codesandbox.io/s/youthful-browser-mid8x?file=/index.html
I would like to know if the code can be written any better with improvements. If anyone can please review and let me know. Thanks.
You don't need to call redraw after setData:
function update_chart2(xmin, xmax) {
...
chart2.series[0].setData(new_data);
// chart2.redraw(); - redraw is called in setData
}
You can update xAxis with plot-band options instead of removing and adding it.
events: {
selection: function (event) {
...
if (event.xAxis) {
xmin = event.xAxis[0].min;
xmax = event.xAxis[0].max;
this.xAxis[0].update(
{
plotBands: [
{
from: xmin,
to: xmax
}
]
},
false
);
}
update_chart2(Math.floor(xmin) + 1, Math.floor(xmax) + 1);
},
...
}
API Reference:
https://api.highcharts.com/class-reference/Highcharts.Series#setData
https://api.highcharts.com/class-reference/Highcharts.Axis#update
I have created an highcharts stacked bar chart, but when the data is skewed, the bars are not visible or the numbers overlap, as shown in below image.
I have seen many posts, but there is no out of the box solution for this, so i am making my custom solution.
I am setting a default height of 150 if the y value is less than 150.
This solution works, but the total of the bars now is shown to be 300 instead of the actual original value. How can i change the total stacklabel value on my own? I am unable to find a way to do that.
Here is the code to change the height to default values. I am storing the actual value in realValue variable in the point object.
chartOptions = {
type: CHARTING.CHART_OPTIONS.TYPE.COLUMN,
// On chart load, apply custom logic
events : {
load: function () {
var chart = this,
minColHeightVal = 150;
chart.series.forEach(function (s) {
s.points.forEach(function (p) {
if (p.y < minColHeightVal) {
p.update({
y: minColHeightVal,
realValue: p.y
}, false);
}
});
});
// How to iterate over the bars here and sum the actual value? i.e. point.realValue and set the stacklabel?
chart.redraw();
}
}
}
Did you try to use minPointLength option? It may be a simpler solution in your case: https://api.highcharts.com/highcharts/series.column.minPointLength
However, using your code to get the wanted result, use stackLabels.formatter function:
formatter: function() {
var series = this.axis.series,
x = this.x,
sum = 0;
series.forEach(function(s) {
if (s.points && s.points[x]) {
sum += s.points[x].realValue ? s.points[x].realValue : s.points[x].y
}
});
return sum;
}
Live demo: https://jsfiddle.net/BlackLabel/uocdykbL/
API Reference: https://api.highcharts.com/highcharts/yAxis.stackLabels.formatter
I have been playing a lot with Chart.Js but trying my hardest to avoid getting into Canvas itself due to time constraints and a personal preference of the SVG route of D3 et al.
I have a mixture of charts on a dashboard page, and everything looks fantastic except for one issue - you have to hover over a pie segment in order to see the underlying % or value.
For a dashboard view, my users would prefer to just quickly see some data labels on the segments - as with Excel - possibly easier to explain with an image:
https://support.office.com/en-gb/article/Display-or-hide-data-label-leader-lines-in-a-pie-chart-d7e7c62e-aaa5-483a-aa00-6d2c437df61b
The problem with other solutions I've found here are that they are simply displaying the value in the segment, but some segments are too small for this to be the way forward.
There were also other solutions that always displayed tooltips - but there was a lot of overlapping and generally looked quite horrible.
I would even be happy if the legend could display data next to it, but I don't understand why a lot more people haven't requested the same functionality - am I missing something?
This feature isn't available so far, so there is no really quick solution for that.
It actually is possible to show the data within the legend (I have done this for dashboards I create at work). You just need to use the generateLabels legend label property to achieve this.
Here is an example that shows the data value in parenthesis within the legend (this is done in the legend item text property that is returned from the function).
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var custom = arc.custom || {};
var getValueAtIndexOrDefault = Chart.helpers.getValueAtIndexOrDefault;
var arcOpts = chart.options.elements.arc;
var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
return {
// here is where we are adding the data values to the legend title
text: label + " (" + ds.data[i].toLocaleString() + ")",
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
index: i // extra data used for toggling the correct item
};
});
} else {
return [];
}
}
You can see it in action at this codepen.
This is in continued to my question here
I was having a lot of problems in creating highcharts basic charts using CSV data from my local filesystem without using a server/framework and just basic HTML/CSS/JS etc
So, finally, I got an idea to create a chart inside "d3.csv" function wherein we can add highchart functions insdie d3.csv ones
But, there seems to be something very silly wrong, I'm trying with a very basic code and table.
HTML code has only container div element,
Javascript
d3.csv("test.csv", function(data) {
data.forEach(function(d) {
name = d.name,
apples = +d.apples
});
console.log(data[2]);
dataset = data;
//display();
console.log(dataset[0]);
console.log(dataset[0].name);
function push(a)
{
var filter = [];
for (i=0; i<a.length ; i++)
{
filter.push(a[i].apples);
//console.log (filter);
}
return filter;
}
window.apples = push(dataset);
console.log(apples);
$(function () {
$('#container').highcharts({
chart: {
type : 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: [dataset[0].name, dataset[1].name]
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
data: apples
}
]
});
})
});
test.csv :
name,apples
John,8
Jane,3
My console is showing "apples" correctly as [8,3]. I'm getting an empty graph on screen with only axes shown and nothing inside and also, x axis and y axis elements are interchanged.
What am I doing wrong here? Is the global variable - apples, not being accessed inside highcharts fucntions?
UPDATE :
Found the answer, but only one number is showing up.
I have 2 more questions :
How do I show the whole series?
Is this a good method to draw highcharts or will I face many issues later?
Found the solution to this, myself, for a change.
Highcharts will expect function to be parsed in their format ( Highcharts error 14 in console)
Changed my function above to this,
for (i=0; i<a.length ; i++)
{
x = a[i].apples;
y = parseFloat(x)
filter.push(y);
}
return filter;
}
window.apples = push(dataset);
And the series part to this :
series: [{
data : [apples]
}
]
This is finally, giving me a graph with one bar (John, 8) now!!
The second number is still not being loaded, if someone wants to help with that, please comment below.
Update :
changed
data : [apples] -> data: apples (Correct format)
Credits : PawelFus
I'm trying to make a particular bar chart with D3.js, and I don't find any example who could match. I would code a bar chart with two series (one negative, and one generally positive) disposed on the same line, but not stacked.
I guess that maybe it's not very clear, so I've made this on Highcharts. I want to use D3 to connect the chart with a map I did before.
So, does someone know any example that could help me? Can I sort directly the chart even if my series are unordered? And if the two series are punctually postive, does the little one appear in front of the largest?
The trick is to order your data, in order to do so, you can use the [d3.ascending()][1] functions:
with the following example data:
data = [{
name: "A",
valueRight: 1,
valueLeft: 2
}, {
name: "B",
valueRight: 4,
valueLeft: 5
}, ...]
We would have:
function leftBound(node) {
return d3.max([node.valueLeft,-node.valueRight])
}
function rightBound(node) {
return d3.max([node.valueRight,-node.valueLeft])
}
dataSort = function(a,b) {
res = d3.descending(leftBound(a),leftBound(b))
if(res==0) {
return d3.descending(rightBound(a),rightBound(b))
} else {
return res
}
}
For reusable charts, you can also use [selection.sort()][2] but you have to do this for the 2 bar categories.
JsFiddle: http://jsfiddle.net/vgZ6E/55/
ScreenShot:
The original code is from the following question: d3.js bar chart with pos & neg bars (win/loss) for each record