I have created a chart using the HighCharts javascript library, the problem I have is that my y-Axis labels are cut by the Y-Axis vertical line. I would like to add more space in the y-axis label gutter area to allow for the labels to be fully visible and so i can add some annotations to the in that area, see image below:
Ideally I would like to add 40px, to the Y-Axis gutter. I have read through the api reference and tried using "yAxis.labels.padding", "yAxis.margin" and "yAxis.offset".
My code is as follows:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<style type="text/css">
#container {
height: 400px;
width: 350px;
}
.highcharts-tick{display: none;}
.highcharts-grid-line{opacity: 0.2}
</style>
</head>
<body>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/data.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://code.highcharts.com/stock/modules/export-data.js"></script>
<script src="https://code.highcharts.com/stock/modules/accessibility.js"></script>
<div id="container"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id=container2></div>
<script type="text/javascript">
$(function() {
const options = {
chart: {
backgroundColor: '#1B191B', // Background Color
type: 'line',
zoomType: "",
},
rangeSelector : {
enabled: false,
selected : 2,
inputEnabled: false
},
title: {
text: 'APPLE INC', // Title of the Chart
align: 'left',
style: {
color: '#dedbde', // Custom CSS for the title
fontWeight: 'bold'
}
},
scrollbar: { enabled: false },
exporting: {
enabled: false
},
yAxis: {
lineWidth: 2,
tickWidth: 1,
labels: {
style: {
color: '#dedbde'
},
align: 'right',
},
opposite: true,
offset: -1
},
xAxis: {
labels: {
style: {
color: '#dedbde'
}
},
gridLineWidth: 1,
},
navigator: {
enabled: false
},
series: [{
name: 'AAPL Stock Price',
data: [],
type: 'areaspline',
threshold: null,
color: '#5861B3',
tooltip: {
valueDecimals: 2
},
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
}
}]
}
const url = 'https://demo-live-data.highcharts.com/aapl-c.json'
const chart = Highcharts.stockChart('container', options)
$.getJSON(url, function(data) {
chart.series[0].setData(data)
// Execute callback
if (chart.options.chart.events && chart.options.chart.events.dataLoad) {
const dataLoad = chart.options.chart.events.dataLoad.bind(chart)
dataLoad(data)
}
})
})
</script>
</body>
</html>
Been banging my head around this for while, but I cant seem to figure it out any help would be very much appreciated. Thanks
In Highstock, the yAxis is inverted by default, so aligning the labels is reversed as well.
The only thing you need to change is setting yAxis.labels.align to 'left'.
Demo:
https://jsfiddle.net/BlackLabel/10ae8g9d/
Related
I have a large data set which, when graphed have several vertical sections as shown below. Chart.js formats these sections with thin, semi-transparent coloring. I want to format these to match the regular, thicker and solid line style.
The dataset itself is normally in a separate file called data.js, but I linked a portion of it from a CodePen.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<!--
NOT USED FOR THIS EXAMPLE
<script src="data.js"></script>
-->
<script src="https://codepen.io/EtherealBug/pen/wjOdoa.js"></script>
</head>
<body>
<canvas id="myChart"></canvas>
</body>
<style>
canvas {
width: 100% !important;
max-width: 2000px;
height: auto !important;
}
</style>
<script>
var labels = jsonfile.jsonarray.map(function(e) {
return e.Time;
});
var data = jsonfile.jsonarray.map(function(e) {
return e.Speed;
});
var ctx = myChart.getContext('2d');
var config = {
options: {
legend: {
position: 'bottom',
},
scales: {
xAxes: [{
scaleLabel: {
fontSize: 12,
fontStyle: 'bold',
display: true,
labelString: 'Y(1)'
},
ticks: {
autoSkip: true,
maxTicksLimit: 30,
},
}],
},
},
type: 'line',
data: {
labels: labels,
datasets: [{
fill: false,
label: 'Graph Line',
data: data,
backgroundColor: 'rgba(0, 119, 204, 0.3)'
}]
}
};
var chart = new Chart(ctx, config);
</script>
</html>
I figured it out, what you're seeing when you look at the graph is actually mostly just the individual points. Due to the large number of point data, it wasn't apparent at first, but the lines were thinner than the points width.
The vertical lines being so much thinner are actually because those are formatted with the line settings. By setting the transparency of the points color and border to 0, and by reformatting the line settings, I got was able to format it the way I intended. Sample below for reference should anyone else have a similar issue in the future.
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<!--
NOT USED FOR THIS EXAMPLE
<script src="data.js"></script>
-->
<script src="https://codepen.io/EtherealBug/pen/wjOdoa.js"></script>
</head>
<body>
<canvas id="myChart"></canvas>
</body>
<style>
canvas {
width: 100% !important;
max-width: 2000px;
height: auto !important;
}
</style>
<script>
var labels = jsonfile.jsonarray.map(function(e) {
return e.Time;
});
var data = jsonfile.jsonarray.map(function(e) {
return e.Speed;
});
var ctx = myChart.getContext('2d');
var config = {
options: {
legend: {
position: 'bottom',
},
scales: {
xAxes: [{
scaleLabel: {
fontSize: 12,
fontStyle: 'bold',
display: true,
labelString: 'Y(1)'
},
ticks: {
autoSkip: true,
maxTicksLimit: 30,
},
}],
},
},
type: 'line',
data: {
labels: labels,
datasets: [{
lineTension: 0.4, //defaul val = 0.4
pointBackgroundColor: 'rgba(0,0,0,0)',
pointBorderColor: 'rgba(0,0,0,0)',
borderColor: 'black',
borderWidth: 4,
fill: false,
label: 'Graph Line',
data: data,
}]
}
};
var chart = new Chart(ctx, config);
</script>
</html>
Note: I'll accept this answer when it allows me in 2 days since it's my own.
I trying to get highcharts to draw a linked graph. It works when I have not so much data in my data set. Now I have tried to put a dataset with ~30.000 points. I see the mouse over with the points, but the line is not plot?
I have read about turboThreshold: and have set it to turboThreshold: 40000 but it does still not plot the line??
Any ideas what I do wrong?
/Jesper
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<script type="text/javascript" src="/js/lib/dummy.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<style type="text/css">
.chart {
min-width: 200px;
max-width: 1250px;
height: 350px;
margin: 0 auto;
}
</style>
<!-- http://doc.jsfiddle.net/use/hacks.html#css-panel-hack -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
</style>
<title>Highcharts Demo</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
<script type='text/javascript'>//<![CDATA[
/*
The purpose of this demo is to demonstrate how multiple charts on the same page can be linked through DOM and Highcharts events and API methods. It takes a standard Highcharts config with a
small variation for each data set, and a mouse/touch event handler to bind the charts together.
*/
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function () {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function (event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
/**
* Synchronize zooming through the setExtremes event handler.
*/
function syncExtremes(e) {
var thisChart = this.chart;
if (e.trigger !== 'syncExtremes') { // Prevent feedback loop
Highcharts.each(Highcharts.charts, function (chart) {
if (chart !== thisChart) {
if (chart.xAxis[0].setExtremes) { // It is null while updating
chart.xAxis[0].setExtremes(e.min, e.max, undefined, false, { trigger: 'syncExtremes' });
}
}
});
}
}
// Get the data. The contents of the data file can be viewed at
// https://github.com/highcharts/highcharts/blob/master/samples/data/activity.json
$.getJSON('http://vels.dk/beer/getdata.php?name=velsdk002', function (activity) {
$.each(activity.datasets, function (i, dataset) {
// Add X values
dataset.data = Highcharts.map(dataset.data, function (val, j) {
return [activity.xData[j], val];
});
$('<div class="chart">')
.appendTo('#container')
.highcharts({
chart: {
marginLeft: 40, // Keep all charts left aligned
spacingTop: 20,
spacingBottom: 20
},
title: {
//text: dataset.name,
text: null,
align: 'left',
margin: 0,
x: 30
},
credits: {
enabled: false
},
legend: {
enabled: false
},
xAxis: {
type: 'datetime',
crosshair: true,
events: {
setExtremes: syncExtremes
}
},
yAxis: {
title: {
text: dataset.name
},
opposite: true, //flytter skala til højre
labels: {
align: 'left',
x: 0,
y: -2
},
plotLines: [{
value: dataset.min,
color: 'grey',
dashStyle: 'shortdash',
width: 2,
label: {
text: 'Estimated Final Gravity - XX SG',
x: 30
}
}, {
value: dataset.max,
color: 'grey',
dashStyle: 'shortdash',
width: 2,
label: {
text: 'Estimated Starting Gravity - XX SG',
x: 30
}
}]
},
plotOptions: {
series: {
turboThreshold: 40000,
marker: {
enabled: false
}
}
},
series: [{
data: dataset.data,
name: dataset.name,
type: dataset.type,
color: Highcharts.getOptions().colors[i],
fillOpacity: 0.3,
tooltip: {
valueSuffix: ' ' + dataset.unit
}
}]
});
});
});
//]]>
</script>
<script>
// tell the embed parent frame the height of the content
if (window.parent && window.parent.parent){
window.parent.parent.postMessage(["resultsFrame", {
height: document.body.getBoundingClientRect().height,
slug: "None"
}], "*")
}
</script>
</body>
</html>
I am attempting to get the full label displayed in the x axis, but highcharts keeps on cutting it off. I tried using the crop, overflow, and margin options discussed in other posts to no avail. The only option that worked was to make the div height of the chart an absurd size.
$('#da-expulsions').highcharts({
chart: {
type: 'column',
renderTo: 'da-expulsions',
},
data: {
googleSpreadsheetKey: '1Nx8zcIi0ULxytLmra0A9N11-llzJCDVH2-7SbK_k5-U',
startColumn: 0,
startRow: 0,
googleSpreadsheetWorksheet: 19,
},
title: {
text: 'Expulsion rates at campuses with highest expulsion rates over time'
},
yAxis: {
min: 0,
max: 30,
breaks: [{
from: 12,
to: 24,
breakSize: 1
}],
tickInterval: 3,
title: {
text: 'Expulsions Rate (%)'
},
labels: {
formatter: function() {
return this.value + '%';
}
}
},
tooltip: {
valueSuffix: '%'
},
xAxis: {
type: 'category',
title: {
text: 'School'
},
},
});
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/data.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/4.1.5/modules/broken-axis.js">
</script>
</head>
<body>
<div id="da-expulsions"></div>
</body>
The "make the div height of the chart an absurd size" is why the truncated view was added. If you hover over the xAxis labels the full text is shown.
If you want to increase the available size for the xAxis labels you can. Another recommendation would be to use a 'bar' format where the xAxis is vertical and then adjust font sizing of the xAxis label although this is not 100% accurate. What is wrong with the ellipsis?
labels: {
useHTML: true,
style: {
fontSize: '8px',
width: '300px'
}
}
I want to draw multiple line for this type of graph of your library : http://www.highcharts.com/stock/demo/basic-line
I found this sample on internet: http://jsfiddle.net/yildirim_timur/Hb3Q7/
Below you can see my html file. I tried to do couple of things but couldn't make it. How can i make my chart to be able to draw multiple lines as well? (it is for an ipad app project)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Senior Project Timur Aykut YILDIRIM - IH Technology</title>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
<link rel="stylesheet" type="text/css" href="/Users/ihtechnology/Desktop/chart_deneme/css/normalize.css">
<link rel="stylesheet" type="text/css" href="/Users/ihtechnology/Desktop/chart_deneme/css/result-light.css">
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet"/>
<script type='text/javascript'>
var serviceDataURL = "http://xx.xx.xxx.xxx:83/get_item_data_ios?generic=";
function setDictionary(x){
return x;
} // no need for this method
var dict = "web service query string will be here";
$(function() {
$.getJSON(serviceDataURL.concat(dict), function(data) {
// Create the chart
window.chart = new Highcharts.StockChart({
chart : {
renderTo : 'container'
},
navigation: {
buttonOptions: {
enabled: false,
width: 60
}
},
rangeSelector : {
buttonSpacing: 20,
buttonTheme: { // styles for Q,Y,YTD,ALL buttons
fill: 'none',
stroke: 'none',
'stroke-width': 15,
style: {
color: '#039',
fontWeight: 'bold'
},
states: {
hover: {},
select: {
fill: '#039',
style: {
color: 'white'
}
}
}
},
selected : 3, // 3=ALL buton at first
inputDateFormat: '%Y-%m-%d',
inputEditDateFormat: '%Y-%m-%d',
buttons:[
{
type: 'month',
count: 3,
text: 'QQ'
},
{
type: 'year',
count: 1,
text: 'YY'
},
{
type: 'ytd',
text: 'YTD'
},
{
type: 'all',
text: 'ALL'
},
]
},
title : {
text : 'My Total Market'
},
credits: {
text: " ",
href: " ",
},
series : [{
name : 'Total Market',
data : arr,
tooltip: {
valueDecimals: 2
}
}],
exporting: {
enabled: false
}
}, function(chart){
// apply the date pickers
setTimeout(function(){
$('input.highcharts-range-selector').attr('readonly',1); // burda webviewı engelledik
$('input.highcharts-range-selector', $('#'+chart.options.chart.renderTo))
},0)
});
});
});
//]]>
</script>
</head>
<body>
<div id="container" style="height: 500px; min-width: 500px;"></div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>
</body>
</html>
Right now you have:
series : [{
name : 'Total Market',
data : arr,
tooltip: {
valueDecimals: 2
}
}]
So you have just one object inside series. If you want multiple series then should be something like that:
series : [{
name : 'Total Market I',
data : arr_1,
tooltip: {
valueDecimals: 2
}
},{
name : 'Total Market II',
data : arr_2,
tooltip: {
valueDecimals: 2
}
}]
Edit:
To add multiple series, push them to array:
var mySeries = [];
mySeries.push({
name : 'Total Market I',
data : arr_1
});
mySeries.push({
name : 'Total Market II',
data : arr_2
});
mySeries.push({
name : 'Total Market III',
data : arr_3
});
Then create chart:
series: mySeries
I want to get the correct x axis label when user zooms the chart and click on a specific bar
when clicking on the bar on (02/14/14 - xaxis) the alert shows the (02/19/14 - xaxis) label.
It returns the correct date when the zoom(selection) is not firing. but after zooming the chart and clicking on the bar it populate a wrong date.
I am new to flot charts. please help me. thanks.
[<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Stack Zoom Click</title>
<link href="style.css" rel="stylesheet" type="text/css">
<link href="plot.css" rel="stylesheet" type="text/css">
<link href="master.css" rel="stylesheet" type="text/css">
<!--\[if lte IE 8\]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><!\[endif\]-->
<script language="javascript" type="text/javascript" src="jquery.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.valuelabels.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.stack.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.selection.js"></script>
<script type="text/javascript">
$(function() {
var dataset = \[{
data: \[
\[1391279400000, -588\],\[1391365800000, -1324\],\[1391452200000, -1525\],\[1391538600000, -588\],\[1391625000000, -1525\],\[1391711400000, -588\],
\[1391797800000, -1324\],\[1391884200000, -1525\],\[1391970600000, -588\],\[1392057000000, -1234\],\[1392143400000, -588\],\[1392229800000, -1324\],
\[1392316200000, -1525\],\[1392402600000, -588\],\[1392489000000, -1525\],\[1392575400000, -588\],\[1392661800000, -1324\],\[1392748200000, -1525\],
\[1392834600000, -588\]
\],
color:'#9D538E',
label: "Out"
},
{
data: \[
\[1391279400000, 3221\],\[1391365800000, 2496\],\[1391452200000, 1050\],\[1391538600000, 3221\],\[1391625000000, 1050\],\[1391711400000, 3221\],
\[1391797800000, 2496\],\[1391884200000, 1050\],\[1391970600000, 2221\],\[1392057000000, 1050\],\[1392143400000, 3221\],\[1392229800000, 2496\],
\[1392316200000, 1050\],\[1392402600000, 3221\],\[1392489000000, 1050\],\[1392575400000, 3221\],\[1392661800000, 2496\],\[1392748200000, 1050\],
\[1392834600000, 2221\]
\],
color:'#702BD7',
label: "Intake"
}, {
data: \[
\[1391279400000, 1000\],\[1391365800000, -1000\],\[1391452200000, -475\],\[1391538600000, 1000\],\[1391625000000, -475\],\[1391711400000, 1000\],
\[1391797800000, -1000\],\[1391884200000, -475\],\[1391970600000, 1000\],\[1392057000000, -475\],\[1392143400000, 1000\],\[1392229800000, -1000\],
\[1392316200000, -475\],\[1392402600000, 1000\],\[1392489000000, -475\],\[1392575400000, 1000\],\[1392661800000, -1000\],\[1392748200000, -475\],
\[1392834600000, 1000\]
\],
color:'#2082F2',
label: "Net"
}\];
var plot = $.plot("#placeholder", dataset, {
xaxis: {
mode: 'time',
timeformat: "%m/%d/%y",
tickSize: \[1, "day"\],
},
series: {
bars: {
fill: 1,
show: true,
barWidth: 100*100*4000,
},
valueLabels: {
show: true,
showAsHtml: true,
},
},
grid: {
hoverable: true,
clickable: true,
borderWidth: 2,
markings: \[ { yaxis: { from: 0, to: 0 }, color: "#fff" }\],
backgroundColor: { colors: \["#000000", "#000000"\] }
}
});
var overview = $.plot("#overview", dataset, {
xaxis: {
mode: 'time',
ticks: \[\]
},
yaxis: {
ticks: \[\],
},
series: {
bars: {
fill: 1,
show: true,
},
},
grid: {
markings: \[ { yaxis: { from: 0, to: 0 }, color: "#fff" }\],
backgroundColor: { colors: \["#000000", "#000000"\] }
},
selection: {
mode: "x"
},
legend: {show: false}
});
// now connect the two
$("#placeholder").bind("plotselected", function (event, ranges) {
//Reset Chart resolution dropdown
$(".chartResolution").val("0");
// do the zooming
plot = $.plot("#placeholder", dataset, {
xaxis: {
mode: 'time',
min: ranges.xaxis.from,
max: ranges.xaxis.to,
},
series: {
bars: {
fill: 1,
show: true,
barWidth: 100*100*4000,
},
valueLabels: {
show: true,
showAsHtml: true,
},
},
grid: {
hoverable: true,
clickable: true,
borderWidth: 2,
markings: \[ { yaxis: { from: 0, to: 0 }, color: "#fff" }\],
backgroundColor: { colors: \["#000000", "#000000"\] }
}
});
// don't fire event on the overview to prevent eternal loop
//overview.setSelection(ranges, true);
});
//bind the plotselected function
$("#overview").bind("plotselected", function (event, ranges) {
plot.setSelection(ranges);
});
$("#placeholder").bind("plotclick", function (event, pos, item) {
if (item) {
var tickClicked = item.series.xaxis.ticks\[item.dataIndex+1\].label;
alert(tickClicked);
}
});
});
</script>
</head>
<body style="background-color:#222222; color:white;">
<div id="content">
<div class="demo-container" style="margin-top:1%;">
<div id="placeholder" class="demo-placeholder"></div>
<p class="notifyMessage">Please click and drag and select a range to zoom Revert to all data</p>
<div id="overview" class="psycho" style="width:950px;height:150px;"></div>
</div>
</div>
</body>
</html>][1]
The problem is this line of code:
var tickClicked = item.series.xaxis.ticks[item.dataIndex+1].label;
When your plot is unzoomed you have one tick per datapoint (bar). When you zoom, however, you end up with in between ticks, so the finding a tick by item.dataIndex isn't going to work.
I'm guessing you care more about the data associated to the bar (and not really the tick) so get the bar x value and format it back to a date string.
var tickClicked = $.plot.formatDate(new Date(item.datapoint[0]),"%m/%d/%Y");
EDITS
Instead of making another .plot call on zoom redraw the chart with (this is how I do it in my applications using flot):
var opts = plot.getOptions();
opts.xaxes[0].min = ranges.xaxis.from;
opts.xaxes[0].max = ranges.xaxis.to;
opts.yaxes[0].min = ranges.yaxis.from;
opts.yaxes[0].max = ranges.yaxis.to;
plot.setupGrid();
plot.draw();