All series data are equal highcharts - javascript

I have function for updating sensors. Idea is simple, i add new points from sensors (1 sensor = 1 line) and after appending I update charts. But something went wrong and all series equal to themself
seriesArr - just array of sensors like {"sensorId1", sensorId2 etc}
chartObj - object of charts like chart 1: { chart: highcharts,
seriesArr: seriesArr }
Simple explanations:
chartObject.chart.series[0].points = chartObject.chart.series[1].points = chartObject.chart.series[2].points = etc
My code:
updateAllCharts: function() {
var allCharts = this.charts;
console.log('charts');
for (var chart in allCharts) {
var chartObject = allCharts[chart];
for (var i = 0; i < chartObject.seriesArr.length; i++) {
var elemId = chartObject.seriesArr[i][0];
var val = this.sensors[elemId].get('value');
console.log(val);
if (val === undefined) { // if sensor cant get data
continue;
}
var now = new Date;
var x = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),
now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds());
var y = parseFloat(val);
chartObject.chart.series[i].addPoint([x, y], false, false);
console.log(x, y);
console.log(chartObject.chart.series[i].data);
}
}
for (var chart in allCharts) {
var chartObject = allCharts[chart];
chartObject.chart.redraw();
}
}
Screen:
UPDATE:
ProcessedDataX and Y arrays are changing, but there problem with points array, I always get some weird (maybe cached) points. WTF.
Playground
If you wanna play, i've setted up here jsfiddle, but actually it probably doesn't work. Can't add points to highchart object with setInterval.
JSFIDDLE
UPDATE2:
Actually it works fine in jsfiddle but i don't know wtf is going on in my project.
UPDATE3:
Found, that the same last point adds to each series. For example, series[i].lastPoints = series[n] , where n = last iteration.

Works, only if i REDRAW EVERYTIME AFTER ADDING EACH POINT. so bad solution, so bad.
just put true in parameter after Point object
chartObject.chart.series[z].addPoint(Point, true, false);

To all chart.redraw() you need to set isDirty flag
so try to use this code:
for (var chart in allCharts) {
var chartObject = allCharts[chart];
chartObject.yAxis[0].isDirty = true;
chartObject.chart.redraw();
}

Related

Chart.js : sparser clickable data points

I've got a chart.js line chart, with 128 datapoints.
Currently, it uses the solution here for drag and drop verticals.
But it's a hassle. I'd like to limit the clickable / editable points to 30 or so.
(Then ideally it would do some smart interpolation of the surrounding values.)
Any ideas how to achieve this?
function move_handler(event)
{
// locate grabbed point in chart data
if (activePoint != null) {
var data = activePoint._chart.data;
var datasetIndex = activePoint._datasetIndex;
// read mouse position
const helpers = Chart.helpers;
var position = helpers.getRelativePosition(event, myChart);
// convert mouse position to chart y axis value
var chartArea = window.myChart.chartArea;
var yAxis = window.myChart.scales["y-axis-0"];
var yValue = map(position.y, chartArea.bottom, chartArea.top, yAxis.min, yAxis.max);
// update y value of active data point
data.datasets[datasetIndex].data[activePoint._index] = yValue;
// try {
// for (let i = -5;i < 5;i++){
// data.datasets[datasetIndex].data[activePoint._index + i] = yValue;
// }
// }
// catch (err) {}
window.myChart.update();
};
};
I found Smooth.js which did the trick

how to pass big data to google scatter chart

I am relatively new to JavaScript and Django and I am struggling with passing big data to my google chart.
I have a chart representing velocities for a given date and distance. In my django views I create list of distances, dates and according velocities. I also generate there a list with sorted values occuring in velocity list and a list with colors according to velocity's value.
I want to have a chart with velocity map with applied colortable like this :
http://i.imgur.com/9Tyv8Rn.jpg
So I used scatter chart with velocity series. The chart is dynamic, it's diffrent for every item selected by a user.
JS to generate rows and columns :
// Define data table rows:
var rows = [];
var rows_list = [];
var vl_max = vel_list.length;
for (i=0; i < vl_max; i+=1) {
var date_tmp = new Date(date_list[i].split(',')[0],date_list[i].split(',')[1]-1,date_list[i].split(',')[2]);
var date = [date_tmp];
var vel_tmp = vel_list[i];
var vtemp_max = vel_tmp.length;
var tooltip_dsname = dsname_list[i];
var tooltip_track = track_list[i];
for (j=0; j < vtemp_max; j+=1) {
var cell = [{v : date_tmp}];
for (k=0; k < vr_max; k+=1) {
var vel_full = vel_tmp[j];
var vel = vel_full.toFixed(1);
if (vel == vel_range[k]) {
// tooltip:
var dist = dist_list[j]/1000;
var yyyy = date_tmp.getFullYear().toString();
var mm = (date_tmp.getMonth()+1).toString(); // getMonth() is zero-based
var dd = date_tmp.getDate().toString();
var tooltip_date = yyyy + "-" + (mm[1]?mm:"0"+mm[0]) + "-" + (dd[1]?dd:"0"+dd[0]);
var tooltip = "<b>dataset: </b>"+tooltip_dsname+"<br><b>date: </b>"+tooltip_date+"<br><b>track: </b>"+tooltip_track+"<br><b>distance: </b>"+dist+" k"+mapunit+"<br><b> velocity: </b>"+vel_full.toFixed(2)+" m/d";
var color = color_list[k]
var style = "point { shape-type: square; fill-color: "+color+";}"
} else {
var dist = NaN;
var tooltip = "empty" ;
var style = "empty" ;
}
cell.push({v: dist},{v: tooltip},{v:style});
}
rows_list.push({c: cell});
}
};
Here is JSfiddle for chart generation with smaller data :
http://jsfiddle.net/joannao89/t26ooyrt/2/
The problem that I have is while the chart is working for smaller data, once I want to load it for a long distance and a wide date range, the browser keeps on popping us this line : "A website is slowing down your browser, what would you like to do ? {stop} {wait}"
I know that this is probably the problem of too large amount of rows, my website generates also 3 other charts like this, with the same data but in another X-Y axis combination (for example time on X-axis, velocity on Y-axis and distance as series) and it works perfectly fine. That's why I would like to pass the data to the chart in some faster way, but I have no clue how.
I already tried to use setTimeout, but it doesn't change a lot. I also tried doing a little less coding on JS side and more in django views, but it also didn't help.
So any suggestions about how to solve this will be very appreciated!

flot multiple line graph animation

I have multiple series on a graph and would like to animate them but it is not working. I am using flot and animator plugin.
https://jsfiddle.net/shorif2000/L0vtrgc2/
var datasets = [{"label":"IT","curvedLines":{"apply":true},"animator":{"start":0,"steps":7,"duration":3000,"direction":"right"},"idx":0,"data":[{"0":1433156400000,"1":"095.07"},{"0":1435748400000,"1":"097.80"},{"0":1438426800000,"1":"096.72"},{"0":1441105200000,"1":"097.62"},{"0":1443697200000,"1":"097.68"},{"0":1446379200000,"1":"098.49"},{"0":1448971200000,"1":"098.59"},{"0":1451649600000,"1":"098.69"}]},{"label":"Network","curvedLines":{"apply":true},"animator":{"start":0,"steps":7,"duration":3000,"direction":"right"},"idx":1,"data":[{"0":1433156400000,"1":"095.07"},{"0":1435748400000,"1":"097.80"},{"0":1438426800000,"1":"096.72"},{"0":1441105200000,"1":"097.62"},{"0":1443697200000,"1":"097.68"},{"0":1446379200000,"1":"098.49"},{"0":1448971200000,"1":"098.59"},{"0":1451649600000,"1":"098.69"}]},{"label":"Success Rate","curvedLines":{"apply":true},"animator":{"start":0,"steps":7,"duration":3000,"direction":"right"},"idx":2,"data":[[1433156400000,98.58],[1433156400000,null],[1433156400000,95.18],[1433156400000,null],[1435748400000,null],[1438426800000,null],[1441105200000,null],[1443697200000,null],[1446379200000,null],[1448971200000,null],[1451649600000,null]]}];
var options = {"series":{"lines":{"show":true},"curvedLines":{"active":true}},"xaxis":{"mode":"time","tickSize":[1,"month"],"timeformat":"%b %y"},"grid":{"clickable":true,"hoverable":true},"legend":{"noColumns":3,"show":true}};
$.plotAnimator($('#CAGraph'), datasets, options);
Problem I have is when I add curved lines it does not work. https://github.com/MichaelZinsmaier/CurvedLines
Without curvedLines plugin (like in the fiddle in your question):
1) If you have multiple data series and use animator, it will only animate the last series. All other series are drawn instantly. (You can see this in your fiddle when you comment out the third data series.)
2) Your last data series has only two points at the same date, so there is nothing to animate (this leads also to problems with the curvedLines plugin for this series).
To animate multiple data series one by one see this answer to another question.
With curvedLines plugin:
3) The curvedLines plugin doesn't work together with the animator plugin (probably because the animator plugin generates a new partial data series for each step). But we can work around this issue with these steps:
a) plot a curvedLines chart without animator,
b) read the data points from this chart and replace the original data,
c) change the options (deactivate curvedLines since the new data is already curved and adjust the step count to the new data),
d) plot the animated chart with the new data.
See this fiddle for a working example with one data series. Relevant code:
var plot = $.plot($('#CAGraph'), datasets, options);
var newData = plot.getData()[0].datapoints.points;
datasets[0].data = [];
for (var i = 0; i < newData.length; i = i+2) {
datasets[0].data.push([newData[i], newData[i+1]]);
}
datasets[0].animator.steps = (newData.length / 2) - 1;
options.series.curvedLines.active = false;
var ani = $.plotAnimator($('#CAGraph'), datasets, options);
Full solution:
Combining the two parts above we get a fiddle which animates two curved lines one by one (the third data series is left out because of the issues mentioned under 2)). Relevant code:
var chartcount = datasets.length;
var chartsdone = 0;
var plot = $.plot($('#CAGraph'), datasets, options);
for (var i = 0; i < chartcount; i++) {
var newData = plot.getData()[i].datapoints.points;
datasets[i].data = [];
for (var j = 0; j < newData.length; j = j + 2) {
datasets[i].data.push([newData[j], newData[j + 1]]);
}
datasets[i].animator.steps = (newData.length / 2) - 1;
}
options.series.curvedLines.active = false;
var ani = $.plotAnimator($('#CAGraph'), [datasets[0]], options);
$("#CAGraph ").on("animatorComplete", function() {
chartsdone++;
if (chartsdone < chartcount) {
ani = $.plotAnimator($('#CAGraph'), datasets.slice(0, chartsdone + 1), options);
}
});

What javascript library is best for plotting line chart with many series having low amount of points each

I need to plot 60 (more in the future) series of 25 points on a single plot onto the HTML page. Whole plot should be zoomable and filterable (user should be able to i. e. hide all series except the one selected or to hide only one series selected).
Somebody knows the javascript chart library which best suited for such a task? Current implementation works on Highcharts and it chokes on "hide all series except one selected" feature.
Maybe I can just stick with Highcharts, but I really need a way to quickly hide all series except the one clicked on.
UPDATE:
Okay, guys, I found the acceptable solution myself.
Try amCharts.com
Here is JS fiddle with your scenario implemented: jsfiddle.net/zeroin/gqtmN/
Clicking on legend entry hides all graphs and shows the one you clicked.
And the source code, as SO requested:
var chart;
var chart;
var chartData = [];
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 60);
for (var i = 0; i < 25; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var obj = {
date: newDate
};
for (var j = 0; j < 60; j++) {
obj["val" + j] = Math.round(Math.random() * (j + 1) * 10);
}
chartData.push(obj);
}
}
AmCharts.ready(function() {
generateChartData();
chart = new AmCharts.AmSerialChart();
chart.marginTop = 0;
chart.autoMarginOffset = 5;
chart.pathToImages = "http://www.amcharts.com/lib/images/";
chart.zoomOutButton = {
backgroundColor: '#000000',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData;
chart.categoryField = "date";
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "DD"; // our data is daily, so we set minPeriod to DD
categoryAxis.dashLength = 2;
categoryAxis.gridAlpha = 0.15;
categoryAxis.axisColor = "#DADADA";
for (var j = 0; j < 60; j++) {
var graph = new AmCharts.AmGraph();
graph.title = "series " + j;
graph.valueField = "val" + j;
graph.hidden = true;
chart.addGraph(graph);
}
chart.graphs[0].hidden = false;
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = "mouse";
chart.addChartCursor(chartCursor);
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
var legend = new AmCharts.AmLegend();
legend.addListener("showItem", handleAll);
chart.addLegend(legend);
chart.write("chartdiv");
});
function handleAll(event) {
for (var j = 0; j < 60; j++) {
chart.graphs[j].hidden = true;
}
event.dataItem.hidden = false;
chart.validateNow();
}​
Disclaimer: I am author of amCharts.
Check out Rickshaw.
Seems pretty nice for graphs. May be able to get it to do what you want?
If not, maybe try Raphaël JS Also pretty nice for graphs, and there is the extension gRaphaël for graphs as well.
Perhaps one of those may do what you're after :)
Edit
I'd also throw Flot into the mix as well. I've just used it in a project and it works pretty damn well with large datasets and it's pretty flexible and expandable. Worth looking in to
teechart HTML5 Charting Javascript allows hidding series setting their "visible" property to false. You can use the series onclick event to hide all the other series except the clicked one, for example:
Chart1.series.each(function(series) { series.onclick=clickedSeries; });
function clickedSeries(series, point) {
Chart1.series.each(function(s) { s.visible = (s === series) });
Chart1.draw();
}
There's a full online demo here:
http://www.steema.com/files/public/teechart/html5/v2012.12.14.1.4/demos/
regards
david berneda
www.teechart.com
Well, sorry, I've upvoted all of your answers but I was fully content with my own solution.
Disabling the auto-updating of scale on Highcharts made the needed increase in perfomance:
new Highcharts.Charts({
chart: {
ignoreHiddenSeries: false,
reflow: false
}
});
This way hiding/showing the series work acceptable. It's just that all other functions of Highcharts completely satisfy me.
The mass hiding/showing of series itself is not so important, I was interested only in increase of perfomance.

jqplot--how to have 2 lines with very different values to scale for good values in one chart?

i'm using jqplot to draw charts, in one chart it will have 2 line series, but the values are quite different, one is about 2000, and the other might be more than 1,000,000,
how can i specify it to have 2 lines with 2 y axis in a way that can be displayed in one chart fine?
currently i just saw one line that's just a plain line in the bottom? my codes are something like below
$.ajax({url: myurl,
success:function(json){
$.jqplot.config.enablePlugins = true;
var data = eval(json);
var ssList = data[0];
var sdList = data[1];
var dataOption = [ssList];
if(sdList.length > 0){
dataOption[1] = sdList;
}
var seriesOption = {lineWidth:2, markerOptions:{style:'square'}};
if(sdList.length > 0){
seriesOption[1] = {renderer:$.jqplot.OHLCRenderer, rendererOptions:{candleStick:true}};
}
var axisOption ={};
axisOption.xaxis = {
renderer:$.jqplot.DateAxisRenderer,
tickOptions:{formatString:'%Y-%m-%d'}
};
axisOption.yaxis = {autoscale:true,label: "time"};
if(sdList.length > 0){
axisOption.y2axis = {autoscale:true,label: "index"};
}
var plot2 = $.jqplot('chart2', dataOption, {
title:'水木社区股票版人气指数',
axes:axisOption,
series:seriesOption,
highlighter:{
showMarker:false,
tooltipAxes: 'xy',
yvalues: 1,
formatString:'<table class="jqplot-highlighter"><tr><td>日期:%s</td></tr><tr><td>人气指数:%s</td></tr></table>'
}
});
}});
You can create plots with more 'y' axes. Second example here http://www.jqplot.com/tests/zooming.php
Don't use autoscale, try to set max and min values for each one and you will have your plot more readable.

Categories

Resources