i have data comprised of both positive and negative values which are to be displayed in a chart. i
am trying to display data in such a way that data point of positive values is greater than that of negative values.
the following is my code
<html>
<head>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="demochart"></div>
<button id="update"> Update</button>
<script>
Highcharts.chart('demochart', {
chart: {
type: 'scatter'
},
xAxis: {
categories: [0, 10, 20, 30, 40, 50, 60, 70, 80]
},
series: [{
name: 'Temperature',
data: [15, 50, -56.5, -46.5, -22.1, -2.5, -27.7, -55.7, 76.5]
}]
},function(chart){
$('#update').click(function(){
var data = chart.series[0].data;
var new_array = [];
new_array = data;
console.log(new_array);
for(var i = 0; i < new_array.length; i++){
console.log("For: "+ new_array[i].y);
if(new_array[i].y > 0){
new_array[i].y = "{y:"+ new_array[i] +",marker: {radius: 10}}"
console.log("If: "+ new_array[i].y);
}else{
new_array[i].y = "{y:"+ new_array[i] +",marker: {radius: 4}}"
console.log("Else: "+ new_array[i].y);
}
}
chart.series[0].setData(new_array);
})
});
</script>
</body>
</html>
When i click the update button, the size of data point value radius has to be changed.
Can this scenario will work ?
You can simply use the update method for points that meet your condition and change marker options. For performance reasons, it is better to set redraw parameter to false and redraw the chart after loop to avoid redrawing on every iteration.
Highcharts.chart('container', {
...
}, function(chart) {
$('#update').click(function() {
var points = chart.series[0].points;
points.forEach(function(point) {
if (point.y > 0) {
point.update({
marker: {
radius: 10
}
}, false);
}
});
chart.redraw();
})
});
Live demo: http://jsfiddle.net/BlackLabel/jznums3L/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.Point#update
https://api.highcharts.com/class-reference/Highcharts.Chart#redraw
Related
I want to draw a multiline chart with a dataSet(multiple lists append in 1 list) where I know which one I will as X-axis and Y-axis.
let dataSet = [[1, 2, 3, 4], [10, 15, 13, 17], [16, 5, 11, 9]];
/**
X-axis = dataSet[0]
The remaining will be used as Y-axis*/
The example is taken from here. Where I have seen for plotting each line(here 2 times) variable is calling to set the data. In my case, Y-axis will appear near about 30 times and for each X-axis value will be the same. But I haven't found a dynamic solution where I can append the Y-axis value using a for loop or something like that. That means I want to call this data variable only 1 time and want to append all information of multi-chart there at instant.
I have added my approach here.
let dataSet = [[1, 2, 3, 4], [10, 15, 13, 17], [16, 5, 11, 9]];
function get_val (data){
let x = [];
for(let j = 1;j<data.length;j++)
{
x.push(data[j]);
}
//console.log("x: ",x);
return x;
}
var trace1 = {
x: dataSet[0],
y: get_val(dataSet), /* if write here get_val(dataSet)[0] then works fine*/
type: 'scatter'
};
/**
if you uncomment the following lines, result will be as like as the example of plotly JS
*/
/*
var trace2 = {
x: dataSet[0],
y: get_val(dataSet)[1],
type: 'scatter'
};
*/
var data = [trace1/*, trace2*/];
Plotly.newPlot('myDiv', data);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
So, I want to know is there any approach by following which I can add multiple time any axis within a single variable(here trace1).
I have understood(maybe) where was my lacking.
1/ At first I have realized that I have overlooked that the traces or datapoints of plotly is an array of objects.
2/ I have also tried to organize my data
I have given here the solution that I have done.
let dataSet = [[10, 20, 30, 40], [10, 15, -13, 17], [1-6, 5, 11, 20] ]
/** following function will take the data and return the dataTRace as per as plotly's requirements.*/
function make_trace({data, set_type = "scatter", set_mode = "lines"} = {}){
let dataPoint = [];
for(let i = 1; i<data.length; i++){
dataPoint.push({
x: data[0],
y: data[i],
mode: set_mode,
type: set_type,
name: 'y_' + i
});
}
return dataPoint;
}
/** following function will make the layout for the plot*/
function make_layout({given_title="the title is not provided",x_min=0,x_max=15,x_axis_title="x_axis", y_min=0,y_max=15, y_axis_title="y_axis"} = {})
{
let layout_object = {
title: {
text: given_title
},
showlegend: true,
xaxis: {
range: [x_min, x_max],
title: x_axis_title
},
yaxis: {
range: [y_min, y_max],
title: y_axis_title
},
};
return layout_object;
}
let fig_layout = make_layout({given_title:"x vs y1, y2 plot",
x_min: 10, x_max : 50, x_axis_title:"x",
y_min: -20, y_max: 20, y_axis_title : "y(1,2)"});
Plotly.newPlot('myDiv', make_trace({data : dataSet, set_type:"scatter", set_mode : "lines"}), fig_layout);
Plotly.newPlot('myDiv_1', make_trace({data : dataSet, set_type:"scatter", set_mode : "markers"}), fig_layout);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
<div id='myDiv_1'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
I have a simple gauge chart, but I wish to alter it dynamically, for instance, I would like to have the scale limits set based on data extracted from a database. how would I achieve this?
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<div id="chart-A" class="chart"></div>
var axismin = 10;
$(function(axismin,axismax) {
$('#chart-A').highcharts({
chart: {
type: 'gauge',
},
title: {
text: 'Gauge'
},
pane: {
startAngle: -150,
endAngle: 150,
},
// the value axis
yAxis: {
min: axismin,
max: 100,
},
series: [{
data: [1]
}]
},
// Add some life
function(chart) {
if (!chart.renderer.forExport) {
setInterval(function() {
var point = chart.series[0].points[0],
newVal,
inc = Math.round((Math.random() - 0.5) * 20);
newVal = point.y + inc;
if (newVal < 0 || newVal > 100) {
newVal = point.y - inc;
}
point.update(newVal);
}, 500);
}
});
});
jsfiddle
Suppose from database you call min and max values.
$(function() {
//suppose using php
var axismin = <?php echo $axismin ?>;
var axismax = <?php echo $axismax ?>;
function init(axismin, axismax) {
......
}
init(axismin, axismax); //call chart function with arguments
});
Fiddle demo
Highcharts provide some functions for altering already rendered chart. For updating yAxis.min and yAxis.max values you can use setExtremes or update.
API references:
https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes
https://api.highcharts.com/class-reference/Highcharts.Axis#update
I am trying to pass an Array as a variable, with Javascript, into a HighCharts graph. The points with their markers are displayed correcty, but there is NO spline connecting the dots (Data 2, Purple).
I tried on the same chart as well, to pass an Array directly with the values, and this time HighCharts is displaying the markers and the splines (Data 1, Red).
For both series, all the line parameters (lineWidth, dashStyle, color) are set up.
I tested it on IE11 and Chrome and FireFox, and the result is the same...
Below is the full code. If anybody already encountered this or, better !, have an idea on how to solve this (have both set of data displayed with markers AND line joining those markers), I would be very very interested ! Thanks a lot !!
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Chart</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var myData = new Array();
for (n=1;n<=10;n++)
{
myData[n]=Math.floor((Math.random() * 10) + 1);
}
var mySeries = [];
for (var i = 0; i < myData.length; i++){
mySeries.push([i,myData[i]]);
}
$('#container').highcharts({
title: {
text: 'Chart',
x: -20 //center
},
xAxis: {
opposite:true,
title: {text: 'Horizontal Axis'},
showFirstLabel: true,
showLastLabel: true,
min: 0, max: 12,
tickInterval: 1,
startOnTick: true,
endOnTick: true,
},
yAxis: {
title: {text: 'Vertical Axis - inverted'},
reversed: true,
showFirstLabel: true,
showLastLabel: true,
min: 0, max: 12,
tickInterval: 1,
startOnTick: true,
endOnTick: true,
},
tooltip: {
valueSuffix: 'Week'
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [
{name:'Data 1',data:[0,1,2,3,4,5,6,7,8,9,10],marker:{symbol:'circle'},lineWidth:1,dashStyle:'Solid',color:'#FF0000'},
{name:'Data 2',data:mySeries ,marker:{symbol:'circle'},lineWidth:1,dashStyle:'Solid',color:'#FF00FF'},
]
});
});
</script>
</head>
<body>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 1000px; height: 700px; margin: 0 auto"></div>
</body>
</html>
I believe Highcharts is silently failing to draw the spline because your first value of mySeries is undefined.
With myData you start off at n = 1, so myData[0] is still undefined after you run through your for loop. Then you start off mySeries with i = 0so that first undefined value is added to mySeries. If instead you either start i = 1 or change your myData for loop to i = 0 then it should work.
In other words, do this:
var myData = new Array();
for (var n=0; n<10; n++){
myData[n]=Math.floor((Math.random() * 10) + 1);
}
var mySeries = [];
for (var i = 0; i < myData.length; i++){
mySeries.push([i,myData[i]]);
}
That said, I would condense your data generation to one for loop for efficiency reasons which would also remove the problem:
//define an empty array
var mySeries = [];
for (var i = 0; i < 10; i++){
//create your value
var d = Math.floor((Math.random() * 10) + 1);
//push an array into your array
mySeries.push([i,d]);
}
I have this code I have made out of a composition of my own code and the template code of Canvasjs which uses API of Canvasjs to make the chart.
Everything is good, I debugged it nicely and the chart shows with my database data as a source. My database data reads the data from a textfile which has data from a Arduino-based Pulse Sensor.
This is my code:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"> </script>
<script type="text/javascript">
$().ready(function () {
var dataPoints = [];
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
function updateChart( result ) { // move it here!!!
$.getJSON("arduino_data.php", function( result ){
var dataLength = 40; // number of dataPoints visible at any point
var updateInterval = 20;
var chart = new CanvasJS.Chart("chartContainer",{ // new chart Object
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
}
if (dataPoints.length > dataLength){
dataPoints.shift();
}
chart.render();
});
}
// First read - Start
updateChart();
// Update chart after specified time.
setInterval(updateChart, updateInterval);
});
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width:100%;">
</div>
</body>
</html>
Why do dataLength = 40; and updateInterval=20 and the last line: updateChart();
do not work? Should there be something in updateChart() like updateChart(dataPoints) ??
Why is my chart not live, though I have the right code parts?
EDIT
This is the template code that works without database data. And this is a Live Chart. It updates every second or so.
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"> </script>
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer2",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
As you can see, it is just like my code. However this uses math.randomize data instead of real data from database.
My Question: Why won't my chart keep updating (live) so it will show changes? My chart remains static. I have to refresh it manually to show new data transmission.
I want to draw a marker on the last point. Data source is dynamic.
Have a look at following code
$(function() {
$("#btn").click(function() {
var l = chart.series[0].points.length;
var p = chart.series[0].points[l - 1];
p.marker = {
symbol: 'square',
fillColor: "#A0F",
lineColor: "A0F0",
radius: 5
};
a = 1;
chart.series[0].points[l - 1] = p;
chart.redraw(false);
});
var ix = 13;
var a = 0;
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
events: {
load: function() {
var series = this.series[0];
setInterval(function() {
ix++;
var vv = 500 + Math.round(Math.random() * 40);
chart.series[0].data[0].remove();
var v;
if (a == 1) v = {
y: vv,
x: ix,
marker: {
symbol: 'square',
fillColor: "#A0F",
lineColor: "A0F0",
radius: 5
}
}
else v = {
y: vv,
x: ix
}
a = 0;
series.addPoint(v);
}, 1500);
}
}
},
plotOptions: {
series: {}
},
series: [{
data: [500, 510, 540, 537, 510, 540, 537, 500, 510, 540, 537, 510, 540, 537]}]
});
});
http://jsfiddle.net/9zNUP/
On button click event I am trying to draw marker on last point which is already added to chart.
Is there a way to do that??
$("#btn").click(function() {
var l = chart.series[0].points.length;
var p = chart.series[0].points[l - 1];
p.update({
marker: {
symbol: 'square',
fillColor: "#A0F",
lineColor: "A0F0",
radius: 5
}
});
a = 1;
});
solution # http://jsfiddle.net/jugal/zJZSx/
Also tidied up your code a little, removed the removal of point before adding one at the end, highcharts supports it inbuilt with the third param to addPoint as true, which denotes shift series, which removes first point and then adds the given point.
I didn't really understand what the a vv etc were, but well i didn't bother much either. I think this is enough based on what you asked for.