How to match columns height with spline in Highcharts - javascript

I'm using Highcharts to draw a spline. This works good.
I'm using secondary series (columns) for another data.
My problem is: how to set column height to be matched with spline.
As far i've done this: jsfiddle
Columns have height almost i need, but not all.
It is possible at all?
Relevant code:
$('#chart').highcharts({
title: {text: 'Chart'},
chart: {
type: 'spline'
},
xAxis: {
title: {
text: 'X-Axis'
}
},
yAxis: {
title: {
text: 'Y-Axis'
},
labels: {
enabled: false
}
},
series: [{
name: 'Chart',
data: chdata,
marker: {
enabled: false
},
}],
legend: {
enabled: false
}
});
var chartObj = Highcharts.charts[$('#chart').attr('data-highcharts-chart')];
var d = [];
for(var i = 0; i < ldata.length; i++) {
d.push([ldata[i],getYValue(chartObj,0,getClosest(ldata[i],bdata[0]))]);
}
chartObj.addSeries({
type: 'column',
pointWidth: 1,
borderWidth: 0,
data: d
});
I've tried even with plotLines, but it have height of whole chart.
Thanks,
Bartek

Rather than plotting the height of the closest point, try plotting the average height of the points either side of your bar.
You can get even closer if you work out a linear best fit for your bar on the line between the points either side. Something like:
function getY(xVal,points) {
var higher = 0;
var lower=0;
for(var i=0;i<points.length;i++){
if (points[i][0] > xVal) {
higher=i;
lower=i-1;
break;
}
}
return points[lower][1] + ((points[higher][1]-points[lower][1])*(xVal-points[lower][0])/(points[higher][0]-points[lower][0]));
};
http://jsfiddle.net/5h471o3d/

Related

Too many categories to display on column chart with vue-apexchart

i have a big data set to display ( around 150 category) with a library named vue-apexchart my problem is that i cant find a way to make the graph scrollable on xaxis without having a broken display the following image will explain my problem better
as you can see having too many categories leads to an unreadable chart
can you please help me
i have tried to make a scrollable div, the probleme still remains ( unreadable xaxis )
here's my chartOptions object :
chartOptions: {
chart: {
type: "bar",
height: 350,
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: "55%",
endingShape: "rounded",
},
},
dataLabels: {
enabled: false,
},
stroke: {
show: true,
width: 2,
colors: ["transparent"],
},
xaxis: {
categories: [],
},
fill: {
opacity: 1,
},
},
I think there are two strategies that you could adopt here. In my opinion, the second one is better.
1. Horizontal bar chart
If you do not have strict constraints in terms of UX/UI, a possible solution might be to switch both axes...
plotOptions: {
bar: {
horizontal: true
}
},
... and give your chart much more height:
chart: {
type: 'bar',
height: 2500,
},
Doing that would allow you to use the natural vertical scrolling of your browser.
let data = [];
for (let i = 1; i <= 150; i++) {
data.push({x: `Category ${i}`, y: i});
}
let options = {
series: [{
name: 'Series',
data
}],
chart: {
type: 'bar',
height: 2500
},
yaxis: {
labels: {
style: {
fontSize: '10px'
},
offsetY: 3
}
},
plotOptions: {
bar: {
horizontal: true
}
},
dataLabels: {
enabled: false
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>
All categories are visible. This is not very handy, though.
2. Zoom, pan and tick settings
Zooming and panning are useful features. They are available by default in the toolbar, but this toolbar does not appear immediately when your xaxis has categories. To enable the toolbar in this case, you have to change xaxis.tickPlacement from 'between' to 'on' (see Zoom on Category Bar Charts – ApexCharts.js).
Since you have a lot of categories, it is also a good idea to limit the number of visible labels with xaxis.tickAmount.
xaxis: {
tickPlacement: 'on',
tickAmount: 25
},
Thanks to the zoomX() method, you can decide to display your chart with only a subset of your data. The rest is still accessible via zooming and/or panning.
let data = [];
for (let i = 1; i <= 150; i++) {
data.push({x: `Category ${i}`, y: i});
}
let options = {
series: [{
name: 'Series',
data
}],
chart: {
type: 'bar',
height: 350
},
xaxis: {
tickPlacement: 'on',
tickAmount: 25
},
dataLabels: {
enabled: false
}
};
let chart = new ApexCharts(document.querySelector('#chart'), options);
chart.render();
chart.zoomX(37, 71);
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>

How to highlight specific Point with Highcharts Js

I have a simple Highchart with a dataset of up to 1000 datas. There are only y values the x values are generated automatically. Also, the values come from my nodejs server so please don't be surprised about the notation.
Now I want 3 special values whose x and y values are known to be highlighted. In which way doesn't matter for now.
One possibility would be to show the point at the location, otherwise they are not displayed. The problem I have is that I don't know how to control a specific point.
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'chart-emg1',
type: 'line'
},
title: {
text: 'EMG 1'
},
xAxis: {
tickInterval: 1
},
yAxis: {
title: { text: 'Voltage'}
},
series: [{
data: [<%-data1 %>]
}]
});
You can use the load event and update specific points. For example:
events: {
load: function() {
this.series[0].points.forEach(point => {
const isPointToHighlight = pointsToHighlight.some(
p => p.x === point.x && p.y === point.y
);
if (isPointToHighlight) {
point.update({
color: 'red',
marker: {
enabled: true
}
}, false);
}
});
this.redraw();
}
}
Live demo: http://jsfiddle.net/BlackLabel/tLd3j78f/
API Reference:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/class-reference/Highcharts.Point#update

javascript highcharts builder function

I am trying to make a function which will be building Highcharts charts dynamically based on parameters passed. I do it the following way:
function makeChart(name, title, series)
{
var options = {
chart: {
type: 'areaspline',
renderTo: name
},
credits: { enabled: false },
legend: { enabled: true },
title: {
text: title
},
xAxis: {
type: 'datetime'
},
yAxis: {
gridLineDashStyle: 'dot',
title: {
text: 'Quantity'
}
},
plotOptions: {
areaspline: {
animation: false,
stacking: '',
lineWidth: 1,
marker: { enabled: false }
}
},
series: [] //chart does not display except title. It will draw if I paste the data here manually
};
this.chart = new Highcharts.Chart(options);
for (index = 0; index < series.length; ++index) {
options.series[index] = {'name':series[index][0], 'data':series[index][1], 'color':series[index][2], 'fillOpacity': .3};
}
}
makeChart('container2', 'second chart', [['thisisname1', [20,21,22,23,24,25,26,27,28], '#d8d8d8']]);//calling function with test parameters
But everything I can see is the charts title. I guess the problem is in adding data to series array. I tried to add it with several ways but it did not work, although I see that the data has been added if I console.log(options.series). Any ideas how to fix that? Thank you.
Place this.chart = new Highcharts.Chart(options); after the for loop.
You're adding the data after the chart has been initialized, for it to work this way you need to tell HighCharts to redraw itself, easier option is to init after the loop. :)

HighCharts with Dynamic Data not working

I have a ASP.NET MVC project with SignalR.
I have a page with a HighChart and the script looks like this:
$(function () {
window.Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$(document).ready(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 10
},
title: {
text: 'GMAS Queues'
},
xAxis: {
type: 'datetime',
tickInterval: 500,
labels: {
enabled: false
}
},
yAxis: {
title: {
text: 'Queue Count'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Processing Queues'
}]
});
});
$.connection.hub.logging = true;
// Reference the auto-generated proxy for the hub.
var chartData = $.connection.processingQueuesHub;
// Create a function that the hub can call back to display messages.
chartData.client.updateQueueCounts = function (data) {
//$.each(data, function(i, item) {
// // Add the message to the page.
// $('#chartDataLog').append('<li><strong>' + htmlEncode(item.QueueName)
// + '</strong>: ' + htmlEncode(item.Length) + '</li>');
//});
// set up the updating of the chart.
var series = chart.series[0];
$.each(data, function (i, item) {
if (item.QueueName == "Queue A") {
var x = Date.parse(item.Date),
y = item.Length;
series.addPoint([x, y], true, false);
}
});
};
However, I see the graph but not the points.
The strange part is the series data points are there:
Anyone know why HighCharts is not rendering the points?
Thanks, Bill N
I have to thank my good friend and co developer for figuring this out. He is a smarter and braver man than me. :) He went to the highcharts source and found that the highcharts breaks if you add to the graph series before the initial animation is completed. The animation is why the clip-rect is zero-width (it animates from zero to full width over 1s when you first create the chart). You end up adding a point to the series before this animation even really starts. This kills the animation but it doesn’t fix the width of the clip-rect. The fix is to add animation is false for the series.
series: [{ name: 'Processing Queues', data: [], animation: false }]
It looks like you are not defining what your chart.series is until it is created. The line in your ajax is as follows and its not waiting for DOM ready:
var series = chart.series[0];
But you do not define chart until $(document).ready(function () {.... Try keeping your chart object in scope of your ajax.

drawing two spline series with different number of values

i have to draw two different spline series. i got the values of the first line from a webservice, instead the second one is composed by two only values that means that is a straight line.
the code is the following
var options = {
chart: {
renderTo: 'container'
},
yAxis: {
labels: {
formatter: function () {
return '€ ' + this.value;
}
}
},
xAxis: {
categories: seriesMesi
},
series: [
{
name: 'scenario sfavorevole',
color: '#FF3300',
type: 'spline',
data: [0, 12175],
marker: {
fillColor: 'none',
lineColor: null
}
},
{
name: 'Valori del piano',
color: 'blue',
type: 'spline',
marker: {
fillColor: 'none',
lineColor: null
}
}]
};
options.series[1].data = seriesValoriPiano;
var chart = new Highcharts.Chart(options);
I can't represent the straight line: it has to occupy the whole x axis that means between the first and the last x values, but in my case it occupies only the range between the first and the second x values.
How can i do to represent a straight line that occupies all the x values?
thank you very much
I assume that you get data from webservice by $.ajax();
$.get(url,function(data){
var options = {
series:[{
//your hardcoded data
},{
data:data //data from ajax
}]
}
var chart = new Highcharts.Chart(options);
});

Categories

Resources