I have created a bar graph using the echarts library. How can I highlight the bar graph when the user clicks on a bar, or else apply the bar border when a bar is clicked?
Is there a way to highlight a bar when the click event is triggered for the bar?
Yes, there is a way to highlight a bar when click.
When the click event is triggered, you can get the exactly data(single bar) be clicked from the parameter, then you only need to change color(For example, decrease alpha) of this data to achieve the 'highlight' goal.
And don't forget recovery color of other data(not clicked) at same time.
check this demo
let echartsObj = echarts.init(document.querySelector('#canvas'));
option = {
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
}],
yAxis: [{
type: 'value'
}],
series: [{
name: '直接访问',
type: 'bar',
barWidth: '60%',
data: [{
value: 10,
itemStyle: {
color: 'hsl(200,60%,45%)'
}
}, {
value: 52,
itemStyle: {
color: 'hsl(200,60%,45%)'
}
}, {
value: 200,
itemStyle: {
color: 'hsl(60,60%,45%)'
}
}, {
value: 334,
itemStyle: {
color: 'hsl(150,60%,45%)'
}
}, {
value: 390,
itemStyle: {
color: 'hsl(220,60%,45%)'
}
}, {
value: 330,
itemStyle: {
color: 'hsl(200,60%,45%)'
}
}, {
value: 220,
itemStyle: {
color: 'hsl(150,60%,45%)'
}
}]
}]
};
echartsObj.setOption(option)
echartsObj.on('click', function(params) {
console.log(params)
option.series[0].data.forEach((data, index) => {
if (index === params.dataIndex) {
if (!data.isChecked) {
data.itemStyle.color = getHighLightColor(data.itemStyle.color);
data.isChecked = true;
}
} else {
if (data.isChecked) {
data.itemStyle.color = getOrigColor(data.itemStyle.color);
data.isChecked = false;
}
}
})
echartsObj.setOption(option)
});
function getHighLightColor(color) {
return color.replace(/(\d+)%\)/, (...args) => {
return 20 + Number(args[1]) + '%)'
});
}
function getOrigColor(highlightColor) {
return highlightColor.replace(/(\d+)%\)/, (...args) => {
return Number(args[1]) - 20 + '%)'
});
}
<html>
<header>
<script src="https://cdn.bootcss.com/echarts/4.1.0.rc2/echarts-en.min.js"></script>
</header>
<body>
<div id="canvas" style="width: 100%; height: 200px">
</div>
</body>
</html>
Can be highlight like this:
chart.on('click', (params) => {
chart.dispatchAction({
type: 'highlight',
seriesIndex: params.seriesIndex,
dataIndex: params.dataIndex
})
})
The highlight style can be set using emphasis.itemStyle
The document can be found here: https://echarts.apache.org/en/api.html#action.highlight
Related
Is there a way to make the div wrapping the chart part of the fullscreen as well?
This is my code: fiddle
THis code only fulscreens the chart. When I try and do to point the div I need in the fullscreen:
Highcharts.FullScreen = function(container) {
this.init(ontainer.parentNode.parentNode);
};
My fullscreen is getting cut off and also not adding the parent div to the full screen. Is there to make the whole div with id yo and the other div inside (<div>Random Data and text.......</div>) as part of the fullscreen?
You can connect the content of a custom element through chart.renderer.text().add() by specifying this element with the html() method:
chart.renderer.text(selector.html(), 0, 0).add();
...hiding this element through css, set the display: none:
.random_data {
display: none;
}
This is the piece of code to add:
function (chart) {
chart.renderer
.text($(".random_data").html(), 10, 10)
.css({
color: "green",
fontSize: "12px",
})
.add();
}
JavaScript:
let chart = Highcharts.chart(
"container",
{
chart: {
type: "column",
},
title: {
text: "",
},
xAxis: {
categories: ["one", "two", "three"],
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,
},
},
yAxis: {
title: {
text: "",
},
endOnTick: false,
},
series: [
{
name: "books",
data: [
["one", 64161.71548379661],
["two", 3570.6197029028076],
["three", -200.70625619033547],
],
marker: {
symbol: "circle",
},
},
],
},
function (chart) {
chart.renderer
.text($(".random_data").html(), 10, 10)
.css({
color: "green",
fontSize: "12px",
})
.add();
}
);
let btn = document.getElementById("btn");
btn.addEventListener("click", function () {
Highcharts.FullScreen = function (container) {
console.log(container.parentNode.parentNode);
this.init(container.parentNode); // main div of the chart
};
Highcharts.FullScreen.prototype = {
init: function (container) {
if (container.requestFullscreen) {
container.requestFullscreen();
} else if (container.mozRequestFullScreen) {
container.mozRequestFullScreen();
} else if (container.webkitRequestFullscreen) {
container.webkitRequestFullscreen();
} else if (container.msRequestFullscreen) {
container.msRequestFullscreen();
}
},
};
chart.fullscreen = new Highcharts.FullScreen(chart.container);
});
CSS:
.random_data {
display: none;
}
HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="yo">
<div class="random_data">Random Data and text.......</div>
<div id="container" style="height: 400px; margin-top: 1em;"></div>
</div>
<button id="btn">
Show full screen
</button>
kind of stuck in a hole here. I have a stacked Highchart that I'm trying to re-render when you click on a button. Here is what it looks like for now:
Clicking on any of the buttons will trigger a designated event handler that helps me generate a new series of data for that particular category. The data is organized in a way that bar-charts can consume.
For instance, clicking on the "Asset Class" button will return an output of:
(4) [{…}, {…}, {…}, {…}]
0: {name: "Cash", data: Array(1)}
1: {name: "Equity", data: Array(1)}
2: {name: "Fixed Income", data: Array(1)}
3: {name: "Fund", data: Array(1)}
length: 4
The problem I'm having is that the chart never seems to update even though I'm updating the series data. (this.chart.options.series = myNewSeries)
Some events will return more than 4 items (could be anywhere from 4 to 30 values) and I need them to stack as well.
Here is my code with the updating logic near the bottom:
export class ChartComponent{
constructor(){
|| block of script logic ||
this.options = {
chart: {
type: 'column',
height: 500,
width: 500,
style: {
fontFamily: "Arial"
},
events: {
redraw: function (){
alert("The chart is being redrawn")
}
}
},
title: {
text: ""
},
xAxis: {
categories: this.seriesData.category,
labels: {
style: {
fontSize: "14px"
}
}
},
yAxis: {
min: 0,
title: {
text: ""
},
labels: {
formatter: function () {
let valueString = (
this.value > 999.99 && this.value <= 999999.99 ?
"$" + (this.value / 1000).toFixed(0) + "K" : this.value > 999999.99 ?
"$" + (this.value / 1000000).toFixed(1) + "M" : this.value
)
return valueString
},
style: {
fontSize: "14px",
}
}
},
legend: {
x: 0,
y: 0,
verticalAlign: "top",
align: "right",
layout: "vertical",
itemStyle: {
fontSize: "16px",
color: "#6c6c6c",
},
symbolPadding: 8,
itemMarginTop: 10,
shadow: false,
labelFormatter: function () {
return `${this.name}`
}
},
tooltip: {
formatter: function () {
let name = this.series.name
let value = this.y
let valueString = `$${value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`
let total = this.point.stackTotal
let percentage = ((value / total) * 100).toFixed(2)
let percentageString = `(${percentage})%`
return `<b>${name}</b> <br> ${valueString} ${percentageString}`
},
style: {
fontSize: "14px",
},
backgroundColor: "#ffffff"
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: false
}
},
series: {
pointWidth: 100,
borderColor: "rgba(0, 0, 0, 0)"
}
},
series: this.seriesData.series
}
}
options: Object
saveInstance(chartInstance): void {
this.chart = chartInstance;
}
updateSeriesData = (data: Array<any>, title): void => {
this.chart.options.series = data
this.chart.xAxis[0].update({categories: title})
}
// event handlers
getIndustryData = (e) => {
let newSeries = this.getSeriesTotals("Industry", "SecuritySectorLevel1", "SecuritySectorLevel2")
this.updateSeriesData([...newSeries.series], newSeries.category)
}
getSectorData = (e) => {
let newSeries = this.getSeriesTotals("Sector", "SecuritySectorLevel2", "SecuritySectorLevel1")
this.updateSeriesData([...newSeries.series], newSeries.category)
}
getAssetClassData = (e) =>{
let newSeries = this.getSeriesTotals("Asset Class", "AssetClassLevel1", "SecuritySectorLevel1")
this.updateSeriesData([...newSeries.series], newSeries.category)
}
getRegionData = (e) => {
let newSeries = this.getSeriesTotals("Region", "CountryOfRisk", "CountryOfIssuance")
this.updateSeriesData([...newSeries.series], newSeries.category)
}
getCurrencyData = (e) =>{
let newSeries = this.getSeriesTotals("Currency", "LocalCCY", "LocalCCYDescription")
this.updateSeriesData([...newSeries.series], newSeries.category)
}
}
Generally speaking, for the next person who surfs here:
In your HTML-Element you'll have something like:
<highcharts-chart
...
[(update)]="updateFlag">
</highcharts-chart>
And in the corresponding Typescript file you have a
updateFlag = false;
and after the section where you've changed something, you do:
this.updateFlag = true;
When Dropdown selected change ıt shows previous selected values. I tried many ways like destroy the chart functionality but none of them work or I am not able to work it
any one can help me about the solution.
I have saw many answers about this question but none of them works ..
I have shared my code below so looking for help
let asyaIlceRuhsat = document.getElementById('asyaIlceRuhsat').getContext('2d');
$(document).ready(function () {
$('#mySelectAsya').select2({
width: '100%'
}).val() == -1 ? $('#asyaIlceRuhsat').after('<div class="asyaSecimi"><p class="text-center text-uppercase font-weight-bolder">Lütfen ilçe seçiniz!</p></div>') : null;
});
//Asya Yakası
$('#mySelectAsya').on('select2:select', function (e) {
var selectedId = $('#mySelectAsya').val()
var selectedText = $("#mySelectAsya :selected").text()
var canvas = document.getElementById('asyaIlceRuhsat')
if (selectedId === -1) {
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
$(".asyaSecimi").css("display", "block");
$(canvas).addClass("hidden");
}
else {
$(canvas).removeClass("hidden");
$(".asyaSecimi").css("display", "none");
}
fetch(`http://myurl/api/Web/Test/GetValue?query=${queryId}`)
.then(function (response) {
return response.json();
// console.log(response)
})
.then(function (ids) {
// console.info(`ids:`, ids)
new Chart(asyaIlceRuhsat, {
type: 'bar',
data: {
labels: ids.map(function (id) {
return id.TUR;
}),
datasets: [
{
label: "ARIZA",
backgroundColor: "#e65c00",
data: ids.map(function (id) {
return id.ARIZASAYISI;
}),
}, {
label: "ARIZA ONAY",
backgroundColor: "#66ff66",
data: ids.map(function (id) {
return id.ARIZAONAYSAYISI;
}),
}, {
label: "NORMAL",
backgroundColor: "#66ccff",
data: ids.map(function (id) {
return id.NORAMLSAYISI;
}),
}, {
label: "BAŞVURU",
backgroundColor: "#0099ff",
data: ids.map(function (id) {
return id.BASVURUSAYISI;
}),
},
]
},
options: {
title: {
display: true,
text: 'Normal Ruhsat Durum',
fontSize: 18
},
legend: {
display: true,
position: 'right',
labels: {
fontColor: '#000',
usePointStyle: false
}
},
layout: {
padding: {
left: 0,
right: 0,
bottom: 0,
top: 0
}
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Asya Geneli Normal Ruhsat Durumları',
fontColor: '#000000',
fontSize: 12
}
}]
}
}
});
});
})
This is a very common issue while updating the same canvas with a new chart. On your dropdown change event try to add the following code which will destroy all the charts previous instance.
Chart.helpers.each(Chart.instances, function (instance) {
instance.destroy();
});
I'm using c3 js for generating categories bar chart
Here is code
var obj = {
size: {
height: 200,
},
bindto: '#grBarChart',
data: {
columns: data.columns,
type: "bar"
},
color: {
pattern: ['#c90000', '#008cba', '#FAAC3D','#427322', '#9ead9b', '#ffa500']
},
axis: {
x: {
type: 'category',
categories: data.categories,
label: {
text: 'Scanned Groups',
position: 'outer-center'
}
},
y: {
label: {
text: 'Count (Rules)',
position: 'outer-middle'
}
}
},
bar: {
width: {
ratio: 0.5,
}
},
grid: {
y: {
show: true
}
}
};
var chart = c3.generate(obj);
This code is generating the following graph
Now my problem is I'm not able to add click event on X Axis Category Names ( Logging 11, Data Protection 13 ...)
I referred C3 Documentation but not able to solve my problem.
Please give me your thought?
Tricky one to explain this so please bear with me.
I have this Large Tree Map created with Highcharts:
http://jsfiddle.net/mb3hu1px/2/
var data = {
"ARS": {
"01To03Years": {
"N": {
"ARGENTINA": 951433
}
},
"Above05Years": {
"N": {
"ARGENTINA": 3719665
}
}
},
"CNY": {
"03To05Years": {
"N": {
"CHINA": 162950484
}
}
},
"COP": {
"Above05Years": {
"N": {
"COLOMBIA": 323390000
}
}
},
"EUR": {
"01To03Years": {
"Y": {
"BELGIUM": 393292575
}
}
}
},
points = [],
currencyPoints,
currencyVal,
currencyI = 0,
periodPoints,
periodI,
yesOrNoPoints,
yesOrNoI,
currency,
period,
yesOrNo,
mil,
causeMil,
causeMilI,
causeName = {
'N': 'Country Name',
'Y': 'Country Name'
};
for (currency in data) {
if (data.hasOwnProperty(currency)) {
currencyVal = 0;
currencyPoints = {
id: 'id_' + currencyI,
name: currency,
color: Highcharts.getOptions().colors[currencyI]
};
periodI = 0;
for (period in data[currency]) {
if (data[currency].hasOwnProperty(period)) {
periodPoints = {
id: currencyPoints.id + '_' + periodI,
name: period,
parent: currencyPoints.id
};
points.push(periodPoints);
yesOrNoI = 0;
for (yesOrNo in data[currency][period]) {
if (data[currency][period].hasOwnProperty(yesOrNo)) {
yesOrNoPoints = {
id: periodPoints.id + '_' + yesOrNoI,
name: yesOrNo,
parent: periodPoints.id,
};
causeMilI = 0;
for (mil in data[currency][period][yesOrNo]) {
if (data[currency][period][yesOrNo].hasOwnProperty(mil)) {
causeMil = {
id: yesOrNoPoints.id + '_' + causeMilI,
name: mil,
parent: yesOrNoPoints.id,
value: Math.round(+data[currency][period][yesOrNo][mil])
};
currencyVal += causeMil.value;
points.push(causeMil);
causeMilI = causeMilI + 1;
}
}
points.push(yesOrNoPoints);
yesOrNoI = yesOrNoI + 1;
}
}
periodI = periodI + 1;
}
}
currencyPoints.value = Math.round(currencyVal / periodI);
points.push(currencyPoints);
currencyI = currencyI + 1;
}
}
Highcharts.chart('container', {
series: [{
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 3
}],
data: points
}],
title: {
text: ''
}
});
#container {
min-width: 300px;
max-width: 600px;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<script src="https://code.highcharts.com/modules/treemap.js"></script>
<div id="container"></div>
<textarea name="text" id="text" cols="30" rows="10"></textarea>
And as you can see there is also a text area underneath.
What I want is for every level that is clicked through on the chart, the text area updates with some random text.
So for example on the first drill down, the text area could literally just print out level 1, the second drill down print level 2 etc. etc.
If anyone needs anything else from my end please let me know.
Many thanks:)
You can do this several ways. Here is how to do it with plotOptions.series.point.events.click. What you need to do is capture the point click and render some text. As you do not describe what text to show this will just update the textarea with the clicked point's properties name and value.
Highcharts.chart('container', {
series: [{
point: {
events: {
click: function() {
var thePointName = this.name,
thePointValue = this.value;
$('#text').val(function(_, val) {
return 'Category: ' + thePointName + ', value: ' + thePointValue;
});
}
}
},
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 3
}],
data: points
}],
title: {
text: ''
}
});
Live example.