I'm just getting some experience with Google Charts and I'm having a hard time understanding the difference between setting a width and height in the chart options vs. setting the width and height in the chart area settings. For example, I've seen this done:
var options = {
width: '500px',
height: '400px',
chartArea: {
left: "15%",
top: "5%",
height: "80%",
width: "75%"
},
//chartArea: { top: 10, left: 80, bottom: 50 },
legend: { position: 'bottom', alignment: 'start' },
annotations: { alwaysOutside: true},
hAxis: {
gridlines: { count: 10 },
},
If I had to guess, this is telling Google Charts to use a 'canvas' size of 500 x 400 pixels but the chart itself should only consume 75% of the width of that and 80% of the height. Is this correct?
chart options height & width are for the entire chart in respect to the chart's container,
including axis labels, titles, legends, etc...
option chartArea is for the inside portion of the chart,
where the plot actually occurs, excluding any labels on the edges...
the following options will stretch the chart to the full width and height of the chart's container,
and stretch the chart area to the full width and height of the chart,
leaving room on the edges for the labels (top, left, bottom, right)
chartArea: {
height: '100%',
width: '100%',
top: 32,
left: 32,
bottom: 32,
right: 16
},
height: '100%',
width: '100%',
see following working snippet...
google.charts.load('current', {
packages: ['controls', 'corechart']
}).then(function () {
var chart = new google.visualization.ChartWrapper({
chartType: 'ScatterChart',
containerId: 'chart',
dataTable: google.visualization.arrayToDataTable([
['x', 'y'],
[10, 15],
[15, 13],
[18, 20],
[24, 26],
[34, 30],
[40, 43],
[49, 48],
[50, 55],
[65, 67],
[70, 70],
[72, 70],
[73, 70],
[80, 85]
]),
options: {
chartArea: {
height: '100%',
width: '100%',
top: 32,
left: 32,
bottom: 32,
right: 16
},
height: '100%',
width: '100%',
legend: {
position: 'top'
}
}
});
chart.draw();
window.addEventListener('resize', function () {
chart.draw();
}, false);
});
html, body {
height: 100%;
margin: 0px 0px 0px 0px;
overflow: hidden;
padding: 0px 0px 0px 0px;
}
.chart {
height: 100%;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="chart" id="chart"></div>
Related
In Apache Echarts, when using multiple pie charts (e.g. nested pies, or even side-by-side pies), how do we add a title to each pie to signify what the pie represents? While the "title" option can accept an array of titles, there isn't a good way to position them so that they are above, within or in some other way related to the respective pies they are meant to label. It's as if there's a missing concept of a seriesLabel / seriesTitle that sits conceptually between the chart title and the individual item labels.
Series item labels are already in use for the items (pie slices) so cannot be used with position: center, and that wouldn't help with nested pies anyway since there's only room for one label at the center.
Here are my nested pies. I used an image editor to add labels where I might want them - hugging the pies they each label. That's what I'm trying to accomplish.
I do not understand what is your problem with the array of titles...
Here is a simple example showing how to give a title to each pie:
const data = [
{
name: 'Foo',
value: 10
},
{
name: 'Bar',
value: 20
},
{
name: 'Baz',
value: 15
}
];
let option = {
title: [
{
text: 'Pie 1',
subtext: 'Left',
left: '46px',
textAlign: 'center'
},
{
text: 'Pie 2',
subtext: 'Center',
left: '146px',
textAlign: 'center'
},
{
text: 'Pie 3',
subtext: 'Right',
left: '246px',
textAlign: 'center'
}
],
series: [
{
type: 'pie',
radius: '42px',
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
left: 0,
right: '66%',
top: 0,
bottom: 0
},
{
type: 'pie',
radius: '42px',
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
left: '33%',
right: '33%',
top: 0,
bottom: 0
},
{
type: 'pie',
radius: '42px',
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
left: '66%',
right: 0,
top: 0,
bottom: 0
}
]
};
let myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
#main {
width: 300px;
height: 200px;
}
<script src="https://cdn.jsdelivr.net/npm/echarts#5.4.1/dist/echarts.min.js"></script>
<div id="main"></div>
EDIT 1
Same example with nested pies:
const data = [
{
name: 'Foo',
value: 10
},
{
name: 'Bar',
value: 20
},
{
name: 'Baz',
value: 15
}
];
let option = {
title: [
{
text: 'Pie 1',
left: '48%',
textAlign: 'center'
},
{
text: 'Pie 2',
left: '48%',
top: '26%',
textAlign: 'center'
}
],
series: [
{
type: 'pie',
radius: ['120px', '90px'],
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
top: '10px'
},
{
type: 'pie',
radius: '42px',
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
top: '10px'
}
]
};
let myChart = echarts.init(document.getElementById('main'));
myChart.setOption(option);
#main {
width: 300px;
height: 300px;
}
<script src="https://cdn.jsdelivr.net/npm/echarts#5.4.1/dist/echarts.min.js"></script>
<div id="main"></div>
EDIT 2
If you want something completely responsive with nested pies, indeed, I do not know the recipe using a simple array of titles...
But you can do this somehow creating two containers, which means each pie will be in its own <canvas> element. Then you can use CSS to give your inner pie an absolute position.
There is extra work to handle the behavior of both charts on resize. Your <canvas> elements should always be squares. In other words, their width and height should stay equal.
When you resize the window, you have to get its width and height to determine if you have a horizontal display or a vertical one. In both cases, take the smallest value and resize outer and inner containers (width and height) with it. You can even get a variable font size thanks to this value.
Of course, you should avoid px in your options. Prefer % instead.
Here is the code:
const data = [
{
name: 'Foo',
value: 10
},
{
name: 'Bar',
value: 20
},
{
name: 'Baz',
value: 15
}
];
let outerOption = {
title: {
text: 'Pie 1',
top: '2%',
left: '50%',
textAlign: 'center'
},
series: [
{
type: 'pie',
radius: ['100%', '80%'],
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
top: '10%'
}
]
};
let innerOption = {
title: {
text: 'Pie 2',
top: '25%',
left: '50%',
textAlign: 'center'
},
series: [
{
type: 'pie',
radius: '50%',
center: ['50%', '50%'],
data,
label: {
position: 'inner'
},
top: '10%'
}
]
};
let outerChart = echarts.init(document.getElementById('outer')),
innerChart = echarts.init(document.getElementById('inner'));
outerChart.setOption(outerOption);
innerChart.setOption(innerOption);
function resize(container, size) {
container.resize({
width: size,
height: size
});
container.setOption({
title: {
textStyle: {
fontSize: Math.round(size / 20)
}
}
});
}
['load', 'resize'].forEach(event => {
window.addEventListener(event, () => {
let width = window.innerWidth,
height = window.innerHeight,
size = width;
if (width > height) {
size = height;
}
resize(outerChart, size);
resize(innerChart, size);
});
});
body {
margin: 0;
}
#outer, #inner {
width: 100vh;
height: 100vh;
}
#inner {
position: absolute;
top: 0;
left: 0;
}
<script src="https://cdn.jsdelivr.net/npm/echarts#5.4.1/dist/echarts.min.js"></script>
<div id="outer"></div>
<div id="inner"></div>
I am trying to create a scrollbar like the one below using echarts
So far I have managed to get the scroll using dataZoom feature but I haven't been able to style it like a normal scroll bar.
const dataY = [
'a',
'b',
'v',
'd',
'e',
'f',
'x',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n'
]; // 名称
const dataX = [
20, 50, 15, 35, 50, 30, 40, 50, 60, 20, 50, 15, 35, 50, 30, 40, 50, 60
]; // 数据
option = {
backgroundColor: '#1C1C1C',
grid: {
top: '10%',
right: '10%',
left: '10%',
bottom: '10%'
},
yAxis: [
{
type: 'category',
data: dataY,
axisLine: {
lineStyle: {
color: '#333333'
}
},
axisLabel: {
interval: 0,
margin: 10,
color: '#999999',
textStyle: {
fontSize: 11
},
rotate: '0'
},
axisTick: {
show: false
}
}
],
xAxis: [
{
axisLabel: {
padding: [3, 0, 0, 0],
formatter: '{value}',
color: '#999999',
textStyle: {
fontSize: 11
}
},
axisTick: {
show: true
},
axisLine: {
lineStyle: {
color: '#333333'
}
},
splitLine: {
lineStyle: {
color: '#333333'
}
}
}
],
dataZoom: [
{
type: 'slider',
yAxisIndex: 0,
zoomLock: true,
width: 5,
right: 10,
top: '10%',
bottom: '10%',
start: 70,
end: 20,
brushSelect: false,
handleSize: '60%',
showDetail: false,
backgroundColor: '#000',
borderColor: '#000',
opacity: 1,
brushStyle: false,
handleStyle: {
color: '#FF6700',
borderColor: '#FF6700'
}
},
{
type: 'inside',
id: 'insideY',
yAxisIndex: 0,
start: 15,
end: 20,
zoomOnMouseWheel: false,
moveOnMouseMove: true,
moveOnMouseWheel: true,
backgroundColor: 'transparent'
}
],
series: [
{
type: 'bar',
data: dataX,
barWidth: '5',
itemStyle: {
normal: {
color: '#FF6700',
shadowBlur: 4,
borderRadius: 100
}
},
label: {
normal: {
show: false,
lineHeight: 4,
formatter: '{c}',
position: 'top',
textStyle: {
color: '#fff',
fontSize: 10
}
}
}
}
]
};
I am left with a weird scrollbar that works as it should be unfortunately looks really weird.
I had the exact same issue as you, and i found a turnaround.
Instead of using the datazoom from ECharts as a scrollbar, you can just use the overflow of the div of the chart, and you can costumize it as you want with css. First you need to comment or delete the part of the datazoom in you code and change the html and css as this:
<div class="grid" [style.width.%]="100" [style.height.%]="100" #wrapper>
<div class="ChartDiv" echarts [options]="options" [style.width.px]="ganttWidth" [style.height.px]="ganttHeight"></div>
</div>
Then you just have to define the css like this:
.grid {
overflow-y: scroll !important;
//hidden if you dont want the x-Axis to have a scroll
overflow-x: hidden !important;
}
//Change the css as you want
::-webkit-scrollbar {
width: 16px;
}
::-webkit-scrollbar-track {
background-color: #e4e4e4;
border-radius: 100px;
}
With this code, your graph will have this aspect:
Now you just need to change your css as you want the style of this xD.
I'm having trouble on getting the events to work on my chart. I need to get the value of selected area of my parallel coordinates chart. I tried using chartDataRangeSelected but it does nothing when I select some data.
Here's my code:
<div echarts [options]="chartOption" class="demo-chart" (chartInit)="onChartInit($event)" (chartDataRangeSelected)="onChartSelect($event)"></div>
Chart config:
chartOption: EChartOption = {
title: {
text: 'Demo Parallel Coordinates',
subtext: 'data from macrofocus',
left: 'center',
top: 5,
itemGap: 0,
textStyle: {
color: '#000000'
},
z: 200
},
parallelAxis: this.makeParallelAxis(this.schema),
grid: [{
show: true,
left: 0,
right: 0,
top: '0',
bottom: 0,
borderColor: 'transparent',
backgroundColor: 'white',
z: 99
}],
parallel: {
top: '10%',
left: 100,
right: 100,
bottom: 100,
axisExpandable: true,
axisExpandCenter: 15,
axisExpandCount: 10,
axisExpandWidth: 60,
axisExpandTriggerOn: 'mousemove',
z: 100,
parallelAxisDefault: {
type: 'value',
nameLocation: 'start',
nameRotate: 25,
// nameLocation: 'end',
nameTextStyle: {
fontSize: 12
},
nameTruncate: {
maxWidth: 170
},
nameGap: 20,
splitNumber: 3,
tooltip: {
show: true
},
axisLine: {
// show: false,
lineStyle: {
width: 1,
color: '#000000'
}
},
axisTick: {
show: false
},
splitLine: {
show: false
},
z: 100
}
},
series: [
{
name: 'parallel',
type: 'parallel',
smooth: true,
lineStyle: {
color: '#577ceb',
width: 0.5,
opacity: 0.6
},
z: 100,
data: this.rawData
}
]
};
Function:
onChartSelect(e){
console.log(e);
}
Am I using the correct events for doing so? Your help will be much appreciated.
Thanks
according to eCharts document,
the selectDataRange Event emitted after range is changed in visualMap. https://www.echartsjs.com/en/api.html#events.datarangeselected,
which is chartDataRangeSelected of ngx-echarts mapped to.
And you can see that, it is an event related to visualMap. your charts does not have a visual map at all, so i guess the event will not be fired.
You can try chartAxisAreaSelected, as this is more related to your chart.
When i create google donut chart by using the following html code
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 50],
['Eat', 50],
['Commute', 5],
]);
var options = {
title: 'My Daily Activities',
pieHole: 0.63,
enableInteractivity: false,
chartArea: {left: 5, right: 5, top: 5, bottom: 5, width: "100%", height: "100%"},
tooltip: {trigger: 'none'},
sliceVisibilityThreshold: 0,
pieSliceBorderColor: "#FFBE33",
slices: {
0: {
color: '#FFBE33',
textStyle: {bold: false, fontSize: 12, color: 'white'}
},
1: {
color: 'blue',
textStyle: {bold: false, fontSize: 12, color: 'white'}
},
2: {
color: 'black',
textStyle: {bold: false, fontSize: 12, color: 'white'}
}
}
};
var chart = new google.visualization.PieChart(document.getElementById('donutchart'));
chart.draw(data, options);
}
it produce the output like this:
when i give <5 value ,it does not shows percentage value on donut chart. But when i give >5 value means it shows correctly.
how can i display the percentage value outside or inside the donut chart like this?
I have to create a google area chart that has one line with the background fill but then also have additional lines that overlay it with no background fill. I can't figure out how to do this and am hopeful someone here knows. In the example image below the dashed blue lines are the ones I'm trying to figure out how to create.
you can use a ComboChart,
with both line and area series.
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Month', 'Area', 'Line 0', 'Line 1', 'Line 2', 'Line 3'],
['Apr', 70000, 18000, 42000, 80000, 118000],
['May', 90000, 18000, 42000, 80000, 118000],
['Jun', 100000, 18000, 42000, 80000, 118000],
['Jul', 75000, 18000, 42000, 80000, 118000],
['Aug', 60000, 18000, 42000, 80000, 118000],
['Sep', 20000, 18000, 42000, 80000, 118000]
]);
var options = {
chartArea: {
height: '100%',
width: '100%',
top: 48,
left: 72,
right: 16,
bottom: 60
},
height: '100%',
width: '100%',
seriesType: 'line',
series: {0: {type: 'area'}},
colors: ['orange', 'blue', 'blue', 'blue', 'blue']
};
var chart = new google.visualization.ComboChart(document.getElementById('chart'));
drawChart();
window.addEventListener('resize', drawChart, false);
function drawChart() {
chart.draw(data, options);
}
});
html, body {
height: 100%;
margin: 0px 0px 0px 0px;
overflow: hidden;
padding: 0px 0px 0px 0px;
}
#chart {
height: 100%;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>