chart.js 3.7.1 where to go with my plugins? - plugins

I switched from chart.js 2.9.3 to 3.7.1 and some options do not work anymore. If I see it right the options like "Legend" and also "tooltips" went to plugin under "options"?
But it does not work for me. I want to hide the Legend and customize the tooltips.
Where do the plugins go? Any help would be great.
Thank you,
Michael
const titleTooltip_diagramm_fokus = (tooltipItems) => {return "Betroffen";};
const labelTooltip_diagramm_fokus = (tooltipItems) => {return "Tooltip";};
const data_diagramm_fokus = {
datasets: [{
label: ["Positive Value"],
backgroundColor: "rgba(255,0,0,0.2)",
borderColor: "#000",
data: [{
x: 10,
y: 9,
r: 10
}]
},{
label: ["Negative Value"],
backgroundColor: "rgba(255,0,0,0.2)",
borderColor: "#000",
data: [{
x: -5,
y: -5,
r: 5
}]
},{
label: ["Beteiligte / Rollen 3"],
backgroundColor: "rgba(255,0,0,0.2)",
borderColor: "#000",
data: [{
x: -10,
y: -9,
r: 6
}]
},
]};
const options_diagramm_fokus = {
responsive: true,
maintainAspectRatio: true,
title: {
display: false,
text: "Identifiziere die größten fokus"
},
scales: {
yAxes: [{
ticks: {
beginAtZero: false,
max: 10,
min: -10
},
scaleLabel: {
display: true,
labelString: "schwacher Einfluss / starker Einfluss"
}
}],
xAxes: [{
ticks: {
beginAtZero: false,
max: 10,
min: -10
},
scaleLabel: {
display: true,
labelString: "starke Unterstützung / starker Zweifel"
}
}]
},
plugins:{
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var rLabel = (data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].r - 2);
var label = data.datasets[tooltipItem.datasetIndex].label || "";
if (label) {
label += ": ";
}
label += "(" + tooltipItem.xLabel + " / ";
label += tooltipItem.yLabel + ") | ";
label += "Betroffenheit: " + rLabel;
return label;
}
}
}
}
};
const plugin_diagramm_fokus = {
id: "plugin_diagramm_fokus",
beforeDraw(chart, args, options) {
const {ctx, chartArea: {left, top, right, bottom}, scales: {x, y}} = chart;
const midX = x.getPixelForValue(0);
const midY = y.getPixelForValue(0);
ctx.save();
ctx.fillStyle = options.topLeft;
ctx.fillRect(left, top, midX - left, midY - top);
ctx.fillStyle = options.topRight;
ctx.fillRect(midX, top, right - midX, midY - top);
ctx.fillStyle = options.bottomRight;
ctx.fillRect(midX, midY, right - midX, bottom - midY);
ctx.fillStyle = options.bottomLeft;
ctx.fillRect(left, midY, midX - left, bottom - midY);
ctx.restore();
}
};
const config_diagramm_fokus = {
type: "bubble",
data: data_diagramm_fokus,
options: {
options_diagramm_fokus,
plugins: {
plugin_diagramm_fokus: {
topLeft: "#9DC3E6",
topRight: "#2E75B6",
bottomRight: "#BDD7EE",
bottomLeft: "#DEEBF7",
}
}
},
plugins: [plugin_diagramm_fokus]
};
const diagramm_fokus = new Chart(
document.getElementById("diagramm_fokus").getContext("2d"),
config_diagramm_fokus,
);
<h2>
Hello!
</h2>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="diagramm_fokus"></canvas>

This is because your options where totally wrong, the options does not have an options object in it and a plugins object. The options object is an object with all the options in it. So if you have a custom plugin you also need to define it in there. Rest of your config is also still wrong with lot of V2 syntax like the title, and scales config. For all changes please read the migration guide
const titleTooltip_diagramm_fokus = (tooltipItems) => {
return "Betroffen";
};
const labelTooltip_diagramm_fokus = (tooltipItems) => {
return "Tooltip";
};
const data_diagramm_fokus = {
datasets: [{
label: ["Positive Value"],
backgroundColor: "rgba(255,0,0,0.2)",
borderColor: "#000",
data: [{
x: 10,
y: 9,
r: 10
}]
}, {
label: ["Negative Value"],
backgroundColor: "rgba(255,0,0,0.2)",
borderColor: "#000",
data: [{
x: -5,
y: -5,
r: 5
}]
}, {
label: ["Beteiligte / Rollen 3"],
backgroundColor: "rgba(255,0,0,0.2)",
borderColor: "#000",
data: [{
x: -10,
y: -9,
r: 6
}]
}, ]
};
const options_diagramm_fokus = {
responsive: true,
maintainAspectRatio: true,
title: {
display: false,
text: "Identifiziere die größten fokus"
},
scales: {
yAxes: [{
ticks: {
beginAtZero: false,
max: 10,
min: -10
},
scaleLabel: {
display: true,
labelString: "schwacher Einfluss / starker Einfluss"
}
}],
xAxes: [{
ticks: {
beginAtZero: false,
max: 10,
min: -10
},
scaleLabel: {
display: true,
labelString: "starke Unterstützung / starker Zweifel"
}
}]
},
plugins: {
legend: {
display: false
},
plugin_diagramm_fokus: {
topLeft: "#9DC3E6",
topRight: "#2E75B6",
bottomRight: "#BDD7EE",
bottomLeft: "#DEEBF7",
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var rLabel = (data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].r - 2);
var label = data.datasets[tooltipItem.datasetIndex].label || "";
if (label) {
label += ": ";
}
label += "(" + tooltipItem.xLabel + " / ";
label += tooltipItem.yLabel + ") | ";
label += "Betroffenheit: " + rLabel;
return label;
}
}
}
}
};
const plugin_diagramm_fokus = {
id: "plugin_diagramm_fokus",
beforeDraw(chart, args, options) {
const {
ctx,
chartArea: {
left,
top,
right,
bottom
},
scales: {
x,
y
}
} = chart;
const midX = x.getPixelForValue(0);
const midY = y.getPixelForValue(0);
ctx.save();
ctx.fillStyle = options.topLeft;
ctx.fillRect(left, top, midX - left, midY - top);
ctx.fillStyle = options.topRight;
ctx.fillRect(midX, top, right - midX, midY - top);
ctx.fillStyle = options.bottomRight;
ctx.fillRect(midX, midY, right - midX, bottom - midY);
ctx.fillStyle = options.bottomLeft;
ctx.fillRect(left, midY, midX - left, bottom - midY);
ctx.restore();
}
};
const config_diagramm_fokus = {
type: "bubble",
data: data_diagramm_fokus,
options: options_diagramm_fokus,
plugins: [plugin_diagramm_fokus]
};
const diagramm_fokus = new Chart(
document.getElementById("diagramm_fokus").getContext("2d"),
config_diagramm_fokus,
);
<h2>
Hello!
</h2>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="diagramm_fokus"></canvas>

Related

Using ChartJS to create a multiple grouped bar chart - see picture below

I am testing out HighCharts and ChartJS to see which to use. For Highcharts, I was able to find a hack to create a bar chart that had double grouping on the x-axis.
This is what I want to look like:
I am new to both charting JS options and wonder if there is a way to do this in ChartJS.
I have the datasets something like this:
xAxis: {
categories: [{
name: "Total",
categories: ["2004", "2008", "2012"]
}, {
name: "Lower than 2.50",
categories: ["2004", "2008", "2012"]
}]
},
yAxis: {
min: 0,
title: {
text: 'Percent (%)'
}
},
series: [{
name: 'Male',
data: [42.4, 43.0, 43.0, 50.3, 49.4, 48.4]
}, {
name: 'Female',
data: [57.6, 57.0, 57.0, 49.7, 50.6, 51.6]
}]
Essentially I need a nest series on the x-axis and I am open to plugins or code from Github to do this.
You can make use of the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code, I use the afterDraw hook to draw the category labels and the delimiter lines.
new Chart('myChart', {
type: 'bar',
plugins: [{
afterDraw: chart => {
let ctx = chart.chart.ctx;
ctx.save();
let xAxis = chart.scales['x-axis-0'];
let xCenter = (xAxis.left + xAxis.right) / 2;
let yBottom = chart.scales['y-axis-0'].bottom;
ctx.textAlign = 'center';
ctx.font = '12px Arial';
ctx.fillText(chart.data.categories[0], (xAxis.left + xCenter) / 2, yBottom + 40);
ctx.fillText(chart.data.categories[1], (xCenter + xAxis.right) / 2, yBottom + 40);
ctx.strokeStyle = 'lightgray';
[xAxis.left, xCenter, xAxis.right].forEach(x => {
ctx.beginPath();
ctx.moveTo(x, yBottom);
ctx.lineTo(x, yBottom + 40);
ctx.stroke();
});
ctx.restore();
}
}],
data: {
labels: ['2004', '2008', '2012', '2016', '2004', '2008', '2012', '2016'],
categories: ['Total', 'Lower than 2.50'],
datasets: [{
label: 'Male',
data: [42.4, 43.0, 43.0, 50.3, 49.4, 48.4, 51.2, 51.8],
backgroundColor: 'rgba(124, 181, 236, 0.9)',
borderColor: 'rgb(124, 181, 236)',
borderWidth: 1
},
{
label: 'Female',
data: [57.6, 57.0, 57.0, 49.7, 50.6, 51.6, 53.7, 54.6],
backgroundColor: 'rgba(67, 67, 72, 0.9)',
borderColor: 'rgb(67, 67, 72)',
borderWidth: 1
}
]
},
options: {
legend: {
position: 'bottom',
labels: {
padding: 30,
usePointStyle: true
}
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 80,
stepSize: 20
},
scaleLabel: {
display: true,
labelString: 'Percent (%)'
}
}],
xAxes: [{
gridLines: {
drawOnChartArea: false
}
}]
}
}
});
canvas {
max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>
You have to define a second x-axis and play around with the many ticks and gridLines options.
Please take a look at below runnable code and see how it could be done. This is obviously only a draft and needs to optimized and made more generic.
new Chart(document.getElementById('myChart'), {
type: 'bar',
data: {
labels: ['2004', '2008', '2012', '2004', '2008', '2012'],
datasets: [{
label: 'Male',
data: [42.4, 43.0, 43.0, 50.3, 49.4, 48.4],
backgroundColor: 'rgba(124, 181, 236, 0.9)',
borderColor: 'rgb(124, 181, 236)',
borderWidth: 1
},
{
label: 'Female',
data: [57.6, 57.0, 57.0, 49.7, 50.6, 51.6],
backgroundColor: 'rgba(67, 67, 72, 0.9)',
borderColor: 'rgb(67, 67, 72)',
borderWidth: 1
}
]
},
options: {
legend: {
position: 'bottom',
labels: {
usePointStyle: true
}
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 80,
stepSize: 20
},
scaleLabel: {
display: true,
labelString: 'Percent (%)'
}
}],
xAxes: [{
gridLines: {
drawOnChartArea: false
}
},
{
offset: true,
ticks: {
autoSkip: false,
maxRotation: 0,
padding: -15,
callback: (v, i) => {
if (i == 1) {
return 'Total';
} else if (i == 4) {
return 'Lower than 2.50';
} else {
return '';
}
}
},
gridLines: {
drawOnChartArea: false,
offsetGridLines: true,
tickMarkLength: 20,
color: ['white', 'white', 'white', 'lightgray', 'white', 'white', 'lightgray']
}
}
]
}
}
});
canvas {
max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

Echarts:how to set markLine lable above the line and at the end of the line?

In echarts-3.6.2, when I set position:'end' for markLine, the lable will display at the end of line
markLine: {
data: [{
symbol:"none",
name: 'GOAL',
yAxis: 3.12 ,
label:{
normal:{
show:true,
position:'end'
}
},
lineStyle: {
normal: {
color: '#5C57FF',
width: 2
}
},
}]
},
However, I want to dislay it above the line at the end of the line? How to make it?
Change position value to insideEndTop(see in docs):
markLine: {
data: [{
symbol: "none",
name: 'GOAL',
yAxis: 3.12,
label: {
normal: {
show: true,
position: 'insideEndTop'
}
},
lineStyle: {
normal: {
color: '#5C57FF',
width: 2
}
},
}]
},
hello,do you have any ideas for not using position: 'insideEndTop', I could not upgrade the echarts plugin
I can't help without a crutch/workaround because it's very old version. You need to update the Echarts immediately, it's only right way. Or you can try to simulate markLine with the graphic component, something like below but it's highway to hell.
var myChart = echarts.init(document.getElementById('main'));
var option = {
color: ['rgba(92, 87, 255, 0.3)'],
grid: {
left: 50,
bottom: 50,
},
graphic: [{
type: 'group',
id: 'markLine',
bounding: 'raw',
children: [{
id: 'lineShape',
$action: 'replace',
type: 'line',
invisible: true,
shape: {
x1: 50,
y1: 300,
x2: 120,
y2: 300,
},
style: {
stroke: '#5C57FF',
lineWidth: 2,
},
zlevel: 10,
}, {
type: 'polygon',
$action: 'replace',
id: 'arrowShape',
invisible: true,
scale: [0.5, 0.3],
position: [90, 292.5],
shape: {
points: [
[16, 5],
[16, 47],
[38, 26]
]
},
style: {
fill: '#5C57FF',
}
}, {
type: 'text',
$action: 'replace',
id: 'labelShape',
invisible: true,
style: {
text: 'GOAL: 3.12',
x: -100,
y: 290,
fill: '#5C57FF',
font: 'bolder 12px sans-serif',
},
zlevel: 10,
}],
}],
xAxis: {
data: ["1", "2", "3", "4", "5", "6"]
},
yAxis: {
type: 'value',
max: 50
},
series: [{
name: 'Series',
type: 'bar',
data: [5, 20, 36, 10, 10, 20],
}]
};
myChart.setOption(option);
function renderMarkLine({ instance, yAxisValue, text, speed }){
var currentStep = 0;
var arrowShape = (val) => {
return {
stopCoord: 710, // 525
opts: {
invisible: false,
id: 'arrowShape',
position: [5 + val, yAxisValue - 7.5] // yAxisValue + 7.5
}
}
};
var lineShape = (val) => {
return {
stopCoord: 680, //540
opts: {
id: 'lineShape',
invisible: false,
shape: {
x1: 50,
y1: yAxisValue, // +0
x2: 50 + val,
y2: yAxisValue
}
}
}
};
var labelShape = (val) => {
return {
stopCoord: 660, // 460
opts: {
id: 'labelShape',
invisible: false,
style: {
x: -10 + val,
y: yAxisValue - 10, // 10
fill: '#5C57FF',
font: 'bolder 12px sans-serif'
}
}
}
};
var interval = setInterval(function(){
var graphicData = [];
[arrowShape, lineShape, labelShape].forEach(el => {
if (el(null).stopCoord > currentStep){
graphicData.push(el(currentStep).opts);
}
});
if (graphicData.length === 0) clearInterval(interval);
instance.setOption({ graphic: graphicData });
currentStep += 10;
}, speed);
};
renderMarkLine({ instance: myChart, yAxisValue: 500, speed: 0 });
<script src="https://cdn.jsdelivr.net/npm/echarts#3.6.2/dist/echarts.min.js"></script>
<div id="main" style="width:800px;height:600px;"></div>

How to update the echarts plot theme dynamicaly

Can someone explain to me how to toggle from light to dark theme without reloading the page??
I have this code that checks if the theme is light or dark and I want to change the theme dynamically base on the theme.
my code so far
initECharts(days: any, hours: any, data: any) {
if (this._chart) {
this._chart.clear();
this._chart = null;
}
// console.log('days: ', this.days);
// console.log('hours: ', this.hours);
// console.log('values: ', this.values);
data = this.reconstructData(days, hours, data);
// const x: any = document.getElementById('main');
const theme = (this._themeService.theme === 'dark') ? 'dark' : 'light';
console.log('theme', theme);
const domEl: any = this.main.nativeElement;
this._chart = echarts.init(domEl, theme);
// specify chart configuration item and data
const option: any = {
tooltip: {
position: 'top'
},
animation: false,
grid: {
height: '50%',
y: '10%'
},
xAxis: {
type: 'category',
data: hours,
splitArea: {
show: true
},
nameTextStyle: {
color: 'red'
}
},
yAxis: {
type: 'category',
data: days,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 10,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '15%'
},
series: [{
name: 'Punch Card',
type: 'heatmap',
data: data,
label: {
normal: {
show: true
}
},
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
// use configuration item and data specified to show chart
this._chart.setOption(option);
}
Ok, I found it.
every time you want to update the theme dynamically example a button or an observable or Promise, you must call this method
echarts.dispose(this._chart);
then you call the initMethod, example:
this.initECharts();
The init method can look like this in my case.
initECharts(days: any, hours: any, data: any) {
data = this.reconstructData(days, hours, data);
// const x: any = document.getElementById('main');
const theme = (this._themeService.theme === 'dark') ? 'dark' : 'light';
console.log('theme', theme);
const domEl: any = this.main.nativeElement;
this._chart = echarts.init(domEl, theme);
// specify chart configuration item and data
const option: any = {
tooltip: {
position: 'top'
},
animation: false,
grid: {
height: '50%',
y: '10%'
},
xAxis: {
type: 'category',
data: hours,
splitArea: {
show: true
},
nameTextStyle: {
color: 'red'
}
},
yAxis: {
type: 'category',
data: days,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 10,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '15%'
},
series: [{
name: 'Punch Card',
type: 'heatmap',
data: data,
label: {
normal: {
show: true
}
},
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
// use configuration item and data specified to show chart
this._chart.setOption(option);
}

Highmaps mappies with drilldown

I need to do a drilldown of mappies, from country to states:
https://www.highcharts.com/maps/demo/map-pies
Actually I am using a custom map from Peru, but already with the example of USA would help me a lot showing me some solution.
Is it possible to do this?
I've made an example with mappie and drilldown to show you how to start and achieve it. I've added drilldown for California so only this state will work.
Add drilldown module: https://code.highcharts.com/maps/modules/drilldown.js
Each point should have a drilldown property set. You can add it to a point object or to data array (then keys array in series should point to it. API: https://api.highcharts.com/highmaps/plotOptions.series.keys)
When drilldown event occurs hide or remove each mappie series and create it again on drillup event.
Code:
// New map-pie series type that also allows lat/lon as center option.
// Also adds a sizeFormatter option to the series, to allow dynamic sizing
// of the pies.
Highcharts.seriesType('mappie', 'pie', {
center: null, // Can't be array by default anymore
clip: true, // For map navigation
states: {
hover: {
halo: {
size: 5
}
}
},
dataLabels: {
enabled: false
}
}, {
getCenter: function() {
var options = this.options,
chart = this.chart,
slicingRoom = 2 * (options.slicedOffset || 0);
if (!options.center) {
options.center = [null, null]; // Do the default here instead
}
// Handle lat/lon support
if (options.center.lat !== undefined) {
var point = chart.fromLatLonToPoint(options.center);
options.center = [
chart.xAxis[0].toPixels(point.x, true),
chart.yAxis[0].toPixels(point.y, true)
];
}
// Handle dynamic size
if (options.sizeFormatter) {
options.size = options.sizeFormatter.call(this);
}
// Call parent function
var result = Highcharts.seriesTypes.pie.prototype.getCenter.call(this);
// Must correct for slicing room to get exact pixel pos
result[0] -= slicingRoom;
result[1] -= slicingRoom;
return result;
},
translate: function(p) {
this.options.center = this.userOptions.center;
this.center = this.getCenter();
return Highcharts.seriesTypes.pie.prototype.translate.call(this, p);
}
});
var data = [
// state, demVotes, repVotes, libVotes, grnVotes, sumVotes, winner, offset config for pies
['Alabama', 729547, 1318255, 44467, 9391, 2101660, -1],
['Alaska', 116454, 163387, 18725, 5735, 304301, -1],
['Arizona', 1161167, 1252401, 106327, 34345, 2554240, -1],
['Arkansas', 380494, 684782, 29829, 9473, 1104578, -1],
['California', 8577206, 4390272, 467370, 271047, 13705895, 1, {
lon: -1,
drawConnector: false
}, 'us-ca'],
['Colorado', 1338870, 1202484, 144121, 38437, 2723912, 1],
['Connecticut', 897572, 673215, 48676, 22841, 1642304, 1, {
lat: -1.5,
lon: 1
}],
['Delaware', 235603, 185127, 14757, 6103, 441590, 1, {
lat: -1.3,
lon: 2
}],
['District of Columbia', 282830, 12723, 4906, 4258, 304717, 1, {
lat: -2,
lon: 2
}],
['Florida', 4504975, 4617886, 207043, 64399, 9394303, -1],
['Georgia', 1877963, 2089104, 125306, 0, 4092373, -1],
['Hawaii', 266891, 128847, 15954, 12737, 424429, 1, {
lat: -0.5,
lon: 0.5,
drawConnector: false
}],
['Idaho', 189765, 409055, 28331, 8496, 635647, -1],
['Illinois', 2977498, 2118179, 208682, 74112, 5378471, 1],
['Indiana', 1039126, 1557286, 133993, 7841, 2738246, -1],
['Iowa', 653669, 800983, 59186, 11479, 1525317, -1],
['Kansas', 427005, 671018, 55406, 23506, 1176935, -1],
['Kentucky', 628854, 1202971, 53752, 13913, 1899490, -1],
['Louisiana', 780154, 1178638, 37978, 14031, 2010801, -1],
['Maine', 352156, 332418, 37578, 13995, 736147, 1],
['Maryland', 1502820, 878615, 78225, 33380, 2493040, 1, {
lon: 0.6,
drawConnector: false
}],
['Massachusetts', 1995196, 1090893, 138018, 47661, 3271768, 1, {
lon: 3
}],
['Michigan', 2268839, 2279543, 172136, 51463, 4771981, -1],
['Minnesota', 1367716, 1322951, 112972, 36985, 2840624, 1, {
lon: -1,
drawConnector: false
}],
['Mississippi', 462127, 678284, 14411, 3595, 1158417, -1],
['Missouri', 1054889, 1585753, 96404, 25086, 2762132, -1],
['Montana', 174281, 273879, 28036, 7868, 484064, -1],
['Nebraska', 273185, 485372, 38746, 8337, 805640, -1],
['Nevada', 539260, 512058, 37384, 0, 1088702, 1],
['New Hampshire', 348526, 345790, 30694, 6465, 731475, 1],
['New Jersey', 1967444, 1509688, 72143, 37131, 3586406, 1, {
lat: -1,
lon: 1.2
}],
['New Mexico', 380923, 316134, 74544, 9797, 781398, 1],
['New York', 4145376, 2638135, 162273, 100110, 7045894, 1],
['North Carolina', 2169496, 2345235, 130021, 1038, 4645790, -1],
['North Dakota', 93758, 216794, 21434, 378, 332364, -1],
['Ohio', 2320596, 2776683, 174266, 44310, 5315855, -1],
['Oklahoma', 420375, 949136, 83481, 0, 1452992, -1],
['Oregon', 991580, 774080, 93875, 49247, 1908782, 1],
['Pennsylvania', 2874136, 2945302, 144826, 49334, 6013598, -1],
['Rhode Island', 227062, 166454, 14700, 6171, 414387, 1, {
lat: -0.7,
lon: 1.7
}],
['South Carolina', 855373, 1155389, 49204, 13034, 2073000, -1],
['South Dakota', 117442, 227701, 20845, 0, 365988, -1],
['Tennessee', 868853, 1519926, 70286, 15952, 2475017, -1],
['Texas', 3877868, 4685047, 283492, 71558, 8917965, -1],
['Utah', 222858, 375006, 39608, 7695, 645167, -1],
['Vermont', 178573, 95369, 10078, 6758, 290778, 1, {
lat: 2
}],
['Virginia', 1981473, 1769443, 118274, 27638, 3896828, 1],
['Washington', 1727840, 1210370, 160356, 57571, 3156137, 1],
['West Virginia', 187519, 486304, 22958, 8016, 704797, -1],
['Wisconsin', 1382947, 1407028, 106470, 31016, 2927461, -1],
['Wyoming', 55973, 174419, 13287, 2515, 246194, -1]
],
maxVotes = 0,
demColor = 'rgba(74,131,240,0.80)',
repColor = 'rgba(220,71,71,0.80)',
libColor = 'rgba(240,190,50,0.80)',
grnColor = 'rgba(90,200,90,0.80)';
// Compute max votes to find relative sizes of bubbles
Highcharts.each(data, function(row) {
maxVotes = Math.max(maxVotes, row[5]);
});
// Build the chart
var chart = Highcharts.mapChart('container', {
chart: {
animation: false, // Disable animation, especially for zooming
events: {
load: function() {
addMapPie(this);
},
drilldown: function(e) {
if (!e.seriesOptions) {
var chart = this,
mapKey = 'countries/us/' + e.point.drilldown + '-all',
// Handle error, the timeout is cleared on success
fail = setTimeout(function() {
if (!Highcharts.maps[mapKey]) {
chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
fail = setTimeout(function() {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner
// Load the drilldown map
$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function() {
data = Highcharts.geojson(Highcharts.maps[mapKey]);
// Set a non-random bogus value
$.each(data, function(i) {
this.value = i;
});
chart.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.hide();
}
});
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
});
}
this.setTitle(null, {
text: e.point.name
});
},
drillup: function() {
this.setTitle(null, {
text: ''
});
this.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.show();
}
});
}
}
},
title: {
text: 'USA 2016 Presidential Election Results'
},
colorAxis: {
dataClasses: [{
from: -1,
to: 0,
color: 'rgba(244,91,91,0.5)',
name: 'Republican'
}, {
from: 0,
to: 1,
color: 'rgba(124,181,236,0.5)',
name: 'Democrat'
}, {
from: 2,
to: 3,
name: 'Libertarian',
color: libColor
}, {
from: 3,
to: 4,
name: 'Green',
color: grnColor
}]
},
mapNavigation: {
enabled: true
},
// Limit zoom range
yAxis: {
minRange: 2300
},
tooltip: {
useHTML: true
},
// Default options for the pies
plotOptions: {
mappie: {
borderColor: 'rgba(255,255,255,0.4)',
borderWidth: 1,
tooltip: {
headerFormat: ''
}
}
},
series: [{
mapData: Highcharts.maps['countries/us/us-all'],
data: data,
name: 'States',
borderColor: '#FFF',
showInLegend: false,
joinBy: ['name', 'id'],
keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes',
'sumVotes', 'value', 'pieOffset', 'drilldown'
],
tooltip: {
headerFormat: '',
pointFormatter: function() {
var hoverVotes = this.hoverVotes; // Used by pie only
return '<b>' + this.id + ' votes</b><br/>' +
Highcharts.map([
['Democrats', this.demVotes, demColor],
['Republicans', this.repVotes, repColor],
['Libertarians', this.libVotes, libColor],
['Green', this.grnVotes, grnColor]
].sort(function(a, b) {
return b[1] - a[1]; // Sort tooltip by most votes
}), function(line) {
return '<span style="color:' + line[2] +
// Colorized bullet
'">\u25CF</span> ' +
// Party and votes
(line[0] === hoverVotes ? '<b>' : '') +
line[0] + ': ' +
Highcharts.numberFormat(line[1], 0) +
(line[0] === hoverVotes ? '</b>' : '') +
'<br/>';
}).join('') +
'<hr/>Total: ' + Highcharts.numberFormat(this.sumVotes, 0);
}
}
}, {
name: 'Separators',
type: 'mapline',
data: Highcharts.geojson(Highcharts.maps['countries/us/us-all'], 'mapline'),
color: '#707070',
showInLegend: false,
enableMouseTracking: false
}, {
name: 'Connectors',
type: 'mapline',
color: 'rgba(130, 130, 130, 0.5)',
zIndex: 5,
showInLegend: false,
enableMouseTracking: false
}],
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
}
});
function addMapPie(chart) {
// Add the pies after chart load, optionally with offset and connectors
Highcharts.each(chart.series[0].points, function(state) {
if (!state.id) {
return; // Skip points with no data, if any
}
var pieOffset = state.pieOffset || {},
centerLat = parseFloat(state.properties.latitude),
centerLon = parseFloat(state.properties.longitude);
// Add the pie for this state
chart.addSeries({
type: 'mappie',
name: state.id,
zIndex: 6, // Keep pies above connector lines
sizeFormatter: function() {
var yAxis = this.chart.yAxis[0],
zoomFactor = (yAxis.dataMax - yAxis.dataMin) /
(yAxis.max - yAxis.min);
return Math.max(
this.chart.chartWidth / 45 * zoomFactor, // Min size
this.chart.chartWidth / 11 * zoomFactor * state.sumVotes / maxVotes
);
},
tooltip: {
// Use the state tooltip for the pies as well
pointFormatter: function() {
return state.series.tooltipOptions.pointFormatter.call({
id: state.id,
hoverVotes: this.name,
demVotes: state.demVotes,
repVotes: state.repVotes,
libVotes: state.libVotes,
grnVotes: state.grnVotes,
sumVotes: state.sumVotes
});
}
},
data: [{
name: 'Democrats',
y: state.demVotes,
color: demColor
}, {
name: 'Republicans',
y: state.repVotes,
color: repColor
}, {
name: 'Libertarians',
y: state.libVotes,
color: libColor
}, {
name: 'Green',
y: state.grnVotes,
color: grnColor
}],
center: {
lat: centerLat + (pieOffset.lat || 0),
lon: centerLon + (pieOffset.lon || 0)
}
}, false);
// Draw connector to state center if the pie has been offset
if (pieOffset.drawConnector !== false) {
var centerPoint = chart.fromLatLonToPoint({
lat: centerLat,
lon: centerLon
}),
offsetPoint = chart.fromLatLonToPoint({
lat: centerLat + (pieOffset.lat || 0),
lon: centerLon + (pieOffset.lon || 0)
});
chart.series[2].addPoint({
name: state.id,
path: 'M' + offsetPoint.x + ' ' + offsetPoint.y +
'L' + centerPoint.x + ' ' + centerPoint.y
}, false);
}
});
// Only redraw once all pies and connectors have been added
chart.redraw();
}
#container {
min-width: 320px;
max-width: 800px;
height: 500px;
margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/maps/modules/data.js"></script>
<script src="https://code.highcharts.com/maps/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://code.highcharts.com/mapdata/countries/us/us-all.js"></script>
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<div id="container"></div>
Demo:
https://jsfiddle.net/BlackLabel/1d845opk/1/
EDIT
To add mappies also to the first level of drilldown you have to remove mappies series form the main view of the map when drilldown event occurs and create new ones for drilled data. It's quite difficult to explain exactly how to make it, so I prepared an example where each drilled level has sample data (you can get them from a server the same as drilled map data). I hope this example will help and you will see what's going on there.
Demo:
http://jsfiddle.net/BlackLabel/zLcnby79/
Thank you Wojciech Chmiel !
I did my map with the help of your post.
// New map-pie series type that also allows lat/lon as center option.
// Also adds a sizeFormatter option to the series, to allow dynamic sizing
// of the pies.
Highcharts.seriesType('mappie', 'pie', {
center: null, // Can't be array by default anymore
clip: true, // For map navigation
states: {
hover: {
halo: {
size: 5
}
}
},
dataLabels: {
enabled: false
}
}, {
getCenter: function() {
var options = this.options,
chart = this.chart,
slicingRoom = 2 * (options.slicedOffset || 0);
if (!options.center) {
options.center = [null, null]; // Do the default here instead
}
// Replace lat/lon with plotX/plotY
if (options.center.plotX !== undefined) {
options.center = [options.center.plotX, options.center.plotY];
}
// Handle dynamic size
if (options.sizeFormatter) {
options.size = options.sizeFormatter.call(this);
}
// Call parent function
var result = Highcharts.seriesTypes.pie.prototype.getCenter.call(this);
// Must correct for slicing room to get exact pixel pos
result[0] -= slicingRoom;
result[1] -= slicingRoom;
return result;
},
translate: function (p) {
this.options.center = this.userOptions.center;
this.center = this.getCenter();
return Highcharts.seriesTypes.pie.prototype.translate.call(this, p);
}
});
var data = [
// state, demVotes, repVotes, libVotes, grnVotes, sumVotes, winner, drilldown
['CAPLINA-OCONA', 729547, 1318255, 44467, 9391, 2101660, -1, 'aaa01'],
['CHAPARRA-CHINCHA', 116454, 163387, 18725, 5735, 304301, -1, 'aaa02'],
['CANETE-FORTALEZA', 1161167, 1252401, 106327, 34345, 2554240, -1, 'aaa03'],
['HUARMEY-CHICAMA', 380494, 684782, 29829, 9473, 1104578, -1, 'aaa04'],
['JEQUETEPEQUE-ZARUMILLA', 8577206, 4390272, 467370, 271047, 13705895, 1, 'aaa05'],
['MARANON', 1338870, 1202484, 144121, 38437, 2723912, 1, 'aaa06'],
['AMAZONAS', 897572, 673215, 48676, 22841, 1642304, 1, 'aaa07'],
['HUALLAGA', 235603, 185127, 14757, 6103, 441590, 1, 'aaa08'],
['UCAYALI', 282830, 12723, 4906, 4258, 304717, 1, 'aaa09'],
['MANTARO', 4504975, 4617886, 207043, 64399, 9394303, -1, 'aaa10'],
['PAMPAS-APURIMAC', 1877963, 2089104, 125306, 0, 4092373, -1, 'aaa11'],
['URUBAMBA-VILCANOTA', 266891, 128847, 15954, 12737, 424429, 1, 'aaa12'],
['MADRE DE DIOS', 189765, 409055, 28331, 8496, 635647, -1, 'aaa13'],
['TITICACA', 2977498, 2118179, 208682, 74112, 5378471, 1, 'aaa14']
],
maxVotes = 0,
demColor = 'rgba(74,131,240,0.80)',
repColor = 'rgba(220,71,71,0.80)',
libColor = 'rgba(240,190,50,0.80)',
grnColor = 'rgba(90,200,90,0.80)';
// Compute max votes to find relative sizes of bubbles
Highcharts.each(data, function(row) {
maxVotes = Math.max(maxVotes, row[5]);
});
// Build the chart
var chart = Highcharts.mapChart('container', {
chart: {
animation: false, // Disable animation, especially for zooming
events: {
load: function() {
addMapPie(this);
},
drilldown: function(e) {
if (!e.seriesOptions) {
var chart = this,
//mapKey = 'countries/us/' + e.point.drilldown + '-all',
mapKey = 'paises/pe/' + e.point.drilldown,
ruta = e.point.drilldown,
// Handle error, the timeout is cleared on success
fail = setTimeout(function() {
if (!Highcharts.maps[mapKey]) {
chart.showLoading('<i class="icon-frown"></i> Failed loading ' + e.point.name);
fail = setTimeout(function() {
chart.hideLoading();
}, 1000);
}
}, 3000);
// Show the spinner
chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // Font Awesome spinner
// Load the drilldown map
//$.getScript('https://code.highcharts.com/mapdata/' + mapKey + '.js', function() {
//$.getScript('http://test1.ana.gob.pe/prueba-mappies/' + ruta + '.js', function () {
$.getScript('https://aplicaciones01.ana.gob.pe/mappies/' + ruta + '.js', function () {
data = Highcharts.geojson(Highcharts.maps[mapKey]);
// Set a non-random bogus value
$.each(data, function(i) {
this.value = i;
});
chart.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.hide();
}
});
// Hide loading and add series
chart.hideLoading();
clearTimeout(fail);
chart.addSeriesAsDrilldown(e.point, {
name: e.point.name,
data: data,
dataLabels: {
enabled: true,
format: '{point.name}'
}
});
});
}
this.setTitle(null, {
text: e.point.name
});
},
drillup: function() {
this.setTitle(null, {
text: ''
});
this.series.forEach(function(s) {
if (s.options.type === 'mappie') {
s.show();
}
});
}
}
},
title: {
text: 'Resultados'
},
colorAxis: {
dataClasses: [{
from: -1,
to: 0,
color: 'rgba(244,91,91,0.5)',
name: 'Republican'
}, {
from: 0,
to: 1,
color: 'rgba(124,181,236,0.5)',
name: 'Democrat'
}, {
from: 2,
to: 3,
name: 'Libertarian',
color: libColor
}, {
from: 3,
to: 4,
name: 'Green',
color: grnColor
}]
},
mapNavigation: {
enabled: true //Para el zoom (+ -)
},
// Limit zoom range
yAxis: {
minRange: 2300
},
tooltip: {
useHTML: true
},
// Default options for the pies
plotOptions: {
mappie: {
borderColor: 'rgba(255,255,255,0.4)',
borderWidth: 1,
tooltip: {
headerFormat: ''
}
}
},
series: [{
mapData: Highcharts.maps['paises/pe/aaa-all'],
data: data,
name: 'States',
borderColor: '#FFF',
showInLegend: false,
joinBy: ['name', 'id'],
//keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes',
// 'sumVotes', 'value', 'pieOffset'],
keys: ['id', 'demVotes', 'repVotes', 'libVotes', 'grnVotes', 'sumVotes', 'value', 'drilldown'],
tooltip: {
headerFormat: '',
pointFormatter: function () {
var hoverVotes = this.hoverVotes; // Used by pie only
return '<b>' + this.id + ' votes</b><br/>' +
Highcharts.map([
['Democrats', this.demVotes, demColor],
['Republicans', this.repVotes, repColor],
['Libertarians', this.libVotes, libColor],
['Green', this.grnVotes, grnColor]
].sort(function (a, b) {
return b[1] - a[1]; // Sort tooltip by most votes
}), function (line) {
return '<span style="color:' + line[2] +
// Colorized bullet
'">\u25CF</span> ' +
// Party and votes
(line[0] === hoverVotes ? '<b>' : '') +
line[0] + ': ' +
Highcharts.numberFormat(line[1], 0) +
(line[0] === hoverVotes ? '</b>' : '') +
'<br/>';
}).join('') +
'<hr/>Total: ' + Highcharts.numberFormat(this.sumVotes, 0);
}
}
}],
drilldown: {
activeDataLabelStyle: {
color: '#FFFFFF',
textDecoration: 'none',
textOutline: '1px #000000'
},
drillUpButton: {
relativeTo: 'spacingBox',
position: {
x: 0,
y: 60
}
}
}
});
function addMapPie(chart) {
// Add the pies after chart load, optionally with offset and connectors
Highcharts.each(chart.series[0].points, function(state) {
//if (!state.id) {
if (!state.id || !state.properties) {
return; // Skip points with no data, if any
}
var pieOffset = state.pieOffset || {},
centerLat = parseFloat(state.properties.latitude),
centerLon = parseFloat(state.properties.longitude);
// Add the pie for this state
chart.addSeries({
type: 'mappie',
name: state.id,
zIndex: 6, // Keep pies above connector lines
sizeFormatter: function () {
var yAxis = this.chart.yAxis[0],
zoomFactor = (yAxis.dataMax - yAxis.dataMin) /
(yAxis.max - yAxis.min);
return Math.max(
this.chart.chartWidth / 45 * zoomFactor, // Min size
this.chart.chartWidth / 11 * zoomFactor * state.sumVotes / maxVotes
);
},
/*****/
tooltip: {
// Use the state tooltip for the pies as well
pointFormatter: function () {
return state.series.tooltipOptions.pointFormatter.call({
id: state.id,
hoverVotes: this.name,
demVotes: state.demVotes,
repVotes: state.repVotes,
libVotes: state.libVotes,
grnVotes: state.grnVotes,
sumVotes: state.sumVotes
});
}
},
data: [{
name: 'Democrats',
y: state.demVotes,
color: demColor
}, {
name: 'Republicans',
y: state.repVotes,
color: repColor
}, {
name: 'Libertarians',
y: state.libVotes,
color: libColor
}, {
name: 'Green',
y: state.grnVotes,
color: grnColor
}],
center: {
/*lat: centerLat + (pieOffset.lat || 0),
lon: centerLon + (pieOffset.lon || 0)*/
plotX: state.plotX,
plotY: state.plotY
}
}, false);
});
// Only redraw once all pies and connectors have been added
chart.redraw();
}
#container {
min-width: 320px;
max-width: 800px;
height: 500px;
margin: 1em auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.15/proj4.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<script src="https://code.highcharts.com/maps/modules/exporting.js"></script>
<script src="https://code.highcharts.com/maps/modules/offline-exporting.js"></script>
<script src="https://aplicaciones01.ana.gob.pe/mappies/AAA_psad56_simp.js"></script>
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<div id="container"></div>
Here:
- https://jsfiddle.net/JMarcia/w06k5zog/17/

Semi donot chart with highcharts

I have been trying to achieve a chart like below using Highcharts library.
All i have been able to achieve is this http://jsfiddle.net/HpdwR/1489/ . So is there a way i could control how much the outer circle covers and its color. Also putting a title at the center of the chart.
Here is the config i have used to draw the chart
{
chart: {
renderTo: 'container',
type: 'pie'
},
title: {
text: 'Browser market share, April, 2011'
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
shadow: false
}
},
tooltip: {
formatter: function() {
return '<b>' + this.point.name + '</b>: ' + this.y + ' %';
}
},
series: [{
name: 'Browsers',
data: [
["Chrome", 70]
],
size: '60%',
innerSize: '60%',
showInLegend: true,
dataLabels: {
enabled: false
}
}]
}
I would also like to know if there are any other js libraries that could draw the same.
Tooltip Image
You can use solid-gauge type of chart with circle background (instead of default arc).
pane: {
center: ['50%', '50%'],
size: '100%',
startAngle: 0,
endAngle: 360,
background: {
backgroundColor: 'black',
innerRadius: '0%',
outerRadius: '80%',
shape: 'circle'
}
},
plotOptions: {
solidgauge: {
dataLabels: {
enabled: true,
y: -25,
borderWidth: 0,
useHTML: true,
format: '<div style="text-align:center"><span style="font-size:45px;color:#fff;">{y}</span><br/>' +
'<span style="font-size:12px;color:silver">%</span></div>'
}
}
},
Example:
http://jsfiddle.net/12kwyftq/1/
you can use start angle ,end angle to make it desired view
startAngle: -90,
endAngle: 90,
center: ['50%', '75%']
example fiddle