I have the following code:
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": "DendriticCells"
}]
}, ];
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);
new Plottable.Components.Table([
[titleLabel],
[plot]
]).renderTo(targetElement);
}
function drawPieLegend(targetElement) {
new Plottable.Components.Legend(colorScale)
.renderTo(targetElement);
}
drawPieLegend('#pies-legend')
<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>
Legend here:
<div id="pies-legend"></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>
What I want do do is to display one legend for both pie charts under '#pies-legend'
as the target element called by the function drawPieLegend()
. But why it does not show up?
colorScale
is defined inside plotSamplePie()
, so it doesn't appear in the scope of drawPieLegend()
. Declaring colorScale
outside both functions will make it possible for both functions to access it (although this is a bit messy since it is now a global variable). It'd probably be cleaner to create colorScale
inside the processing function, then pass it to the functions that make the pies and the legend separately. Here's a quick attempt at fixing it:
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": "DendriticCells"
}]
}, ];
var colorScale = new Plottable.Scales.Color();
var tableau20 = ['#1F77B4', '#FF7F0E', '#2CA02C', '#D62728',
'#9467BD', '#8C564B', '#CFECF9', '#7F7F7F', '#BCBD22', '#17BECF'
];
colorScale.range(tableau20);
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 titleLabel = new Plottable.Components.TitleLabel(title);
var plot = new Plottable.Plots.Pie()
.addDataset(new Plottable.Dataset(purity_data))
.attr("fill", function(d) {
return d.celltype;
}, colorScale)
.sectorValue(function(d) {
return d.score;
}, scale)
.labelsEnabled(true);
new Plottable.Components.Table([
[titleLabel],
[plot]
]).renderTo(targetElement);
}
function drawPieLegend(targetElement) {
new Plottable.Components.Legend(colorScale)
.maxEntriesPerRow(Infinity)
.renderTo(targetElement);
}
drawPieLegend('#pies-legend');
<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>
Legend here:
<svg id="pies-legend" height="50" width="400"></svg>
<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>
Note also the change from
.attr("fill", function(d) {
return d.score;
}, colorScale)
to
.attr("fill", function(d) {
return d.celltype;
}, colorScale)
which causes the colors to be driven by celltype
rather than score
.