Bind dynamic Json data in pie chart - javascript

I am using highcharts and want to bind dynamic json data to pie chart.Here is my dynamic string
for(i = 0; i < month.length; i++){
pi_data+='{name:"'+month[i]+'",y: '+ percent[i] +',color: Highcharts.getOptions().colors['+ i
+']},';
}
Here i am generate json string and bind in pie chart data option below
{
type: 'pie',
name: 'Total Percentage',
data: [pi_data],
center: [100, 50],
size: 100,
showInLegend: false,
}
My return string is
{name:"January",y: 24.78,color: Highcharts.getOptions().colors[0]},{name:"February",y: 14.69,color: Highcharts.getOptions().colors[1]},{name:"March",y: 26.51,color: Highcharts.getOptions().colors[2]},{name:"April",y: 34.01,color: Highcharts.getOptions().colors[3]}
If i put directly in data option it working but if i put variable in data option(inside [ ] in data:) it wont work.

I guess you want data to be an array, not a string of JS code (what you get from the loop; it's also malformed), so you need to compose pi_data properly. Try this:
// From the loop I assumed pi_data should be an array.
let pi_data = []
for(i = 0; i < month.length; i++){
pi_data.push({
name: month[i],
y: percent[i],
color: Highcharts.getOptions().colors[i],
});
}
{
type: 'pie',
name: 'Total Percentage',
data: pi_data, // No []!
center: [100, 50],
size: 100,
showInLegend: false,
}

The way you are formatting the data is incorrect. data parameter takes an array of items, where as here your passing is an object.
Try converting it to the following format:
let pi_data = month.map((item,index) => ({
name: item.month,
y: item.percent,
color: Highcharts.getOptions().colors[index]
}));
//Result
[
{ name: "January", y: 24.78, color: Highcharts.getOptions().colors[0] },
{ name: "February", y: 14.69 , color: Highcharts.getOptions().colors[1]},
{ name: "March", y: 26.51,color: Highcharts.getOptions().colors[2] },
{ name: "April", y: 34.01,color: Highcharts.getOptions().colors[3] }
]
And in the options just have this array placed
{
type: 'pie',
name: 'Total Percentage',
data: pi_data,
center: [100, 50],
size: 100,
showInLegend: false,
}
Fiddle for your reference: https://jsfiddle.net/vo3ch9L1/

Related

Getting Zoomdata data to work with echarts index.js stacked line chart

I am working with a echarts javascript chart and trying to get it to work with my data in Zoomdata. I have the data grouped by 20 different computers so I am looking to do a stacked line chart with 20 lines. I know how to hard code this but I would like to link the data in Zoomdata to the code to display in the chart. Right now it just plots all 20 computers on one line.
import echarts from 'echarts'; //
import styles from './index.css';
// create chart container
const chartContainer = document.createElement('div');
chartContainer.style.width = '100%';
chartContainer.style.height = '100%';
chartContainer.classList.add(styles.chartContainer);
controller.element.appendChild(chartContainer);
const groupAccessor = controller.dataAccessors['Group By'];
const metricAccessor = controller.dataAccessors.Size;
//Need help
//Part Im having trouble with linking data in zoomdata to this chart
const chart = echarts.init(chartContainer);
const option = {
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value'
},
series: [
{
name:'邮件营销',
type:'line',
stack: '总量',
data:[120, 132, 101, 134, 90, 230, 210]
},
{
name:'联盟广告',
type:'line',
stack: '总量',
data:[220, 182, 191, 234, 290, 330, 310]
},
{
name:'视频广告',
type:'line',
stack: '总量',
data:[150, 232, 201, 154, 190, 330, 410]
},
{
name:'直接访问',
type:'line',
stack: '总量',
data:[320, 332, 301, 334, 390, 330, 320]
},
{
name:'搜索引擎',
type:'line',
stack: '总量',
data:[820, 932, 901, 934, 1290, 1330, 1320]
}
]
};
//Rest of code
controller.update = data => {
// Called when new data arrives
option.series[0].data = reshapeData(data);
chart.setOption(option);
};
function reshapeData(data) {
return data.map(d => ({
name: groupAccessor.raw(d),
value: metricAccessor.raw(d),
datum: d,
itemStyle: { //tell the chart you would like to use the colors selected
color: groupAccessor.color(d),//tell the chart you would like to use the colors selected
}, //tell the chart you would like to use the colors selected
}));
}
chart.on('mousemove', param => {
controller.tooltip.show({
event: param.event.event,
data: () => param.data.datum,
});
});
chart.on('mouseout', param => {
controller.tooltip.hide();
});
chart.on('click', param => {
controller.menu.show({
event: param.event.event,
data: () => param.data.datum,
});
});
controller.createAxisLabel({
picks: 'Group By',
position: 'bottom',
orientation: 'horizontal',
});
controller.createAxisLabel({
picks: 'Size',
position: 'bottom',
orientation: 'horizontal',
});
The json looks like:
[
{
current: {
count: 1508,
metrics: null,
na: false
},
group: [
"Computer1"
]
},
{..},
{..}
]
Thanks for adding the json details. If I understood it good, the value you want to display on each line must be current.count, and the name of each series is given by the first item in the group array (I don't know why it's an array, though).
Here is the code I would write if I want to map your data on ECharts:
/*
* incremental update counter. This will be displayed
* on the xAxis by being pushed to options.xAxis.data array.
*/
let updateCount = 0,
// initialize series as empty
const options = {
xAxis: {
type: 'category',
data: []
},
yAxis: {
type: 'value'
},
series: []
}
controller.update = data => {
updateCount++
if (options.series.length > 0) {
// Called when new data arrives
options.xAxis.data.push('record ' + updateCount)
options.series = updateData(data)
} else {
// Called only once to initialize
options.xAxis.data.push('record ' + updateCount)
options.series = initData(data)
}
// you can remove the following line if your chart is already reactive.
chart.setOption(option)
}
// the init function.
const initData = data => {
// transform each item in the data array into a series entry.
data.map(item => {
return {
name: item.group[0],
type: 'line',
stack: 'defaultStack',
data: [item.current.count]
}
})
}
// the update function.
const updateData = newData => {
// push new data counts to its respective series data.
options.series.forEach((item, index) => {
item.data.push(newData[index].current.count)
}
}
It's a bit long but more secure way to parse your raw data into an ECharts option. Let me know if you have any issue with this, I haven't tested yet so it's only brain code.

Plotly.js pie chart values format

I'm creating some pie charts with Plotly.js but I can't figure out how to set the value format. If my number is 19.231, I get 19.2. I want 19.2310, with 4 digit precision. My data and layout follow here:
var data = [{
values: values,
labels: labels,
type: 'pie',
marker: {
colors: colors
},
textfont: {
family: 'Helvetica, sans-serif',
size: 48,
color: '#000'
}
}];
var layout = {
height: 1350,
width: 1500,
title: title,
titlefont: {
family: 'Helvetica, sans-serif',
size: 58,
color: '#000'
},
legend: {
x: 1.1,
y: 0.5,
size: 40,
font: {
family: 'Helvetica, sans-serif',
size: 48,
color: '#000'
}
}
};
As far as I know you cannot do that directly in Plotly but you could add text values with your desired precision and set textinfo to text.
var values = [Math.random(), Math.random(), Math.random()];
var sum = values.reduce(function(pv, cv) { return pv + cv; }, 0);
var digits = 4;
var rounded_values = [];
for (var i = 0; i < values.length; i += 1) {
rounded_values.push(Math.round(values[i]/sum * 100 * 10**digits) / 10**digits + '%');
}
var myPlot = document.getElementById('myPlot');
var data = [{
values: values,
type: 'pie',
text: rounded_values,
textinfo: 'text'
}];
Plotly.plot(myPlot, data);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myPlot"></div>
I saw the document find some rule
about Advanced Hovertemplate it said
data: [
{
type: "scatter",
mode: "markers",
x: x,
y: y,
text: t,
marker: { size: s, sizeref: 4000, sizemode: "area" },
transforms: [{ type: "groupby", groups: c }],
hovertemplate:
"<b>%{text}</b><br><br>" +
"%{yaxis.title.text}: %{y:$,.0f}<br>" +
"%{xaxis.title.text}: %{x:.0%}<br>" +
"Number Employed: %{marker.size:,}" +
"<extra></extra>"
}
],
you can change here %{y:$,.0f} 0f to 4f .
like this
hovertemplate: '%{y:$,.4f}',
Polt.ly JS document

Can I assign a different radius for each pie slice using Highcharts?

I am using Highcharts and it is working just amazing, i am stuck at a place where i want to plot a pie chart in which every pie slice (in a single pie chart) has a different radius.
Below is the image attached of the expexted pie chart.
You can skip making it a donout or designing it this specific. I just want to know how each pie slice can have different radius.
Each series in a pie chart can have their own size. So, I stacked a bunch of pie series calculating their begin and end angles. You'll have to do a little clean up to get the tooltips displaying the value instead of 100, but I think it's a workable solution.
Note: The following code makes a bad assumption that the data points add to 100. void fixes that assumption in his fiddle http://jsfiddle.net/58zfb8gy/1.
http://jsfiddle.net/58zfb8gy/
$(function() {
var data = [{
name: 'Thane',
y: 25,
color: 'red'
}, {
name: 'Nagpur',
y: 15,
color: 'blue'
}, {
name: 'Pune',
y: 30,
color: 'purple'
}, {
name: 'Mumbai',
y: 30,
color: 'green'
}];
var start = -90;
var series = [];
for (var i = 0; i < data.length; i++) {
var end = start + 360 * data[i].y / 100;
data[i].y = 100;
series.push({
type: 'pie',
size: 100 + 50 * i,
innerSize: 50,
startAngle: start,
endAngle: end,
data: [data[i]]
});
start = end;
};
$('#container').highcharts({
series: series
});
});
Another way I toyed with, that I didn't like as much, was having each series have invisible points:
series = [{
type: 'pie',
size: 100,
innerSize: 50,
data: [{y:25, color: 'red'}, {y:75, color:'rgba(0,0,0,0)'}]
},{
type: 'pie',
size: 150,
innerSize: 50,
data: [{y:25, color: 'rgba(0,0,0,0)'},{y:15, color: 'blue'}, {y:60, color:'rgba(0,0,0,0)'}]
}, ... ];
The variablepie series type, introduced in Highcharts 6.0.0, handles this with less code. In this series type you can specify a z-parameter for each data point to alter its z-size.
For example (JSFiddle, documentation):
Highcharts.chart('container', {
chart: {
type: 'variablepie'
},
title: {
text: 'Variable pie'
},
series: [{
minPointSize: 10,
innerSize: '20%',
zMin: 0,
name: 'countries',
data: [{
name: 'Pune',
y: 35,
z: 25
}, {
name: 'Mumbai',
y: 30,
z: 20
}, {
name: 'Nagpur',
y: 15,
z: 15
} , {
name: 'Thane',
y: 25,
z: 10
}]
}]
});
This requires including:
<script src="https://code.highcharts.com/modules/variable-pie.js"></script>

put different names to each bar in Highcharts

How I can rename each bar, I want to have different names. always it appears "bar1", "bar2", etc. this is the name of the series. but I want it to appear in place of those texts, others I want to customize. this is what I do. put different names, if there are 9 bars I want to put different names to the bars, bar1, bar2, bar3, Bar4, Bar5, Bar6, Bar7, Bar8, Bar9. I do not want to repeat
in my example.
series: [{
name: 'bar1',
data: [1000, 950, 920, 0, 850],
color: "#FF0000"
}, {
name: 'bar2',
data: [800, 770, 750, 0, 730],
color: "#000000"
}, {
name: 'bar3',
data: [600, 540, 535, 500, 30],
color: "#00FF00"
},
{
name: 'bar4',
data: [28, 28, 28, 28, 28],
color: "#00FF00"
}]
http://jsfiddle.net/05L1n3wb/
This is done by changing name: 'bar1' to something you want. If you still need series.name to be 'bar1' then you should really think harder about your data model. If you want to change the text displayed based on the contents of series.name you can do that with the label formatter or dataLabel formatter.
As you can read in previous answer, you can use dataLabels formatter for changing string you are displaying for your columns: http://api.highcharts.com/highcharts#plotOptions.bar.dataLabels.formatter
You can add custom parameter to your points, like name:
series: [{
name: 'bar1',
data: [{
y: 1000,
name: 'bar1'
}, {
y: 950,
name: 'bar5'
}, {
y: 920,
name: 'bar9'
}, {
y: 0,
name: 'bar13'
}, {
y: 850,
name: 'bar17'
}],
color: "#FF0000"
}]
and inside your dataLabels formatter you can display this parameter:
formatter: function() {
var string = this.point.name + ' ';
if (this.y <= 30) {
string += this.y;
}
return string;
}
example:
http://jsfiddle.net/05L1n3wb/2/

Change Highcharts Series color

EDIT:
So now I have a chart with all my data pushed off to the right, BUT I have labels in different colors for the sets I want to show but no data?? Updated my code
Original post:
I have a working highchart here http://opensourcesurf.com/chart.html . The problem is when I try and change the color of an individual data set, they all change. How could I change these settings given my code? Thanks in advance!
code:
var options1 = {
chart: {
renderTo: 'container1',
type: 'area'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'Swell Period',
color: '#0066FF',
data: 'newSeriesData',
},
{ name: ' Maximum Breaking Wave Height',
color: '#ffffff',
data: 'newSeriesData',
},
{ name: 'Swell Height',
color: '#123456',
data: 'newSeriesData',
}],
};
var drawChart = function(data, name, color) {
var newSeriesData = {
name: name,
data: data
};
// Add the new data to the series array
options1.series.push(newSeriesData);
// If you want to remove old series data, you can do that here too
// Render the chart
var chart = new Highcharts.Chart(options1);
};
$.getJSON('decode.php', function(data){
drawChart(data, 'Swell Height');
});
$.getJSON('decode2.php', function(data){
drawChart(data, ' Maximum Breaking Wave Height');
});
$.getJSON('decode3.php', function(data){
drawChart(data, 'Swell Period');
});
Try this:
// 'series' is an array of objects with keys:
// - 'name' (string)
// - 'data' (array)
// - 'color' (HTML color code)
var newSeriesData = {
name: name,
data: data,
color: color
};
The way to specify a color for a specific series is to define it when you're defining the series. For example:
series: [{
name: 'John',
color: '#0066FF',
dashStyle: 'ShortDash',
data: [
[Date.UTC(2010, 0, 1), 29.9],
[Date.UTC(2010, 2, 1), 71.5],
[Date.UTC(2010, 3, 1), 106.4]
]
},
So essentially when you're creating your series in your drawchart function, do a check for the name, and appropriately assign a color:
var color;
if(name=="Swell Height"){
color="#0066FF";
}else if(name=="Maximum Breaking Wave Height"){
color="#0066EE";
}else if(name=="Swell Period"){
color="#0066HH";
}
var newSeriesData = {
name: name,
data: data,
color: color
};
It looks to me like you are not looping through the array of data and/or you only have one set of data in data.

Categories