How to create Pie chart using Plottable.js - javascript

I tried to create a pie chart using Plottable.js.
Does anyone know how? I get confused on how to pass the value and put a label in.
Here is my sample data:
var store = [{ Name:"Item 1", Total:18 },
{ Name:"Item 2", Total:7 },
{ Name:"Item 3", Total:3},
{ Name:"Item 4", Total:12}];
Thanks again!

You can specify the value of each slice with Pie.sectorValue and you can turn on the label with Pie.labelsEnabled which shows the corresponding value for each sector.
You can also format the labels with Pie.labelFormatter
However, I don't think there is a way to show data other than the sector value as the label, but depending on what you want, a legend might work
Here's an example of Pie chart with Legend:
window.onload = function(){
var store = [{ Name:"Item 1", Total:18 },
{ Name:"Item 2", Total:7 },
{ Name:"Item 3", Total:3},
{ Name:"Item 4", Total:12}];
var colorScale = new Plottable.Scales.Color();
var legend = new Plottable.Components.Legend(colorScale);
var pie = new Plottable.Plots.Pie()
.attr("fill", function(d){ return d.Name; }, colorScale)
.addDataset(new Plottable.Dataset(store))
.sectorValue(function(d){ return d.Total; } )
.labelsEnabled(true)
.labelFormatter(function(n){ return "$ " + n ;});
new Plottable.Components.Table([[pie, legend]]).renderTo("#chart");
}
<link href="https://rawgithub.com/palantir/plottable/develop/plottable.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://rawgithub.com/palantir/plottable/develop/plottable.js"></script>
<div id="container">
<svg id="chart" width="350" height="350"></svg>
</div>
Or, if all the values are unique, then you can probably hack it with labelFormatter
window.onload = function(){
var store = [{ Name:"Item 1", Total:18 },
{ Name:"Item 2", Total:7 },
{ Name:"Item 3", Total:3},
{ Name:"Item 4", Total:12}];
var reverseMap = {};
store.forEach(function(s) { reverseMap[s.Total] = s.Name;});
var ds = new Plottable.Dataset(store);
var pie = new Plottable.Plots.Pie()
.addDataset(ds)
.sectorValue(function(d){ return d.Total; } )
.labelsEnabled(true)
.labelFormatter(function(n){ return reverseMap[n] ;})
.renderTo("#chart");
}
<link href="https://rawgithub.com/palantir/plottable/develop/plottable.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://rawgithub.com/palantir/plottable/develop/plottable.js"></script>
<div id="container">
<svg id="chart" width="350" height="350"></svg>
</div>

Related

How do I update my X axis header title on highcharts?

I am using Datatables to create Highcharts. Everything functions as intended, however I am not sure how to extract the X axis title from Column 1. (Data1, Data2, Data3, Data4, Data5 etc.). I am not sure what am I missing in my code. Any advice would be appreciated because I don't know much about Javascript. Thanks in advance.
The chart should look like this.
See screenshot below.
Link to code - http://live.datatables.net/muvoyacu/2/edit
$(document).ready(function() {
var table = $("#example_full2").DataTable({
searching:false,
lengthChange: false,
ordering: false,
info: false,
paging: false,
} );
//var salary = getSalaries(table);
var salary = getRow(table,0);
var salary2 = getRow(table, 1);
var salary3 = getRow(table, 2);
var salary4 = getRow(table, 3);
var salary5 = getRow(table, 4);
// Declare axis for the column graph
var axis = {
id: "salary",
min: 0,
title: {
text: "Number"
}
};
// Declare inital series with the values from the getSalaries function
var series = {
name: "2012",
data: Object.values(salary)
};
var series2 = {
name: "2013",
data: Object.values(salary2)
};
var series3 = {
name: "2014",
data: Object.values(salary3)
};
var series4 = {
name: "2015",
data: Object.values(salary4)
};
var series5 = {
name: "2016",
data: Object.values(salary5)
};
var myChart = Highcharts.chart("container", {
chart: {
type: "column"
},
title: {
text: "Test Data"
},
xAxis: {
categories: Object.keys(salary)
},
yAxis: axis,
series: [series, series2, series3, series4, series5]
});
// On draw, get updated salaries and refresh axis and series
table.on("draw", function() {
salary = getSalaries(table);
myChart.axes[0].categories = Object.keys(salary);
myChart.series[0].setData(Object.values(salary));
});
});
function getSalaries(table) {
var salaryCounts = {};
var salary = {};
}
function getRow(table, row) {
var chart = {};
var data = table.row(row).data();
for (i=1; i<data.length; i++) {
var x = $( table.column( i ).header() ).html();
var y = data[i].replace(/[^0-9.]/g, "") * 1;
chart[x] = y;
}
return chart;
}
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<meta charset=utf-8 />
</head>
<body>
<div id="container" style=" width: 100%; height: 400px;"></div>
<div class="container">
<table id="example_full2" class="display nowrap" width="100%"><thead>
<tr><th>Year</th><th>2012</th><th>2013</th><th>2014</th><th>2015</th><th>2016</th><th>2017</th><th>2018</th><th>2019</th><th>2020</th><th>2021</th></tr></thead>
<tr ><td> Data1</td><td>3,823</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr>
<tr ><td> Data2</td><td>800</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr>
<tr ><td> Data3</td><td>900</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr>
<tr ><td> Data4</td><td>200</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr>
<tr ><td> Data5</td><td>300</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr>
<tr ><td> Data6</td><td>400</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr>
</tbody></table>

Highcharts giving an extra legend when I get data dynamically from Highcharts

I need to create highcharts series dynamically...So I used addSeries,But I am gettng an extra legend. If you have any other methods pls let me know...
I am not including my total chart code....I am jst placing my series in chart...
$(function () {
chart = Highcharts.chart('container', {
series: [
{
}
]
});
});
json:
"dataa":
[
{
"name": "Unit Test 1",
"data":[1,13,15,17,40,50,80]
},
{
"name": "Unit Test 2",
"data":[2,20,50,40,20,50,15]
},
{
"name": "Unit Test 3",
"data":[3,50,40,10,30,40,25]
}
]
ajax:
let dataeDatal=datae.dataa.length;
for (let i = 0; i < dataeDatal; i++) {
chart.addSeries({
data: datae.dataa[i].data,
name: datae.dataa[i].name
});
}
}
You can check in the image, I am getting an extra series1 legend
you should initialize your charts as
chart = Highcharts.chart('container', {
series: [] //should be empty array
});
fiddle demo

Display many charts with data of the same source javascript ( map (key,value) )

I have a map of this form
Object{485:Array[4],2072:Array[4],9665:Array[3]...}
I would like to display a chart per key.
I have an example which is similar to what i'm looking for and i tried to display my values in many charts : In this example, my key is : car_id
First step : sort my array to get a map with my keys. It works fine. But the second one is not working... I would like to display a chart per data based on car_id and per panel bootstrap...
What am I doing wrong ?
Thank you
<html >
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
</head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript --><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.0/Chart.min.js"></script>
<script src=" https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.0/Chart.min.js"></script>
<body >
<div >
<div class="panel panel-default">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
<canvas id="myChart" width="400" height="400"></canvas>
</div>
</div>
</div>
</body>
<script>var json = {
'cars': [{
"car_id": "1",
"price": "925",
"full_option": "EEEE"
}, {
"car_id": "1",
"price": "990",
"full_option": "DDDDD"
}, {
"car_id": "2",
"price": "500",
"full_option": "FFF"
}, {
"car_id": "2",
"price": "900",
"full_option": "GGGGGGG"
}, {
"car_id": "4",
"price": "900",
"full_option": "JJJ"
}]
};
var car_array = json.cars.reduce((prev, t, index, arr) => {
if (typeof prev[t.car_id] === 'undefined') {
prev[t.car_id] = [];
}
prev[t.car_id].push(t);
return prev;
}, {});
Object.keys(car_array).forEach(i => {
var array_of_cars_with_same_id = car_array[i];
for (var i=0; i<=array_of_cars_with_same_id.length-1;i++){
console.log(array_of_cars_with_same_id[i].price);
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [array_of_cars_with_same_id[i].full_option],
datasets: [{
label: '# of Votes',
data: [array_of_cars_with_same_id[i].price]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
}
console.log("AAAAAAAAAAAAA");
});
</script>
There are a couple of problems with your code.
First, you are only using a single canvas element. Each chart needs its own canvas element. Because of this every chart you add simply renders on top of the prior chart.
At a minimum, you have to give each item a new canvas. You could change your code to accomplish that.
Change the root element for the charts to a basic <div> element that you will append the charts to.
<div class="panel-body">
<div id="chart-holder"></div>
</div>
I would create a variable to hold the cart count, and the root element.
var chart_holder = $('#chart-holder');
var chart_count = 0;
Change the for loop to use these new variables.
for (var i = 0; i <= car_type.length - 1; i++) {
chart_holder.append('<canvas id="myChart' + chart_count + '" width="400" height="400"></canvas>')
var ctx = $("#myChart" + chart_count);
var data = [];
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [car_type[i].full_option],
datasets: [{
label: '# of Votes',
data: [car_type[i].price]
}]
},
options: chart_opts
});
chart_count++;
}
This will create a new chart for each object in each array.
I created a fiddle to demonstrate.
Based on the data, however, I would recommend a different approach. I would create a single chart per unique key, rather than a chart for every element.
You would need to parse each array to pull out labels and data for each chart. Here is an example that would get that data out of each array. There is a variable to capture the data for the chart and the labels for the chart.
var car_data = [], car_labels = [];
for (var i = 0; i <= car_type.length - 1; i++) {
car_data.push(car_type[i].price);
car_labels.push(car_type[i].full_option);
}
We can pass car_data and car_labels to the Chart.js initialization.
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: car_labels,
datasets: [{
label: 'Car Type ' + ct,
data: car_data
}]
},
options: chart_opts
});
Here is a fiddle to demonstrate a single chart per car_id.

How to make two plots side-by-side using JavaScript Plottable

With the following script I tried to make the side by side pie chart
var pies;
var indata = [
{ 'sample' : "Foo",
"pies_pct":[
{
"score": 6.7530200000000002,
"celltype": "Bcells"
},
{
"score": 11.432763461538459,
"celltype": "DendriticCells"
}]
},
{ 'sample' : "Bar",
"pies_pct":[
{
"score": 26.8530200000000002,
"celltype": "Bcells"
},
{
"score": 31.432763461538459,
"celltype": "BCells"
}]
},
];
processData(indata);
function processData(data) {
pies = data.map(function (data) {
return {
title : data.sample,
dataset : data.pies_pct
};
});
buildPlots();
}
function buildPlots () {
var $pieContainer = $('#sample-pies');
pies.forEach(function (pie, index) {
var elementId = "sample-pie-" + index;
$(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.css({width: '200px', height: '200px', display: 'inline-block'})
.attr('id', elementId)
.appendTo($pieContainer);
plotSamplePie(pie.title, pie.dataset, '#' + elementId);
});
}
function plotSamplePie(title,purity_data,targetElement) {
var scale = new Plottable.Scales.Linear();
var tableau20 = ['#1F77B4', '#FF7F0E', '#2CA02C', '#D62728',
'#9467BD', '#8C564B', '#CFECF9', '#7F7F7F', '#BCBD22', '#17BECF'];
var colorScale = new Plottable.Scales.Color();
var legend = new Plottable.Components.Legend(colorScale);
colorScale.range(tableau20);
var titleLabel = new Plottable.Components.TitleLabel(title);
var plot = new Plottable.Plots.Pie()
.addDataset(new Plottable.Dataset(purity_data))
.attr("fill", function(d) { return d.score; }, colorScale)
.sectorValue(function(d) { return d.score; }, scale)
.labelsEnabled(true);
.renderTo(targetElement);
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/plottable.js/1.15.0/plottable.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/basic/jquery.qtip.css" rel="stylesheet" />
</head>
<body>
My Plot
<!-- Show histograms -->
<div id="sample-pies"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/plottable.js/1.15.0/plottable.js"></script>
</body>
</html>
So this functios does
processData() reads the data,
buildPlots() read piechart data chunk by chunk
plotSamplePie() draw individual pie.
But why it doesn't work?
I expect it to show plot like this:
There is a simple error if you can see in you console.
var plot = new Plottable.Plots.Pie()
.addDataset(new Plottable.Dataset(purity_data))
.attr("fill", function(d) { return d.score; }, colorScale)
.sectorValue(function(d) { return d.score; }, scale)
.labelsEnabled(true);
.renderTo(targetElement);
Just remove ; after .labelsEnabled(true); and it should work.
var indata = [
{ 'sample' : "Foo",
"pies_pct":[
{
"score": 6.7530200000000002,
"celltype": "Bcells"
},
{
"score": 11.432763461538459,
"celltype": "DendriticCells"
}]
},
{ 'sample' : "Bar",
"pies_pct":[
{
"score": 26.8530200000000002,
"celltype": "Bcells"
},
{
"score": 31.432763461538459,
"celltype": "BCells"
}]
},
];
processData(indata);
function processData(data) {
pies = data.map(function (data) {
return {
title : data.sample,
dataset : data.pies_pct
};
});
buildPlots();
}
function buildPlots () {
var $pieContainer = $('#sample-pies');
pies.forEach(function (pie, index) {
var elementId = "sample-pie-" + index;
$(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.css({width: '200px', height: '200px', display: 'inline-block'})
.attr('id', elementId)
.appendTo($pieContainer);
plotSamplePie(pie.title, pie.dataset, '#' + elementId);
});
}
function plotSamplePie(title,purity_data,targetElement) {
var scale = new Plottable.Scales.Linear();
var tableau20 = ['#1F77B4', '#FF7F0E', '#2CA02C', '#D62728',
'#9467BD', '#8C564B', '#CFECF9', '#7F7F7F', '#BCBD22', '#17BECF'];
var colorScale = new Plottable.Scales.Color();
var legend = new Plottable.Components.Legend(colorScale);
colorScale.range(tableau20);
var titleLabel = new Plottable.Components.TitleLabel(title);
var plot = new Plottable.Plots.Pie()
.addDataset(new Plottable.Dataset(purity_data))
.attr("fill", function(d) { return d.score; }, colorScale)
.sectorValue(function(d) { return d.score; }, scale)
.labelsEnabled(true)
.renderTo(targetElement);
}
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/plottable.js/1.15.0/plottable.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/basic/jquery.qtip.css" rel="stylesheet" />
</head>
<body>
My Plot
<!-- Show histograms -->
<div id="sample-pies"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/plottable.js/1.15.0/plottable.js"></script>
</body>
</html>

Real Time Chart Generation using epoch.js

I am trying to create a simple real time chart using epoch.js which updates itself on a click event.
My code posted below has a total of 3 functions. They are:
1) generate a random value
2) generate the current date and time in milliseconds.
3) onclick event that updates chart datapoints.
Though I have datapoints in the right format as required for the chart. I am unable to update it .
Appreciate any help on find out as to why the graph is not working as it should.
///////////////this function generates the date and time in milliseconds//////////
function getTimeValue() {
var dateBuffer = new Date();
var Time = dateBuffer.getTime();
return Time;
}
////////////// this function generates a random value ////////////////////////////
function getRandomValue() {
var randomValue = Math.random() * 100;
return randomValue;
}
////////////// this function is used to update the chart values ///////////////
function updateGraph() {
var newBarChartData = [{
label: "Series 1",
values: [{
time: getTimeValue(),
y: getRandomValue()
}]
}, ];
barChartInstance.push(newBarChartData);
}
////////////// real time graph generation////////////////////////////////////////
var barChartData = [{
label: "Series 1",
values: [{
time: getTimeValue(),
y: getRandomValue()
}]
}, ];
var barChartInstance = $('#barChart').epoch({
type: 'time.bar',
axes: ['right', 'bottom', 'left'],
data: barChartData
});
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js">
</script>
<script src="http://www.goldhillcoldtouch.co.uk/wp-content/uploads/d3.min.js">
</script>
<script src="http://www.goldhillcoldtouch.co.uk/wp-content/uploads/epoch.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://www.goldhillcoldtouch.co.uk/wp-content/uploads/epoch.min.css">
</head>
<div id="barChart" class="epoch category10" style="width:320px; height: 240px;"></div>
<p id="updateMessage" onclick="updateGraph()">click me to update chart</p>
You are pushing the wrong object to barChartInstance when updating the graph. You need to just push the array containing the new data point, instead of pushing the full configuration again.
function updateGraph() {
var newBarChartData = [{time: getTimeValue(), y:getRandomValue()}];
/* Wrong: don't use the full configuration for an update.
var newBarChartData = [{
label: "Series 1",
values: [{
time: getTimeValue(),
y: getRandomValue()
}]
}, ];
*/
barChartInstance.push(newBarChartData);
}
///////////////this function generates the date and time in milliseconds//////////
function getTimeValue() {
var dateBuffer = new Date();
var Time = dateBuffer.getTime();
return Time;
}
////////////// this function generates a random value ////////////////////////////
function getRandomValue() {
var randomValue = Math.random() * 100;
return randomValue;
}
////////////// this function is used to update the chart values ///////////////
function updateGraph() {
var newBarChartData = [{time: getTimeValue(), y:getRandomValue()}];
/*
var newBarChartData = [{
label: "Series 1",
values: [{
time: getTimeValue(),
y: getRandomValue()
}]
}, ];
*/
barChartInstance.push(newBarChartData);
}
////////////// real time graph generation////////////////////////////////////////
var barChartData = [{
label: "Series 1",
values: [{
time: getTimeValue(),
y: getRandomValue()
}]
}, ];
var barChartInstance = $('#barChart').epoch({
type: 'time.bar',
axes: ['right', 'bottom', 'left'],
data: barChartData
});
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js">
</script>
<script src="http://www.goldhillcoldtouch.co.uk/wp-content/uploads/d3.min.js">
</script>
<script src="http://www.goldhillcoldtouch.co.uk/wp-content/uploads/epoch.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://www.goldhillcoldtouch.co.uk/wp-content/uploads/epoch.min.css">
</head>
<div id="barChart" class="epoch category10" style="width:320px; height: 240px;"></div>
<p id="updateMessage" onclick="updateGraph()">click me to update chart</p>

Categories