Highcharts redraw previous line still exist - javascript

I'm using Highstock to draw curve,There is a dropdown list in my page,when I select one of them,it will display corresponding curve.Default it will display default value's curve,but when I select another one,it will display the newer curve ,but previous curve line still exist.Why?Here is my code:
<script type="text/javascript" src='#Url.Content("~/Scripts/jquery-1.6.min.js")'></script>
<script src='#Url.Content("~/Scripts/highstock.js")' type="text/javascript"></script>
<script src='#Url.Content("~/Scripts/exporting.js")'type="text/javascript"></script>
<div id="T">
</div>
<script type="text/javascript">
var T_chart;
var T_options;
var T1_data = [];
var T2_data = [];
$(document).ready(function () {
draw_chart();
$('#search').click(function () {
redraw_chart();
});
Highcharts.setOptions({
lang: {
rangeSelectorFrom: 'From',
rangeSelectorTo: 'To',
rangeSelectorZoom:'Range'
},
global: {
useUTC: false
}
});
});
T_options = {
chart: {
renderTo: 'T',
type: 'spline'
},
navigator:{
enabled:false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'day',
text: 'Day'
}, {
count: 1,
type: 'week',
text: 'Week'
}, {
count: 1,
type: 'month',
text: 'Month'
}, {
count: 1,
type: 'year',
text: 'Year'
}, {
type: 'all',
text: 'All'
}],
selected: 0
},
title: {
text: 'Temperature Chart'
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
yAxis: {
labels: {
x: -10,
y: 0
}
},
series: []
};
function draw_chart() {
storenum = $(".StoreNum").val();
$.getJSON("HisGraData", { storenum: storenum }, function (data) {
$.each(data, function (index, item) {
//Date Format
var date = new Date(parseInt((item.Time).replace("/Date(", "").replace(")/", "").split("+")[0]));
T1_data.push([Date.parse(date.toString()), item.T1]);
T2_data.push([Date.parse(date.toString()), item.T2]);
});
T_options.series.push({ name: 'T1', data: T1_data });
T_options.series.push({ name: 'T2', data: T2_data });
T_chart = new Highcharts.StockChart(T_options);
});
}
function redraw_chart() {
storenum = $(".StoreNum").val(); //dropdown list ,select one
while (T_chart.series.length > 0)
T_chart.series[0].remove();
T1_data = [];
T2_data = [];
$.getJSON("HisGraData", { storenum: storenum }, function (data) {
$.each(data, function (index, item) {
//DateFormat
var date = new Date(parseInt((item.Time).replace("/Date(", "").replace(")/", "").split("+")[0]));
T1_data.push([Date.parse(date.toString()), item.T1]);
T2_data.push([Date.parse(date.toString()), item.T2]);
});
T_chart.addSeries({ name: 'T1', data: T1_data });
T_chart.addSeries({ name: 'T2', data: T2_data });
T_chart.redraw();
});
}
Here is my capture:

I suspect your problem is in the while loop which removes the series.
Rather than removing all the series, and then calling addSeries, why not just use series.setData() ?
http://api.highcharts.com/highcharts#Series.setData()
Try something like:
function redraw_chart() {
storenum = $(".StoreNum").val(); //dropdown list ,select one
T1_data = [];
T2_data = [];
$.getJSON("HisGraData", { storenum: storenum }, function (data) {
$.each(data, function (index, item) {
//DateFormat
var date = new Date(parseInt((item.Time).replace("/Date(", "").replace(")/", "").split("+")[0]));
T1_data.push([Date.parse(date.toString()), item.T1]);
T2_data.push([Date.parse(date.toString()), item.T2]);
});
T_chart.series[0].setData(T1_Data, false);
T_chart.series[1].setData(T2_Data, true);
}
Note the last parameter which tells it whether to redraw or not.

Related

Echarts:My pie charts block my line chart while I'm intended to bind them together

How can I bind pie chart and line chart together rather than appear one by one? And the pie charts which appear later than line chart will block the line chart. Is there any chance the pie and line can appear together in the end?
The current situation is that
at the beginning,and then.
This is the JS code.
var dom2 = document.getElementById('demo');
var chart = echarts.init(dom2);
var option = {
title: {
text: '中药与疾病'
},
tooltip: {},
legend: {
data: ['中药', '疾病']
},
xAxis: {
data: []
},
yAxis: [
{},
{}
],
series: [
{
name: '中药',
type: 'line',
data: [],
yAxisIndex: 0
},
{
name: '疾病',
type: 'line',
data: [],
yAxisIndex: 1
}
]
}
chart.setOption(option);
$.get('https://gist.githubusercontent.com/Linya-gzl/4d4f388e1b0e3d8e05c38f875b94a97c/raw/8c121acbfaf4aac9eccaf6b81cd1b3614203c185/demo1.json').done(function (data) {
dataArr = JSON.parse(data);
console.log(dataArr);
chart.setOption({
xAxis: {
data: dataArr.map(row => row['categories'])
},
series: [{
name: '中药',
data: dataArr.map(row => row['value1'])
},
{
name: '疾病',
data: dataArr.map(row => row['value2'])
}]
});
function buildPieSeries() {
var len = dataArr.length;
for (var i = 0; i < len; i++) {
option.series.push({
type: 'pie',
radius: 15,
center: [110 + 90 * i, dataArr[i].value2 - 100],
label: {
show: true,
textStyle: {
fontSize: 8
}
},
data: [
{ value: dataArr[i].value1, name: '黄连' },
{ value: dataArr[i].value2, name: '黄芩' },
]
})
}
chart.setOption(option, true);
}
setTimeout(buildPieSeries, 1000);
});
and
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.7.0/echarts.min.js" integrity="sha256-eKrx6Ly6b0Rscx/PSm52rJsvK76RJyv18Toswq+OLSs=" crossorigin="anonymous"></script>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<div id="demo" style="width: 600px;height:400px;"></div>
I changed your code a bit in the series insertion part, by my opinion need inserting series completely because partial inserts sometimes cause problems with merging data. Also I fixed coordinate calculation, more correct way take the already calculated coordinates from line if they the same.
document.addEventListener("DOMContentLoaded", e => {
var targetNode = document.querySelector('#chartNode');
var chartInstance = echarts.init(targetNode);
var option = {
title: { text: '中药与疾病' },
tooltip: {},
legend: { data: ['中药', '疾病'] },
xAxis: { data: [] },
yAxis: [
{},
{}
],
series: [
{
name: '中药',
type: 'line',
data: [],
yAxisIndex: 0
},
{
name: '疾病',
type: 'line',
data: [],
yAxisIndex: 1
}
]
}
chartInstance.setOption(option);
$.get('https://gist.githubusercontent.com/Linya-gzl/4d4f388e1b0e3d8e05c38f875b94a97c/raw/8c121acbfaf4aac9eccaf6b81cd1b3614203c185/demo1.json').done(function (data) {
dataArr = JSON.parse(data);
chartInstance.setOption({
xAxis: {
data: dataArr.map(row => row['categories'])
},
series: [{
name: '中药',
data: dataArr.map(row => row['value1'])
},
{
name: '疾病',
data: dataArr.map(row => row['value2'])
}]});
pieSeries = chartInstance.getOption().series;
function buildPieSeries() {
var len = dataArr.length;
for (var i = 0; i < len; i++) {
pieSeries.push({
type: 'pie',
radius: 15,
z: 10,
center: chartInstance.getModel().getSeriesByName('中药')[0].getData().getItemLayout(i),
// center: [110 + 90 * i, dataArr[i].value2 - 100],
label: {
show: true,
textStyle: {
fontSize: 8
}},
data: [
{ value: dataArr[i].value1, name: '黄连' },
{ value: dataArr[i].value2, name: '黄芩' },
]
})
};
chartInstance.setOption({ series: pieSeries });
}
setTimeout(() => buildPieSeries(), 1000);
});
});
<script src="https://cdn.jsdelivr.net/npm/echarts#4.7.0/dist/echarts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="chartNode" style="width: 600px;height:400px;"></div>

Show data as a live stream, Highcharts

So What I have is a set of data stored, which I am able to access in Highchart easily. but Now what I need is to show the data as a live stream
like the following example :
https://www.highcharts.com/demo/dynamic-update
What I have done so far is Here :
<script type="text/javascript">
var xValues = [];
xValues = [1,4,3,9,3,4,4,6,4,5,3,4,3,3,1,3,2,3,2,3,4,4,3,3,4,3,5,3,6,7,3,2,5,7,4,6,7,3,6,7,4,7,4,7,3,2,5,6,7,4,3,4,6,6,7,4,6,6,7,3,6,7,3,2,4,5,6,5,9,8,4,6,2,1,5,8,5,8,2,6,3,8,4,7,3,6,1,5,8,0,2,4,7,5,8,3,7,9,3,7];
Highcharts.chart('ppg', {
chart: {
type: 'line'
},
title: {
text: 'ECG Data'
},
subtitle: {
text: ''
},
xAxis: {
crosshair: false
},
yAxis: {
title: {
text: 'Peaks'
}
},
tooltip: {
enable: false
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: '',
lineWidth: 2,
data: xValues,
animation: {
duration: 5000
}
}]
});
</script>.
How can my data flow like the above example? in 10 10 patches.
Here is the Working JSFiddle:
https://jsfiddle.net/abnitchauhan/3vj2afnt/
You can initially add only the first 10 points and then use chart load event function and set interval to add remaining points with shift argument:
var xValues = [],
counter = 11,
startValues;
xValues = [...];
startValues = xValues.slice(0, counter);
var chart = Highcharts.chart('ppg', {
chart: {
type: 'line',
events: {
load: function() {
var chart = this,
interval = setInterval(function() {
chart.series[0].addPoint(xValues[counter], true, true);
counter++;
if (counter === xValues.length - 1) {
clearInterval(interval);
}
}, 1000);
}
}
},
...
});
Live demo: https://jsfiddle.net/BlackLabel/7x9vrLqm/
API Reference:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/class-reference/Highcharts.Series#addPoint
In your code event is missing which will trigger change per sec.
Something like this. I have used random number.
var xValues = [];
xValues = [1,4,3,9,3,4,4,6,4,5,3,4,3,3,1,3,2,3,2,3,4,4,3,3,4,3,5,3,6,7,3,2,5,7,4,6,7,3,6,7,4,7,4,7,3,2,5,6,7,4,3,4,6,6,7,4,6,6,7,3,6,7,3,2,4,5,6,5,9,8,4,6,2,1,5,8,5,8,2,6,3,8,4,7,3,6,1,5,8,0,2,4,7,5,8,3,7,9,3,7];
Highcharts.chart('ppg', {
chart: {
type: 'line',
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = Math.random();
y = Math.random();
series.addPoint([x, y], true, true);
}, 1000);
}
}
},
title: {
text: 'ECG Data'
},
subtitle: {
text: ''
},
xAxis: {
crosshair: false
},
yAxis: {
title: {
text: 'Peaks'
}
},
tooltip: {
enable: false
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: '',
lineWidth: 2,
data: xValues,
animation: {
duration: 5000
}
}]
});
Working fiddle

how to update highstock indicators on dynamically updated chart

Indicators do draw only for 'historical' part of the chart but do not update when new points appear. http://jsfiddle.net/yp6ocybe/
series: [{
id: 'rand',
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data;
}())
},
{
type: 'sma',
linkedTo: 'rand',
name: 'SMA (14)'
}, {
type: 'sma',
linkedTo: 'rand',
name: 'SMA (50)',
params: {
period: 50
}
}]
});
The best solution I found is to manually call update on SMA series when the main series is updated.
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
var series1 = this.series[1];
var series2 = this.series[2];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
//call update by passing the old options and redraw = true
series1.update(series1.options, true);
series2.update(series2.options, true);
}, 1000);
}
It stops animating smoothly though, at least on my machine.
http://jsfiddle.net/yp6ocybe/3/
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Create the chart
Highcharts.stockChart('container', {
chart: {
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
var series1 = this.series[1];
var series2 = this.series[2];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], true, true);
series1.update(series1.options,true);
series2.update(series2.options,true);
}, 1000);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
id: 'rand',
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -999; i <= 0; i += 1) {
data.push([
time + i * 1000,
Math.round(Math.random() * 100)
]);
}
return data;
}())
},
{
type: 'sma',
linkedTo: 'rand',
name: 'SMA (14)'
}, {
type: 'sma',
linkedTo: 'rand',
name: 'SMA (50)',
params: {
period: 50
}
}]
});
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://code.highcharts.com/stock/indicators/indicators.js"></script>
<div id="container" style="height: 400px; min-width: 310px"></div>

Highstock Chart - setExtremes event data missing

I have created a chart with the following specs:
$('#container').highcharts('StockChart', {
chart: {
alignTicks: false,
zoomType: 'x'
},
rangeSelector: {
selected: 5,
buttons: [
{
type: 'minute',
count: 1,
text: '1m'
}, {
type: 'minute',
count: 10,
text: '10m'
}, {
type: 'minute',
count: 30,
text: '30m'
}, {
type: 'minute',
count: 60,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1d'
}, {
type: 'all',
text: 'All'
}
]
},
title: {
text: 'Ping RTT over time for: ' + host
},
subtitle: {
text: document.ontouchstart === undefined ?
'Click and drag in the plot area to zoom in' : 'Pinch the chart to zoom in'
},
xAxis: {
type: 'datetime',
events: {
setExtremes: setExtremesCallback
}
},
yAxis: {
title: {
text: 'Ping RTT (ms)'
}
},
legend: {
enabled: false
},
plotOptions: {
column: {
color: Highcharts.getOptions().colors[c]
},
series: {
dataGrouping: {
approximation: "average"
}
}
},
series: [{
type: 'column',
name: 'Ping RTT',
data: h,
}]
});
Then I have the setExtreme callback defined as follows:
function setExtremeCallback(event) {
var min = event.min;
var max = event.max;
var container = event.target.chart.renderTo
...
}
In this function i would like to compute some statistics regarding the portion of data in the selected range. For this I need min and max, and I'm able to catch them from the event object.
The problem is that don't manage to access the data array. I've tried with
var data = event.target.chart.series[0].data
or
var data = this.series[0].data
but both of them are empty.
I solved it in this way, but I'm pretty sure there is a cleaner way to do that.
function setExtremeCallback(event) {
var minPos = 0;
var maxPos = this.series[0].xData.length - 1;
for (var j = 0; j < this.series[0].xData.length; j++) {
if (this.series[0].xData[j] <= event.min)
minPos = j;
if (this.series[0].xData[j] <= event.max)
maxPos = j;
}
var yData = this.series[0].yData.slice(minPos, maxPos);
...
}

How to display a highchart with more than one line?

I am having a list name aaa. It is an list of list
aaa[0] = [[{'a',1},{'b',2}]
aaa[1] = [[{'q',2},{'bd',0}]
aaa[2] = [[{'sa',3},{'bs',6}]
aaa[2] = [[{'sa',5},{'vb',8}]
I got the response from the model
Now I need to populate this value into Chart
My Chart will contain four lines for aaa[0] ,aaa[1] ,aaa[2] ,aaa[3]
Here is my High Chart Code
<script>
$(document).ready(function () {
//Default time zone
moment.tz.setDefault("America/New_York");
// Global option to disable UTC time usage
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Chart configurations
var options = {
chart: {
renderTo: 'container2',
type: 'area',
marginRight: 45,
zoomType: 'x'
},
title: {
text: 'aaaa'
},
xAxis: {
type: 'datetime',
minRange: 8 * 24 * 3600000,
labels: {
format: '{value:%m-%d-%Y}',
rotation: 45
}
},
yAxis: {
title: {
text: 'count'
},
labels: {
formatter: function () {
return this.value;
}
}
},
plotOptions: {
area: {
marker: {
enabled: true,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true
}
}
},
lineWidth: 1,
threshold: null
}
},
series: [{
fillOpacity: 0.1,
name: 'aaa',
pointInterval: 24 * 3600 * 1000,
pointStart: 1375295400000,
data: GetPercentage()
}]
};
// Rendering the Highcharts
chart = new Highcharts.Chart(options);
function GetPercentage() {
var data = #Html.Raw(JsonConvert.SerializeObject(Model.aaa));
// alert(data)
#foreach(var val in Model.aaa) //loop of getting a list from aaa
{
var percentages = [];
for (var x = 0; x < #val.Count; x++)
{
//Here I need to push the list
}
//percentages.sort(SortByDate);
// return percentages;
}
}
//Sort the array based on first array element
function SortByDate(a,b){
//alert(a[0] +" - " +b[0]);
return (a[0] - b[0]);
}
//Timeout function to reload page on everyone hour
setTimeout(function () {
location.reload(true);
}, 60* 60 * 1000);
//Progress bar to display feed delivery percentage
$('.progress .progress-bar').progressbar({
transition_delay: 500,
display_text: 'fill',
refresh_speed: 500
});
});
</script>
Could anyone help me to diplay a chart with four lines ?
Thanks in advance
Here you can see the series is an object array
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4]
}, {
name: 'John',
data: [5, 7, 3]
}]
});
});
You should add more objects into series array to create more than one line.

Categories