I'm working on an application that will generate some charts and I'm using chartjs to draw them.
The issue I'm facing is this: the charts will be generated with dynamic data. The application may generate up to 9 datasets and rarely they will have the same size. How can I make chartjs advance or fill the values when the datasets size won't match?
I saw some examples here at stackoverflow and even at chartjs github page but they didn't work me.
This is an example of what I have so far: https://jsfiddle.net/camarrone/49onz8no/1/
Two datasets with different data array. The first value for the second dataset doesn't exist hence it should be zero or null. Like this: https://jsfiddle.net/camarrone/d39a0qgw/
This is "failing" code for reference:
<html>
<head>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js'></script>
</head>
<body>
<div style="width: 900px; height: 500px">
<canvas id="chart1"></canvas>
</div>
<script>
let chart1 = new Chart(document.getElementById("chart1"), {
type: 'line',
data: {
labels: ["2018-04-21T16:00:00", "2018-04-21T18:00:00", "2018-04-21T20:00:00", "2018-04-23T12:00:00", "2018-04-23T13:00:00"],
datasets: [
{
type: 'line',
fill: false,
label: 'Label_1',
borderColor:"hsl(181.40751321285697,45.9256727159548%,27.54659126333186%)",
data: [7,3,11,2,3]
},
{
type: 'line',
fill: false,
label: 'Label_2',
borderColor:"hsl(181.91996173600447,39.046658571489985%,65.63412032509264%)",
data: [1,6,1,2]
},
],
},
options: {
animation: {
duration: 0
},
title: {
display: false,
text: ''
},
legend: {
labels: {
useLineStyle: true
},
position: 'bottom',
},
}
});
</script>
</body>
</html>
For those facing the same issue and future reference. Here is the working code for my case:
<html>
<head>
<script type='text/javascript' src='./momentjs-with-locales.js'></script>
<script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js'></script>
</head>
<body>
<div style="width: 900px; height: 500px">
<canvas id="chart1"></canvas>
</div>
<script>
let chart1 = new Chart(document.getElementById("chart1"), {
type: 'line',
data: {
labels: ["2018-04-21T16:00:00", "2018-04-21T18:00:00", "2018-04-21T20:00:00", "2018-04-23T12:00:00", "2018-04-23T13:00:00"],
datasets: [
{
fill: false,
label: 'Page View',
borderColor: "hsl(226.15793242887034,78.48665583019744%,62.177112879909686%)",
data: [
{
labels: ["2018-04-21T16:00:00", "2018-04-21T18:00:00", "2018-04-21T20:00:00", "2018-04-23T12:00:00", "2018-04-23T13:00:00"],
},
{
x: new Date('2018-04-21T16:00:00'),
y: 7
},
{
x: new Date("2018-04-21T18:00:00"),
y: 3
},
{
x: new Date("2018-04-21T20:00:00"),
y: 11
},
{
x: new Date("2018-04-23T12:00:00"),
y: 2
},
{
x: new Date("2018-04-23T13:00:00"),
y: 3
}
],
},
//dataset 2
{
fill: false,
label: 'View Content',
borderColor: "hsl(232.84952363040048,93.45575469963681%,28.844243872178236%)",
data: [
{
labels: ["2018-04-21T17:00:00", "2018-04-21T20:00:00", "2018-04-23T12:00:00", "2018-04-23T13:00:00"],
},
{
x: new Date("2018-04-21T17:00:00"),
y: 1
},
{
x: new Date("2018-04-21T20:00:00"),
y: 6
},
{
x: new Date("2018-04-23T12:00:00"),
y: 1
},
{
x: new Date("2018-04-23T13:00:00"),
y: 2
}
],
},
],
},
options: {
animation: {
duration: 0
},
title: {
display: false,
text: ''
},
legend: {
labels: {
useLineStyle: true
},
position: 'bottom',
},
scales: {
xAxes: [
{
type:'time',
distribution: 'series',
time: {
unit: 'day',
displayFormat: {
day: 'DD/MM/YYYY'
}
},
}
],
yAxes: [
{
ticks: {
beginAtZero: true,
},
}
]
}
}
});
</script>
</body>
</html>
DEMO online:
I am not using x/y formatted datasets, so I kept looking. I ended up finding that inserting 'null' values solved my problem--the arrays can then be the same length, and not have drops to zero polluting the shapes.
However, note that this seems to not work with log scales on line graphs. Luckily, the only graphs I use uneven-length datasets on is probably best presented in linear form, but it is irritating.
Note also that you may want to utilize the { spanGaps: false } option.
Related
I use a DrawChart method and try to set the logarithmic option to the yaxis to true without success:
The datas (for the series) contains :
"[{type:"bar",data:[1.19576304413727E-08,1.30322021618667E-07]}]"
I try to place the logarithmic : true option in several place without succes. For me it must be placed into the yaxis part.
Thank you in advance
chart.updateOptions({
series: datas,
chart: {
toolbar: {
show: showToolbar
},
animations: {
enabled: false
},
type: 'bar'
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '50%',
endingShape: 'rounded'
}
},
stroke: {
show: true,
width: 2,
colors: ['transparent']
},
xaxis: {
title: {
text: 'Masse'
},
categories: categories//,
//tickAmount: 10
},
yaxis: {
labels: {
formatter: function (value) {
//var ex;
return value.toExponential();
//return value;
}
},
title: {
text: unit
},
tickAmount: 10
//min: min,
//max: max,
//decimalsInFloat: 3
},
grid: {
padding: {
left: 50,
right: 50
}
},
legend: {
show: true,
position: 'bottom',
horizontalAlign: 'left',
showForSingleSeries: true,
showForNullSeries: true,
showForZeroSeries: true
},
})
I found the problem !
When you have log values really small (like 5.32E-9), the logarithm option doesnt work if you try to display the legend thrue a JS function.
So multiply by 1E10 the divide into the JS function (where you display the legend) by 1E10.
I am working on django project
I want to do a highchart dependency wheel but I don't know why the chart not showing , you will see my code below ,
in my dependencywheel.html I did already {%load static%} in the top ,
<script>
Highcharts.chart('container', {
title: {
text: 'Highcharts Dependency Wheel'
},
accessibility: {
point: {
valueDescriptionFormat: '{index}. From {point.exped} to {point.destin}: {point.count}.'
}
},
series: [{
keys: ['exped', 'destin', 'count'],
data: '{%url "data"%}',
type: 'dependencywheel',
name: 'Dependency wheel series',
dataLabels: {
color: '#333',
textPath: {
enabled: true,
attributes: {
dy: 5
}
},
distance: 10
},
size: '95%'
}]
});
</script>
that's my views.py
#login_required
def depend(request):
return render(request,'dependWheel.html',{})
def jsonDepend(request):
dataset = mail_item_countries_depend.objects.all().values_list('exped','destin','count')
data = list(dataset)
return JsonResponse(data, safe=False)
the chart is not showing , how can I load my data
that's the answer:
<script type="text/javascript">
$(function(){
$.getJSON('data',function(data){
Highcharts.chart('container', {
title: {
text: 'Highcharts Dependency Wheel'
},
accessibility: {
point: {
valueDescriptionFormat: '{index}. From {point.from} to {point.to}: {point.weight}.'
}
},
series: [{
keys: ['from', 'to', 'weight'],
data:data,
type: 'dependencywheel',
name: 'Dependency wheel series',
dataLabels: {
color: '#333',
textPath: {
enabled: true,
attributes: {
dy: 5
}
},
distance: 10
},
size: '95%'
}]
});
});
});
</script>
Hi I am using canvasjs for making a chart. It is very simple to make a particular chart but here is the problem I want to have two different charts such that a pie chart would be inside of a doughnut chart.
I am not able to make one other inside. I have used the
display : inline-block
for the two div id but no effect. Could someone please suggest me how we can make that happen.
This is my code-
<!DOCTYPE HTML>
<html>
<head>
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<link type='text/css' rel="stylesheet" href='style.css' />
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "My First Chart in CanvasJS"
},
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "doughnut",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
var chart = new CanvasJS.Chart("chartContainerpie", {
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
}
</script>
</head>
<body>
<div>
<div id="chartContainerpie" style="height: 300px; width: 100%;></div>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</div>
</body>
</html>
The CSS only contains the line for display block.
This is probably not the perfect answer but it will point you in right direction:
The idea is to change the background color of canvas to transparent and overlap the two canvas using position css
CSS
#chartContainerpie{
position: absolute;
top: 130px;
left: 0px;
}
#chartContainer{
position: absolute;
top: 0px;
left: 0px;
}
JS
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "My First Chart in CanvasJS"
},
backgroundColor: "transparent",
data: [{
// Change type to "doughnut", "line", "splineArea", etc.
type: "doughnut",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
var chart = new CanvasJS.Chart("chartContainerpie", {
backgroundColor: "transparent",
data: [{
// Change type to "doughnut", "line", "splineArea", etc.
indexLabelPlacement: "inside",
indexLabelFontColor: "white",
indexLabelFontSize: "14px",
type: "pie",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
Here is fiddle
I'm currently creating a system that produces different kind of graphs. I want to create a chart and table, that when a chart is DRILLDOWNED, the table will sync as well. Is there a way to output the current data presented by HighCharts to JSON? Then this JSON will be inputted into a datatable? Thanks!
check this JsFiddle Demo
You can obtain the id by e.seriesOptions.id which is the key to your data. Then you can use this id as the key to get appropriate data and update your data table from within the drillUp and drillDown events.
HTML
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
JS
$(function() {
// Create the chart
$('#container').highcharts({
chart: {
type: 'column',
events: {
drillup: function(e) {
//alert('drill Up');
console.log(this);
console.log(e.seriesOptions.id);
console.log(this.options.series[0].name);
console.log(this.options.series[0].data[0].name);
},
drilldown: function(e) {
//alert('drill Down');
console.log(this);
console.log(e.seriesOptions.id);
console.log(this.options.series[0].name);
console.log(this.options.series[0].data[0].name);
}
}
},
title: {
text: 'DrillUp button styling'
},
xAxis: {
type: 'category'
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Dieren',
y: 5,
drilldown: 'animals'
}, {
name: 'Fruit',
y: 2,
drilldown: 'fruits'
}, {
name: "Auto's",
y: 4
}]
}],
drilldown: {
drillUpButton: {
relativeTo: 'spacingBox',
position: {
y: 0,
x: 0
},
theme: {
fill: 'white',
'stroke-width': 1,
stroke: 'silver',
r: 0,
states: {
hover: {
fill: '#bada55'
},
select: {
stroke: '#039',
fill: '#bada55'
}
}
}
},
series: [{
id: 'animals',
data: [
['Katten', 4],
['Honden', 2],
['Koeien', 1],
['Schapen', 2],
['Varkens', 1]
]
}, {
id: 'fruits',
data: [
['Appels', 4],
['Sinaasappels', 2]
]
}]
}
})
});
I'm trying to update a highcharts highstock chart with live data from a json file on my server.
now I have a chart that gets its data from a json file (that I create with php that requests the data from my MySQL database) like so:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OKcoin Price LTCCNY</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$.getJSON('json/lastTradesOkcoinLTCCNY.json', function(data) {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector : {
selected : 1
},
title : {
text : 'OkCoin Price LTCCNY'
},
rangeSelector: {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'hour',
count: 6,
text: '6h'
}, {
type: 'hour',
count: 12,
text: '12h'
}, {
type: 'hour',
count: 24,
text: '24h'
}, {
type: 'day',
count: 3,
text: '3d'
}, {
type: 'day',
count: 7,
text: '7d'
}, {
type: 'all',
text: 'All'
}],
selected: 2
},
xAxis: {
gridLineWidth: 1,
title: {
enabled: true,
text: 'Time',
style: {
fontWeight: 'normal'
}
}
},
yAxis: [{
title: {
text: 'Price LTCCNY'
},
gridLineWidth: 1,
minorTickInterval: 'auto',
minorTickColor: '#FEFEFE',
labels: {
align: 'right'
}
}],
plotOptions: {
series: {
lineWidth: 1
}
},
tooltip: {
valueDecimals: 5,
valuePrefix: '$ '
},
series : [{
name : 'LTCCNY Price',
data : data,
dataGrouping : {
units : [
['minute',
[1, 5, 10, 15, 30]
], ['hour', // unit name
[1]
]
]
}
}]
});
});
});
</script>
</head>
<body>
<script src="../Highstock/js/highstock.js"></script>
<script src="../Highstock/js/modules/exporting.js"></script>
<div id="container" style="height: 500px; min-width: 500px"></div>
</body>
</html>
So far no problems, I get a chart from the json file. But of course it doesn't update if new data becomes available (only if I reload the page) .
What I want to do is after loading this chart, add live data to it as it becomes available.
something like this example, but instead of random data the chart will be updated with data from a (second) live updating json file on my webserver. The json file will be created by php (this part is working just fine) But I can't figure out how to add the data from the json file to the my existing highstock chart.
I also found
this this example on highcharts.com and that more or less does what I try to do, but I can't integrate the 'requestData' function into my existing chart.
So what I want to do is use the 'requestData' function from the second example with the high stock chart I already have. My second json file (with the live data) looks the same as in the second example (timestamp, price):
[1389022968000,173.3]
Can anyone help me a bit?
nevermind, I figured it out myself...
here's my solution:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OKCoin LTCCNY Price</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
var chart; // global
function requestData() {
$.ajax({
url: 'tickOkCoinLTCCNY.json',
success: function(point) {
var series = chart.series[0],
shift = series.data.length > 2; // shift if the series is longer than 20
// add the point
chart.series[0].addPoint(eval(point), true, shift);
// call it again after one second
setTimeout(requestData, 10000);
},
cache: false
});
}
$(function() {
$.getJSON('../okcoin/json/lastTradesOkcoinLTCCNY.json', function(data) {
// set the allowed units for data grouping
var groupingUnits = [[
'minute', // unit name
[1,5,15,30] // allowed multiples
], [
'hour',
[1, 2, 3, 4, 6]
]];
// create the chart
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
events: {
load: requestData
}
},
rangeSelector: {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'hour',
count: 6,
text: '6h'
}, {
type: 'hour',
count: 12,
text: '12h'
}, {
type: 'hour',
count: 24,
text: '24h'
}, {
type: 'day',
count: 3,
text: '3d'
}, {
type: 'day',
count: 7,
text: '7d'
}, {
type: 'all',
text: 'All'
}],
selected: 2
},
title: {
text: 'OKCoin LTCCNY Price'
},
xAxis: {
type: 'datetime',
gridLineWidth: 1,
title: {
enabled: true,
text: 'Time',
style: {
fontWeight: 'normal'
}
}
},
yAxis: [{
title: {
text: 'LTCCNY'
},
lineWidth: 2
}],
series: [{
name: 'LTCCNY',
data: data,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
</script>
</head>
<body>
<script src="../Highstock/js/highstock.js"></script>
<script src="../Highstock/js/modules/exporting.js"></script>
<div id="container" style="height: 500px; min-width: 500px"></div>
</body>
</html>