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

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>

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>

Can I use vaadin code to generate code dynamically using JavaScript?

<!DOCTYPE HTML>
<html>
<head>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
theme: "theme2",//theme1
title:{
text: "Basic Column Chart - CanvasJS"
},
animationEnabled: false, // change to true
data: [
{
// Change type to "bar", "area", "spline", "pie",etc.
type: "column",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
}
</script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</body>
</html>
Can I use vaadin code to generate code dynamically using JavaScript?
I have not tried the append part.
enter code here
//stackchange.js
function calc2DArrMulti(dArr) {
let vLen = dArr.length;
let eLen = dArr[0].length;
const result = [];
const flip = new Array(eLen);
for (let j = 0; j < eLen; j++) {
flip[j] = new Array(vLen);
for (let i = 0; i < vLen; i++) {
flip[j][i] = dArr[i][j];
if (result[i] == null) result[i] = new Array(eLen);
}
}
for (let i = 0; i < eLen; i++) {
let min = Math.min.apply(null, flip[i]);
for (let j = 0; j < vLen; j++) {
let v = flip[i][j];
result[j][i] = v / min;
}
}
return {
origin: dArr,
calc: result
};
};
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--Vaadin-charts-->
<script src="js/jquery.js"></script>
<script src="js/stackchange.js"></script>
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="bower_components/vaadin-charts/vaadin-charts.html">
<!-- <link rel="import" href="bower_components/vaadin-charts/ybtest.html">-->
<!--stacked-->
<script>
//----------------임의 데이터 만들기------------------//
var fab1 = [5, 2200, 100000, 6000000, 5200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab2 = [7, 2200, 130000, 4600000, 4200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab3 = [7, 2200, 100700, 5600000, 9200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab4 = [7, 2200, 100700, 5600000, 9200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var fab5 = [7, 2200, 100700, 5600000, 9200000, 2200, 100000, 6000000, 5200000,124,124,124,124,124,124];
var test = new Array(5);
// var test2 = new Array(4);
//2차원 배열 선언!!
for (var i = 0; i < test.length; i++) { //2
test[i] = new Array(5);
}
for (var i = 0; i < fab1.length; i++) {
test[0][i] = fab1[i];
test[1][i] = fab2[i];
test[2][i] = fab3[i];
test[3][i] = fab4[i];
test[4][i] = fab4[i];
}
//2차원 배열에 1차원 배열 넣기!!
//----------------임의 데이터 만들기------------------//
var test2 = calc2DArrMulti(test);
var test3 = stackchange(test);
</script>
<!-- <script>
$("#test-chart").append("<template><vaadin-column-chartid='dateAxisAndClickEvent'on-point-click='pointClickListener'><x-axis><categories>Fab1,Fab2,Fab3,Fab4,Fab5</categories></x-axis><y-axisallow-decimals='false'min='0'><stack-labelsenabled='false'></stack-labels></y-axis><tooltipformatter='function(){return(test3.origin[this.series.index][this.point.x])}'></tooltip><plot-options><chart-areastacking='percent'></chart-area><columnstacking='percent'><data-labelsenabled='true'color='white'formatter='function(){return(test3.origin[this.series.index][this.point.x])}'></data-labels></column></plot-options><legendlayout='vertical'align='right'vertical-align='top'x='-40'y='80'floating='true'border-width='1'background-color='#FFFFFF'shadow='true'></legend><data-seriesname='1'id='mytib'data='[[mytib]]'></data-series><data-seriesname='2'id='myext'data='[[myext]]'></data-series><data-seriesname='3'id='mybxt'data='[[mybxt]]'></data-series><data-seriesname='4'id='mycxt'data='[[mycxt]]'></data-series><data-seriesname='5'id='mydxt'data='[[mydxt]]'></data-series><data-seriesname='6'id='mydxx'data='[[mydxx]]'></data-series><data-seriesname='7'id='mydxz'data='[[mydxz]]'></data-series><data-seriesname='8'id='mydxy'data='[[mydxy]]'></data-series><data-seriesname='9'id='mydxr'data='[[mydxr]]'></data-series><data-seriesname='10'id='mydxh'data='[[mydxh]]'></data-series><data-seriesname='11'id='mydx1'data='[[mydx1]]'></data-series><data-seriesname='12'id='mydx2'data='[[mydx2]]'></data-series><data-seriesname='13'id='mydx3'data='[[mydx3]]'></data-series><data-seriesname='14'id='mydx4'data='[[mydx4]]'></data-series><data-seriesname='15'id='mydx5'data='[[mydx5]]'></data-series></vaadin-column-chart></template>");
</script>-->
<dom-module id=test-chart>
<template>
<vaadin-column-chart id='dateAxisAndClickEvent' on-point-click='pointClickListener'>
<x-axis>
<categories>Fab1,Fab2,Fab3,Fab4,Fab5</categories>
</x-axis>
<y-axis allow-decimals='false' min='0'>
<stack-labels enabled='false'></stack-labels>
</y-axis>
<tooltip formatter= 'function() { return (test3.origin[this.series.index][this.point.x])}'></tooltip>
<plot-options>
<chart-area stacking='percent'>
</chart-area>
<column stacking='percent'>
<data-labels enabled='true' color='white' formatter= 'function() { return (test3.origin[this.series.index][this.point.x])}'></data-labels>
</column>
</plot-options>
<legend layout='vertical' align='right' vertical-align='top' x='-40' y='80' floating='true' border-width='1' background-color='#FFFFFF' shadow='true'></legend>
<data-series name='1'id='mytib' data='[[mytib]]'></data-series>
<data-series name='2'id='myext' data='[[myext]]'></data-series>
<data-series name='3'id='mybxt' data='[[mybxt]]'></data-series>
<data-series name='4'id='mycxt' data='[[mycxt]]'></data-series>
<data-series name='5'id='mydxt' data='[[mydxt]]'></data-series>
<data-series name='6'id='mydxx' data='[[mydxx]]'></data-series>
<data-series name='7'id='mydxz' data='[[mydxz]]'></data-series>
<data-series name='8'id='mydxy' data='[[mydxy]]'></data-series>
<data-series name='9'id='mydxr' data='[[mydxr]]'></data-series>
<data-series name='10' id='mydxh' data='[[mydxh]]'></data-series>
<data-series name='11' id='mydx1' data='[[mydx1]]'></data-series>
<data-series name='12' id='mydx2' data='[[mydx2]]'></data-series>
<data-series name='13' id='mydx3' data='[[mydx3]]'></data-series>
<data-series name='14' id='mydx4' data='[[mydx4]]'></data-series>
<data-series name='15' id='mydx5' data='[[mydx5]]' ></data-series>
</vaadin-column-chart>
</template>
</dom-module>
<script>
Polymer({
is: 'test-chart',
properties: {
mytib: {
type: Array,
value: test3.calc[0]
},
myext: {
type: Array,
value: test3.calc[1]
},
mybxt: {
type: Array,
value: test3.calc[2]
},
mycxt: {
type: Array,
value: test3.calc[3]
},
mydxt: {
type: Array,
value: test3.calc[4]
},
mydxx: {
type: Array,
value: test3.calc[5]
},
mydxz: {
type: Array,
value: test3.calc[6]
},
mydxy: {
type: Array,
value: test3.calc[7]
},
mydxr: {
type: Array,
value: test3.calc[8]
},
mydxh: {
type: Array,
value: test3.calc[9]
},
mydx1: {
type: Array,
value: test3.calc[10]
},
mydx2: {
type: Array,
value: test3.calc[11]
},
mydx3: {
type: Array,
value: test3.calc[12]
},
mydx4: {
type: Array,
value: test3.calc[13]
},
mydx5: {
type: Array,
value: test3.calc[14]
},
},
pointClickListener: function(a) {
var b = a.detail.originalEvent,
c = a.detail.point,
d = b.chartX,
f = b.chartY;
this.showLabel(c.series.name+':' + test3.origin[c.series.index][c.x], d, f)
},
showLabel: function(a, b, c) {
var d = this.$.dateAxisAndClickEvent.chart.renderer.label(a, b, c).attr({
fill: 'red',
// Highcharts.getOptions().colors[5],
padding: 5,
r: 5,
zIndex: 8
}).css({
color: '#FFFFFF'
}).add();
this.async(function() {
d.fadeOut()
}, 1e3)
}
});
</script>
<test-chart></test-chart>
</body>
</html>
I have not tried the append part.
I want to code the vaadin chart like a canvas.
Is it possible?
What should I do if possible?

How to create Pie chart using Plottable.js

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>

How to make qtip2 respond to dynamic user input

I have the following working code. It takes the input data and display the histogram based on a threshold.
"use strict";
var histograms,
thresholds = [];
var input_data = [{
"threshold": 1.5,
"histograms": [{
"sample": "Sample1",
"values": [{
"score": 6.7530200000000002,
"celltype": "Bcells"
}, {
"score": 11.432763461538459,
"celltype": "DendriticCells"
}, {
"score": 25.823089615384621,
"celltype": "Macrophages"
}, {
"score": 9.9911211538461551,
"celltype": "gdTCells"
}, {
"score": 7.817228076923076,
"celltype": "StemCells"
}, {
"score": 17.482806923076922,
"celltype": "StromalCells"
}, {
"score": 29.335427692307697,
"celltype": "Monocytes"
}, {
"score": 28.914959615384621,
"celltype": "Neutrophils"
}, {
"score": 13.818888461538467,
"celltype": "NKCells"
}, {
"score": 9.5030688461538464,
"celltype": "abTcells"
}]
}]
}, {
"threshold": 2,
"histograms": [{
"sample": "Sample1",
"values": [{
"score": 5.1335499999999996,
"celltype": "Bcells"
}, {
"score": 16.076072499999999,
"celltype": "DendriticCells"
}, {
"score": 46.182032499999998,
"celltype": "Macrophages"
}, {
"score": 6.5895700000000001,
"celltype": "gdTCells"
}, {
"score": 5.3218800000000002,
"celltype": "StemCells"
}, {
"score": 53.643625,
"celltype": "StromalCells"
}, {
"score": 85.1618225,
"celltype": "Monocytes"
}, {
"score": 55.559129999999996,
"celltype": "Neutrophils"
}, {
"score": 7.6717524999999984,
"celltype": "NKCells"
}, {
"score": 6.3277800000000006,
"celltype": "abTcells"
}]
}]
}];
processData(input_data);
function processData(data) {
histograms = data[0].histograms.map(function(data) {
return {
title: data.sample,
dataset: new Plottable.Dataset(),
dataByThreshold: {},
load: function(threshold) {
this.dataset.data(this.dataByThreshold[threshold]);
}
};
});
data.forEach(function(data) {
var threshold = data.threshold;
thresholds.push(threshold);
data.histograms.forEach(function(histogram, i) {
histograms[i].dataByThreshold[threshold] = histogram.values;
});
});
// Here we generalize the slide bar maximum threshold
$('#threshold').attr('max', thresholds.length - 1);
updateDatasets(thresholds[0]);
buildPlots();
updateThreshold();
}
$('#threshold').change(updateThreshold);
function updateThreshold() {
// This is where the user input updating slider
// takes place and where the QTIP is in action.
var thresholdIndex = parseInt($('#threshold').val(), 10);
$("#foldchange_threshold").html(thresholds[thresholdIndex]);
updateDatasets(thresholds[thresholdIndex]);
$(".tooltipped rect").qtip({
overwrite: true,
position: {
my: "bottom middle",
at: "top middle"
},
style: {
classes: "qtip-light"
}
});
}
function updateDatasets(threshold) {
histograms.forEach(function(histogram) {
histogram.load(threshold);
});
}
function buildPlots() {
var $histogramContainer = $('#sample-histograms');
histograms.forEach(function(histogram, index) {
var elementId = "sample-histogram-" + index;
$(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.css({
width: '200px',
height: '200px',
display: 'inline-block'
})
.attr('id', elementId)
.appendTo($histogramContainer);
plotSampleHistogram(histogram.title, histogram.dataset, '#' + elementId);
});
}
function plotSampleHistogram(title, dataset, targetElement) {
var xScale = new Plottable.Scales.Category(),
yScale = new Plottable.Scales.Linear(),
colorScale = new Plottable.Scales.Color();
var xAxis = new Plottable.Axes.Numeric(xScale, "bottom"),
yAxis = new Plottable.Axes.Numeric(yScale, "left"),
titleLabel = new Plottable.Components.TitleLabel(title);
yScale.domainMin(0);
var plot = new Plottable.Plots.Bar()
.addDataset(dataset)
.x(function(d) { return d.celltype; }, xScale)
.y(function(d) { return d.score; }, yScale)
.attr("fill", function(d) { return d.celltype; }, colorScale)
.attr("title", function(d) { return '<div class="bartip">' + d.celltype + " (" + d.score.toFixed(2) + ') </div>'; })
.addClass("tooltipped");
new Plottable.Components.Table([
[null, titleLabel],
[yAxis, plot],
[null, xAxis]
]).renderTo(targetElement);
}
function drawHistogramLegend(targetElement) {
new Plottable.Components.Legend(colorScale)
.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>
<!-- Display the sliding bar -->
<input id="threshold" type="range" min="0" max="1" step="1" value="0" />
<br>
<!-- Show foldchange threshold -->
<div id="foldchange_threshold" style="display: inline-block; align:center;"></div>
<!-- Show histograms -->
<div id="sample-histograms"></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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/basic/jquery.qtip.js"></script>
</body>
</html>
If you run the code you can notice that the histogram will change as you drag the slider. AND a tool tip will appear if you place your mouse in one of the histogram bar.
The problem I'm facing is that the value of the tool tip does not change upon the user input to the sliding bar. For example with threshold=1.5 the Bcell score is 6.75 and threshold=2, the score is 5.13. This is not reflected in the tool tip.
How can resolve this issue?
It looks like QTip2 modifies the "title" attribute in some way, cacheing the previous information under "oldtitle". I got it to work by switching the title to a different attribute:
plot.attr("qtip2-title", function(d) {
return '<div class="bartip">' + d.celltype + " (" + d.score.toFixed(2) + ') </div>';
});
Then, we tell QTip2 to look up the "qtip2-title" property for the tooltip text:
$(".tooltipped .content rect").qtip({
// ... other setup here...
content: {
text: function() {
return $(this).attr("qtip2-title");
}
}
});
(Note the use of .content to avoid selecting unwanted rectangles).
Also, I noticed that currently xAxis is an Axes.Numeric, which will not work with Scales.Category. Use Axes.Category instead.
"use strict";
var histograms,
thresholds = [];
var input_data = [{
"threshold": 1.5,
"histograms": [{
"sample": "Sample1",
"values": [{
"score": 6.7530200000000002,
"celltype": "Bcells"
}, {
"score": 11.432763461538459,
"celltype": "DendriticCells"
}, {
"score": 25.823089615384621,
"celltype": "Macrophages"
}, {
"score": 9.9911211538461551,
"celltype": "gdTCells"
}, {
"score": 7.817228076923076,
"celltype": "StemCells"
}, {
"score": 17.482806923076922,
"celltype": "StromalCells"
}, {
"score": 29.335427692307697,
"celltype": "Monocytes"
}, {
"score": 28.914959615384621,
"celltype": "Neutrophils"
}, {
"score": 13.818888461538467,
"celltype": "NKCells"
}, {
"score": 9.5030688461538464,
"celltype": "abTcells"
}]
}]
}, {
"threshold": 2,
"histograms": [{
"sample": "Sample1",
"values": [{
"score": 5.1335499999999996,
"celltype": "Bcells"
}, {
"score": 16.076072499999999,
"celltype": "DendriticCells"
}, {
"score": 46.182032499999998,
"celltype": "Macrophages"
}, {
"score": 6.5895700000000001,
"celltype": "gdTCells"
}, {
"score": 5.3218800000000002,
"celltype": "StemCells"
}, {
"score": 53.643625,
"celltype": "StromalCells"
}, {
"score": 85.1618225,
"celltype": "Monocytes"
}, {
"score": 55.559129999999996,
"celltype": "Neutrophils"
}, {
"score": 7.6717524999999984,
"celltype": "NKCells"
}, {
"score": 6.3277800000000006,
"celltype": "abTcells"
}]
}]
}];
processData(input_data);
function processData(data) {
histograms = data[0].histograms.map(function(data) {
return {
title: data.sample,
dataset: new Plottable.Dataset(),
dataByThreshold: {},
load: function(threshold) {
this.dataset.data(this.dataByThreshold[threshold]);
}
};
});
data.forEach(function(data) {
var threshold = data.threshold;
thresholds.push(threshold);
data.histograms.forEach(function(histogram, i) {
histograms[i].dataByThreshold[threshold] = histogram.values;
});
});
// Here we generalize the slide bar maximum threshold
$('#threshold').attr('max', thresholds.length - 1);
updateDatasets(thresholds[0]);
buildPlots();
updateThreshold();
}
$('#threshold').change(updateThreshold);
function updateThreshold() {
// This is where the user input updating slider
// takes place and where the QTIP is in action.
var thresholdIndex = parseInt($('#threshold').val(), 10);
$("#foldchange_threshold").html(thresholds[thresholdIndex]);
updateDatasets(thresholds[thresholdIndex]);
$(".tooltipped .content rect").qtip({
overwrite: true,
position: {
my: "bottom middle",
at: "top middle"
},
style: {
classes: "qtip-light"
},
content: {
text: function() {
return $(this).attr("qtip2-title");
}
}
});
}
function updateDatasets(threshold) {
histograms.forEach(function(histogram) {
histogram.load(threshold);
});
}
function buildPlots() {
var $histogramContainer = $('#sample-histograms');
histograms.forEach(function(histogram, index) {
var elementId = "sample-histogram-" + index;
$(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.css({
width: '200px',
height: '200px',
display: 'inline-block'
})
.attr('id', elementId)
.appendTo($histogramContainer);
plotSampleHistogram(histogram.title, histogram.dataset, '#' + elementId);
});
}
function plotSampleHistogram(title, dataset, targetElement) {
var xScale = new Plottable.Scales.Category(),
yScale = new Plottable.Scales.Linear(),
colorScale = new Plottable.Scales.Color();
var xAxis = new Plottable.Axes.Category(xScale, "bottom"),
yAxis = new Plottable.Axes.Numeric(yScale, "left"),
titleLabel = new Plottable.Components.TitleLabel(title);
xAxis.tickLabelAngle(-90)
yScale.domainMin(0);
var plot = new Plottable.Plots.Bar()
.addDataset(dataset)
.x(function(d) { return d.celltype; }, xScale)
.y(function(d) { return d.score; }, yScale)
.attr("fill", function(d) { return d.celltype; }, colorScale)
.attr("qtip2-title", function(d) { return '<div class="bartip">' + d.celltype + " (" + d.score.toFixed(2) + ') </div>'; })
.addClass("tooltipped");
new Plottable.Components.Table([
[null, titleLabel],
[yAxis, plot],
[null, xAxis]
]).renderTo(targetElement);
}
function drawHistogramLegend(targetElement) {
new Plottable.Components.Legend(colorScale)
.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>
<!-- Display the sliding bar -->
<input id="threshold" type="range" min="0" max="1" step="1" value="0" />
<br>
<!-- Show foldchange threshold -->
<div id="foldchange_threshold" style="display: inline-block; align:center;"></div>
<!-- Show histograms -->
<div id="sample-histograms"></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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/basic/jquery.qtip.js"></script>
<script src="histo.js"></script>
</body>
</html>
Hopefully this works for you! Glad to see you're using Plottable.
P.S. We're working on getting a more detailed tooltip tutorial for the website. Stay tuned.

Add legend at the end of each line in NVD3.js

I'm newbie with D3 and NVD3 charts.
I'm trying to create a line chart, and at the end of each line, I want to display the final values.
Something like this:
http://bl.ocks.org/ZJONSSON/3918369
or fix the tooltip legend to show at the end, like this:
This is my example:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>NVD3</title>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="lib/d3.v3.js"></script>
<link href="nv.d3.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="nv.d3.js"></script>
<script type="text/javascript">
var dados = [
{ descricao: 'serie 1', valores: [
{ data: '2014-10-01T03:00:00.000Z', valor: 1 },
{ data: '2014-10-02T03:00:00.000Z', valor: 2 },
{ data: '2014-10-03T03:00:00.000Z', valor: 3 },
{ data: '2014-10-04T03:00:00.000Z', valor: 4 },
{ data: '2014-10-05T03:00:00.000Z', valor: 2 },
{ data: '2014-10-06T03:00:00.000Z', valor: 10 },
{ data: '2014-10-07T03:00:00.000Z', valor: 5 },
]},
{ descricao: 'serie 2', valores: [
{ data: '2014-10-01T03:00:00.000Z', valor: 3 },
{ data: '2014-10-02T03:00:00.000Z', valor: 2.7 },
{ data: '2014-10-03T03:00:00.000Z', valor: 5 },
{ data: '2014-10-04T03:00:00.000Z', valor: 4.6 },
{ data: '2014-10-05T03:00:00.000Z', valor: 5 },
{ data: '2014-10-06T03:00:00.000Z', valor: 5.8 },
{ data: '2014-10-07T03:00:00.000Z', valor: 7 },
]}
];
/*These lines are all chart setup. Pick and choose which chart features you want to utilize. */
nv.addGraph(function() {
var chart = nv.models.lineChart()
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(300) //how fast do you want the lines to transition?
.color(d3.scale.category10().range())
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
chart.xAxis //Chart x-axis settings
.axisLabel('Data')
.ticks(d3.time.days, 1)
.tickFormat(function(d) {
return d3.time.format('%d/%m/%Y')(new Date(d));
});
chart.yAxis //Chart y-axis settings
.axisLabel('Custo (R$)')
.tickFormat(d3.format('$,2'));
/* Done setting the chart up? Time to render it!*/
var myData = buildData(); //You need data...
d3.select('#chart') //Select the <svg> element you want to render the chart in.
.datum(myData) //Populate the <svg> element with chart data...
.call(chart); //Finally, render the chart!
nv.utils.windowResize(function() { chart.update() });
return chart;
});
function buildData() {
var ret = [];
for (var i = 0; i < dados.length; i++) {
var dado = dados[i];
var serie = { key : dado.descricao, values: [] };
for (var j = 0; j < dado.valores.length; j++) {
var valor = dado.valores[j];
serie.values.push({ x: new Date(valor.data), y: valor.valor });
}
ret.push(serie);
}
return ret;
}
</script>
</head>
<body>
<svg id="chart" style="height: 100%; width: 70%;"></svg>
</body>
</html>
Can someone help me to do one of the both?

Categories