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>
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
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>
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);
...
}
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.