Why does vega-lite draw the legend for layers that have legend set to null? - vega-lite

I have a plot with a separate layer for each of two categories of data. Each category has two subcategories. Only the first top-level category should have a legend. So I put legend: null on the second category and put a resolve at the top level to make the legends independent. But it's not working. Here's the plot, and below it is my code. I expect to see only a and b in the legend.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>legend test</title>
<link rel="stylesheet" href="styles/style.css" />
<script src="https://cdn.jsdelivr.net/npm/vega#5.9.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#4.2.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.2.2"></script>
</head>
<body>
<div id="plot-div"></div>
<script>
let spec = {
$schema: "https://vega.github.io/schema/vega-lite/v4.json",
description: "sigmatcher",
data: {
values: [
{legendGroup: true, x: 1, y: 1, cat: "a"},
{legendGroup: true, x: 2, y: 2, cat: "b"},
{legendGroup: true, x: 3, y: 4, cat: "a"},
{legendGroup: true, x: 4, y: 8, cat: "b"},
{legendGroup: false, x: 1, y: 11, cat: "c"},
{legendGroup: false, x: 2, y: 12, cat: "d"},
{legendGroup: false, x: 3, y: 14, cat: "c"},
{legendGroup: false, x: 4, y: 18, cat: "d"},
{legendGroup: false, x: 5, y: 26, cat: "c"},
]},
width: 400,
height: 400,
resolve: {
legend: {
color: "independent",
}
},
layer: [{
transform: [{
filter: {
field: "legendGroup",
equal: true
}}],
encoding: {
x: {
field: "x",
type: "quantitative"
},
y: {
field: "y",
type: "quantitative"
},
color: {
field: "cat",
type: "nominal"
}
},
mark: {
type: "point"
}
}, {
transform: [{
filter: {
field: "legendGroup",
equal: false
}}],
encoding: {
x: {
field: "x",
type: "quantitative"
},
y: {
field: "y",
type: "quantitative"
},
color: {
field: "cat",
type: "nominal",
legend: null
}
},
mark: {
type: "point"
}
}]};
vegaEmbed("#plot-div", spec);
</script>
</body>
</html>

Independent legends will still share a color scale unless you specify otherwise. You can change this by specifying resolve.scale.
In your case, instead of
"resolve": {"legend": {"color": "independent"}}
you should use
"resolve": {"scale": {"color": "independent"}}
Otherwise the scales will still be shared despite the legends being independent. If desired, you can then adjust the color schemes used by each layer to distinguish the points.
See it in action here:

Related

Vega lite, reduce amount of labels on the x-axis

I need to reduce amount of x-axis labels because now you can see what is going on:
Is it possible to adjust the step on the x-axis? I didn't find it in the documentation. In my case, it automatically counts by 200, I would like to control this.
This is my data:
data = [
{
name: 'Email Invite',
value: 6200,
tooltip: 'Total raised by Email Invite: $6200'
},
{
name: 'Text Invite',
value: 1000,
},
{
name: 'Extra Features',
value: 1800,
},
{
name: 'Snap Store',
value: 2400,
},
{
name: 'Social Media',
value: 4100,
},
]
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
description: 'bar-chart',
"config": {
"style": {
"cell": {
stroke: "#E2E8F0"
}
}
},
data: {
"values": this.data
},
"mark": {"type": "bar", "cornerRadiusTopLeft": 8, "cornerRadiusTopRight": 8},
encoding: {
x: {
field: 'b',
type: 'quantitative',
axis: {
labels: true,
labelAngle: 0,
labelFontSize: 10,
labelColor: '#94A3B8',
ticks: false,
domain: false,
gridColor: "#E2E8F0",
labelPadding: 10,
},
scale: {
paddingInner: 0.2,
paddingOuter: 0.1
},
sort: { field: 'c' }
},
y: {
field: 'a',
type: 'nominal',
axis: {
labelFontSize: 10,
labelColor: '#94A3B8',
ticks: false,
domain: false,
gridColor: "#E2E8F0",
labelPadding: 16,
labelOffset: 3,
}
},
color: {field: 'c', scale: {range: [`#000`]}, legend: null},
tooltip: {field: 'd', type: 'ordinal'}
},
width: "container",
height: 250
};
Thanks in advance!
This is controlled by tick attributes.
You can set a "tickCount", "tickMinStep" or even the values themselves via "values".
https://vega.github.io/vega-lite/docs/axis.html#ticks

Vega lite, y-axis columns are not in the middle of the grid

I added grid for both, x and y axis. For 'x' it works well, but with 'y' something strange, columns are not in the middle of the lines.
My encoding object:
encoding: {
x: {
field: 'b',
type: 'quantitative',
axis: {
labels: true,
labelAngle: 0,
title: null,
labelFontSize: 10,
labelColor: '#94A3B8',
ticks: false,
domain: false,
gridColor: "#E2E8F0",
labelPadding: 10,
grid: true
},
scale: {
paddingInner: 0.2,
paddingOuter: 0.1,
},
sort: { field: 'c' }
},
y: {
field: 'a',
"type": "nominal",
axis: {
title: null,
labelFontSize: 10,
labelColor: '#94A3B8',
ticks: false,
domain: false,
gridColor: "#E2E8F0",
labelPadding: 16,
labelOffset: 3,
grid: true
}
},
In https://vega.github.io/vega-lite/examples/ there is no example with horizontal bar chart with 'x' and 'y' lines. Maybe this is a typical behavior
Thank you in advance!
You can control the position using bandPosition.
https://vega.github.io/vega-lite/docs/band.html

How to check the chosen layer name within a constant

I'm looking for a way to check the name of the Hair layer within the constant below to see if the chosen layer's name is "First" and if so use a if statement before the Glasses layer is chosen to alter the alternative layers within Glasses that can be chosen from.
const NFT = {
stud: {
name: "Base",
layers: [
{
name: "Hair",
elements: [
{
id: 0,
name: "First",
path: `${dir}/1-hair/first.png`,
weight: 100,
},
{
id: 1,
name: "Second",
path: `${dir}/1-hair/second.png`,
weight: 80,
},
],
position: { x: 0, y: 0 },
size: { width: width, height: height },
},
{
name: "Glasses",
elements: [
{
id: 0,
name: "First",
path: `${dir}/2-glasses/first.png`,
weight: 100,
},
{
id: 1,
name: "Second",
path: `${dir}/2-glasses/second.png`,
weight: 20,
},
],
position: { x: 0, y: 0 },
size: { width: width, height: height },
},
],
},
};

How to display two different chart modal in one

I am creating the chart as you see below:
So I can display the charts separately but I cannot display both of the charts on the same chart line.
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<body>
<canvas id="statisticChart" style="width:100%;max-width:600px"></canvas>
<script>
var xValues = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var yValues = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15, 12];
new Chart("statisticChart", {
type: "line",
data: {
labels: xValues,
datasets: [{
fill: false,
lineTension: 0,
backgroundColor: "rgba(25,162,242,1)",
borderColor: "rgba(2, 92, 145, 1)",
data: yValues
}]
},
options: {
legend: { display: false },
scales: {
yAxes: [{ ticks: { min: 6, max: 16 } }],
}
}
});
var barColors = ["#19A2F2"];
Chart("statisticChart", {
type: "bar",
data: {
labels: xValues,
datasets: [{
backgroundColor: barColors,
data: yValues
}]
},
options: {
legend: { display: false },
title: {
display: true,
text: "World Wine Production 2018"
}
}
});
</script>
</body>
</html>
So could you please have a look? Besides I also care about css, so I would like to display the second chart with the color #19A2F2, thanks in advance.
Chart.js supports mixed charts - which involves just using one Chart instance of course.
All you need to do is take the datasets objects of your two individual charts and put those in an array assigned to the Charts' data.datasets property.
For example:
var xValues = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var yValues = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15, 12];
new Chart("statisticChart", {
type: "bar",
data: {
labels: xValues,
datasets: [{
type: "line",
fill: false,
lineTension: 0,
backgroundColor: "rgba(25,162,242,1)",
borderColor: "rgba(2, 92, 145, 1)",
data: yValues,
fill: false
},
{
type: "bar",
backgroundColor: "#19A2F2",
data: yValues
}
]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
min: 6,
max: 16
}
}],
},
title: {
display: true,
text: "World Wine Production 2018"
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="statisticChart" style="width:100%;max-width:600px"></canvas>

How to have one div inside another div

Hi I am using canvasjs for making a chart. It is very simple to make a particular chart but here is the problem I want to have two different charts such that a pie chart would be inside of a doughnut chart.
I am not able to make one other inside. I have used the
display : inline-block
for the two div id but no effect. Could someone please suggest me how we can make that happen.
This is my code-
<!DOCTYPE HTML>
<html>
<head>
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<link type='text/css' rel="stylesheet" href='style.css' />
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
title:{
text: "My First Chart in CanvasJS"
},
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "doughnut",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
var chart = new CanvasJS.Chart("chartContainerpie", {
data: [
{
// Change type to "doughnut", "line", "splineArea", etc.
type: "pie",
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>
<div id="chartContainerpie" style="height: 300px; width: 100%;></div>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</div>
</body>
</html>
The CSS only contains the line for display block.
This is probably not the perfect answer but it will point you in right direction:
The idea is to change the background color of canvas to transparent and overlap the two canvas using position css
CSS
#chartContainerpie{
position: absolute;
top: 130px;
left: 0px;
}
#chartContainer{
position: absolute;
top: 0px;
left: 0px;
}
JS
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "My First Chart in CanvasJS"
},
backgroundColor: "transparent",
data: [{
// Change type to "doughnut", "line", "splineArea", etc.
type: "doughnut",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
var chart = new CanvasJS.Chart("chartContainerpie", {
backgroundColor: "transparent",
data: [{
// Change type to "doughnut", "line", "splineArea", etc.
indexLabelPlacement: "inside",
indexLabelFontColor: "white",
indexLabelFontSize: "14px",
type: "pie",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
Here is fiddle