vue-chartjs not updating on array.push() - javascript

I'm using vue-chartjs to show a line chart on my website. When I click on a button it's supposed to add another value to the chart. The dataset is updated but the chart is not.
LinieChart.vue
<script>
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: {
options: {
type: Object,
default: null
}
},
mounted () {
this.renderChart(this.chartData, this.options)
},
methods: {
}
}
</script>
I added this to my dashboard.vue
Where the chart is displayed
<line-chart
ref="LineChart"
:chart-data="chartdata"
:options="options"
class="h-64"
/>
The JavaScript:
<script>
export default {
middleware: 'auth',
layout: 'dashboard',
name: 'Dashboard',
components: {
temporaryDisableModal,
LineChart
},
data: () => ({
sensors: [],
sensorTypes: [],
valueTypes: [],
measurements: [],
websockets: [],
lastMeasurements: null,
loaded: false,
chartdata: null,
options: {
maintainAspectRatio: false,
responsive: true
}
}),
beforeMount () {
},
async mounted () {
this.fillData()
const self = this
// self.fillData()
await self.getSensors()
self.loaded = false
self.loaded = true
console.log('Sensors:')
console.log(self.sensors)
console.log(self.sensors.length)
for (let i = 0; i < self.sensors.length; i++) {
console.log(i)
console.log('Subscribed to ' + self.sensors[i].id)
self.measurements[self.sensors[i].id] = []
console.log(self.measurements)
window.Echo.channel('measurement.' + self.sensors[i].id).listen('.App\\Events\\WebsocketMeasurements', (e) => {
console.log('Data:')
console.log(e)
self.websockets.push(e.measurement)
self.measurements[self.sensors[i].id].push(e.measurement)
console.log(self.measurements)
})
}
},
methods: {
log () {
this.chartdata.labels.push(10)
this.chartdata.datasets[0].data.push(10)
this.chartdata.datasets[1].data.push(10)
},
fillData () {
this.chartdata = {
labels: this.getRandomInt(),
datasets: [
{
label: 'value_1',
borderColor: 'rgba(131, 24, 48, 1)',
backgroundColor: 'rgba(131, 24, 48, 0.3)',
data: this.getRandomInt()
},
{
label: 'value_2',
borderColor: 'rgba(216, 42, 81, 1)',
backgroundColor: 'rgba(216, 42, 81, 0.3)',
data: this.getRandomInt()
}
]
}
},
getRandomInt () {
let array = []
for (let i = 0; i < 100; i++) {
array.push(Math.floor(Math.random() * (6) * Math.random() * 3 * Math.random() * 9) + 15)
}
console.log(array)
return array
},
// other functions...
</script>
So when I execute the function log() it should add the value 10 as label and a dot in the line. It is added to the dataset, just not to the chart.
When I executed the log() function i get an error when hovering the chart:
Chart.js?30ef:6719 Uncaught TypeError: Cannot read property 'skip' of undefined
This does not happen when I haven't executed the function yet.

This is a known problem with vuecharts, instead of modifying nested elements on data reassign them all along, so instead of this:
this.chartdata.labels.push(10)
this.chartdata.datasets[0].data.push(10)
this.chartdata.datasets[1].data.push(10)
Do this:
this.chartdata.labels = MyNewArrayOfLabels
this.chartdata.datasets= [ //Me new array of datasets
{
label: 'value_1',
borderColor: 'rgba(131, 24, 48, 1)',
backgroundColor: 'rgba(131, 24, 48, 0.3)',
data: this.getRandomInt()
},
{
label: 'value_2',
borderColor: 'rgba(216, 42, 81, 1)',
backgroundColor: 'rgba(216, 42, 81, 0.3)',
data: this.getRandomInt()
}
]

Related

yAxis of chartjs is not displayed?

**When i drawChartData the yAxis of chartjs is not displayed. What is the problem, can you help me **
Before
After
there is my script
<script lang="ts">
import { Vue, Component } from "nuxt-property-decorator";
import BarChartComponent from "#/components/chart/BarChartComponent";
import LineChartComponent from "#/components/chart/LineChartComponent";
import moment from "moment"
import traffic from '#/modules/traffic'
import { TrafficCarrierSummary, TrafficCarrierDetail } from "#/type/traffic-carrier-summary";
const FONT_COLOR = "rgba(255, 255, 255, 1)";
const GRID_LINES_SETTING = {
display: true,
drawOnChartArea: true,
color: "rgba(255, 255, 255, .5)",
zeroLineColor: "rgba(255, 255, 255, 1)"
};
#Component({
components: {
BarChartComponent,
LineChartComponent
},
asyncData: async () => {
let searchObject = {
from: moment().subtract(1, 'months').set('date', 1).format('Y-M-D'),
to: moment().subtract(1, 'months').endOf('month').format('Y-M-D'),
}
const response = await traffic.package(searchObject)
return {
searchObject: searchObject,
packageData: response.data,
}
}
})
export default class extends Vue {
width: number = 575
packageData!: Array<TrafficCarrierSummary>
packageDaliy: TrafficCarrierDetail | null = null
selectedPackage: string | null = null
isDayPackage: boolean = false
selectedDaliyDate: any
loading: boolean = false
lineColors = [
'rgba(120, 0, 0,1)',
'rgba(176, 0, 10,1)',
'rgba(234, 57, 51,1)',
'rgba(251,184, 43,1)',
'rgba(255,234, 97,1)',
'rgba( 92, 98, 91,1)',
'rgba( 35, 37, 35,1)',
]
searchObject = {
from: null,
to: null,
} as any
chartDataPackage: any = {};
chartDataCount: any = {};
chartPackageOptions: Chart.ChartOptions = {
responsive: true,
maintainAspectRatio: false,
title: {
display: false,
},
scales: {
yAxes: [
{
scaleLabel: {
display: true,
labelString: 'Data [GB]',
fontColor: "red",
fontSize: 16
},
ticks: {
suggestedMax: 1000,
suggestedMin: 0,
stepSize: 100,
callback: function(value, index, values) {
return value + "GB";
}
}
}
]
}
};
created() {
this.searchObject.from = new Date(moment().subtract(1, 'months').set('date', 1).toDate())
this.searchObject.to = new Date(moment().subtract(0, 'months').endOf('month').toDate())
this.selectedDaliyDate = this.searchObject.from
this.drawChartPackage()
}
async search() {
this.loading = true
let from = moment(this.searchObject.from).format('Y-MM-DD')
let to = moment(this.searchObject.to).format('Y-MM-DD')
const response = await traffic.package({
from: from,
to: to
})
this.packageData = response.data
this.drawChartPackage()
this.loading = false
}
drawChartPackage() {
let dataArr: Array<any> = []
let labels: Array<string> = []
let obj: any = {}
this.packageData.forEach(element => {
if(!labels.includes(element.target_date)){
labels.push(element.target_date)
}
if(!obj[element.package]){
obj[element.package] = []
}
obj[element.package].push(Number(element.data_total) / 1024 / 1024 / 1024)
})
let index = 0
Object.keys(obj).map(key => {
dataArr.push({
label: key,
data: obj[key],
borderColor: this.lineColors[index],
backgroundColor: 'rgba(0,0,0,0)',
type: 'line'
})
index++
})
this.chartDataPackage = {
labels: labels,
datasets: dataArr
}
}
}
</script>

How to display the data one by one when its already finish fetching data in angular

HTML
<div nz-row *ngIf="tempThermometer | async as temp">
<div *ngFor="let data of temp;let i = index;" nz-col nzXs="24" nzSm="12" nzMd="12" nzXl="8" nzXXl="6">
<nz-spin nzTip="Loading..." [nzSize]="'large'" [nzSpinning]="data.spinning">
<div echarts [options]="chartOption[i]" [autoResize]="true" style="height: 270px;"></div>
</nz-spin>
</div>
</div>
TS
tempLoading = false;
tempThermometer = new BehaviorSubject<any>([]);
getRoomList() {
this.tempLoading = true;
this.subscription = this.global
.getData(`/conditions/latest?length=${this.pageSize}`)
.pipe(take(1))
.subscribe((res: any) => {
this.tempThermometer.next(Object.values(res['data'].map((obj: any) => {
return {
...obj,
spinning: true
};
})));
this.tempLoading = false;
this.lineChart(this.tempThermometer.value);
});
}
lineChart(params?: any) {
const _this = this;
const list: any = [];
params.forEach((param: any) => {
const url = encodeURIComponent(param.sensor);
// List URL
list.push(`/conditions?length=${this.length}&sensor=${url}`);
});
// Promise requests
const promises = list.map(
(url: any) =>
new Promise(resolve => {
this.subscription = this.global.getData(url).pipe(take(1)).subscribe((res) => {
resolve(res);
}, (err: Error) => {
return reject(err);
});
})
);
// Retrieve each data as per promise
Promise.all(promises).then(results => {
const dataRoom: any = [];
results.map((result) => {
const date: any = [], temperature: any = [], humidity: any = [], newRoomData: any = [];
const param = result['data'];
const roomData = orderBy(param, ['date'], ['asc']);
const room = roomData.slice(-1)[0];
const timeEnd = room.date.slice(0, 19);
const timeStart = subHours(timeEnd, 7);
const dataHour = roomData.filter((data: TemplogRecord) => {
return !isBefore(data.date, timeStart) && !isAfter(data.date, timeEnd);
});
// console.log(roomData);
const hash = Object.create(null);
dataHour.forEach((data: any) => {
const key = data.date.slice(0, 13);
if (!hash[key]) {
hash[key] = {
sensor: data.sensor, temperature: data.temperature,
humidity: data.humidity, date: key + ':00:00'
};
newRoomData.push(hash[key]);
}
});
for (let x = 0; x < newRoomData.length; x++) {
temperature.push(newRoomData[x].temperature);
humidity.push(newRoomData[x].humidity);
date.push(newRoomData[x].date);
}
dataRoom.push({
date: date,
humidity: humidity,
temperature: temperature
});
});
dataRoom.forEach((param: any, index: number) => {
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
animation: false
},
backgroundColor: 'rgba(245, 245, 245, 0.8)',
borderWidth: 1,
borderColor: '#ccc',
padding: 10,
textStyle: {
color: '#000'
},
formatter: function (prm: any) {
let rec = prm[0].name.slice(0, 10) + '<br/>' + prm[0].name.slice(11, 19) + '<br/>';
for (let x = 0; x < prm.length; x++) {
if (prm[x].axisIndex !== 1) {
rec += prm[x].marker + ' ' + prm[x].seriesName + ': '
+ prm[x].data + _this.units['Celcius'] + '<br/>';
} else {
rec += prm[x].marker + ' ' + prm[x].seriesName + ': '
+ prm[x].data + '%' + '<br/>';
}
}
return rec;
}
},
...this.echart.roomChart,
dataZoom: [{
type: 'inside',
show: false,
bottom: 0,
width: '84%',
xAxisIndex: [0, 1],
zoomOnMouseWheel: false,
},
{
type: 'slider',
bottom: 0,
show: false,
width: '84%',
xAxisIndex: [0, 1],
zoomLock: false,
}],
xAxis: [{
type: 'category',
boundaryGap: false,
scale: true,
axisLine: {
show: false
},
axisTick: {
show: false
},
data: param.date.map((str: any) => {
return format(str, 'YYYY-MM-DD hh:mm a');
}),
splitLine: {
show: true,
lineStyle: {
color: 'rgba(182, 202, 227)'
}
},
axisLabel: {
show: true,
interval: 0,
rotate: 90,
formatter: ((data: any) => {
return (data).slice(11, 19);
})
}
},
{
gridIndex: 1,
show: false,
scale: true,
type: 'category',
boundaryGap: false,
axisLine: {
show: false
},
data: param.date,
axisTick: {
show: false
},
splitLine: {
show: true
}
}],
series: [{
name: 'Humidity',
data: param.humidity,
type: 'line',
itemStyle: {
color: 'rgba(0, 101, 144, 1)'
},
markPoint: {
type: 'Pin',
data: [
{
type: 'max',
itemStyle: {
color: 'rgba(0, 101, 144)'
}
},
{
type: 'min',
itemStyle: {
color: 'rgb(110, 151, 204)'
}
}
]
},
smooth: true,
xAxisIndex: 1,
yAxisIndex: 1
},
{
name: 'Temperature',
data: param.temperature,
type: 'line',
itemStyle: {
color: 'rgba(255, 0, 0, 1)'
},
markPoint: {
type: 'Pin',
data: [
{
type: 'max',
itemStyle: {
color: 'rgba(255, 5, 0)'
}
},
{
type: 'min',
itemStyle: {
color: 'rgb(255, 87, 86)'
}
}
]
},
smooth: true
},
]
};
this.chartOption.push(option);
this.notScrolly = true;
this.tempThermometer.value.filter((x: any) => params.map((y: any) => {
if (y.id === x.id) {
return y.spinning = false;
}
}));
});
});
}
The problem here is, when it's loading it will fetch all the data before it will display them all.
What I want to do here is when the first item that already fetch, it will display while the others still fetching the data.
for example there's 5 items which is the area 1, area 2, area 3, area 4 and area 5.
when the area 1 already finish fetching the data then it will display it. while the other still loading/fetching.
like the area 1 already finish fetching then next the area 3 then area 2 then 5 then 4.
who ever finish fetching it will display automatically.
I would approach this in one of two ways. Neither would involve promises.
I'm not going to attempt to use your code example, as it is far too large, instead I will focus on the core of your problem - run an array of observables and process results as they are returned.
1. Merge observables
The RxJS merge function will run multiple observables together and call your subscribe callback with the individual values immediately.
const observables: Observable<any>[] = this.getObservables();
merge(...observables).subscribe(result => {
// individual results are logged here as soon as the observable returns them
console.log(result);
}, err => {
// empty error callback.
// This is here to allow us to add the complete callback
}, () => {
console.log('complete');
});
Pro: simple to process results in the subscribe
Con: have to run complete code in the complete callback
2. Process results in the pipe
You can run the observables in parallel in a forkJoin. The subscribe will only be called when the final observable completes, but you can process results in individual tap operators.
const observables: Observable<any>[] = this.getObservables()
.map(x => x.pipe(
// tap is run as soon as the observable is returned
tap(result => console.log(result))
));
forkJoin(observables).subscribe(result => {
console.log('complete');
});
Pro: simple complete handling in the subscribe
Con processing results in individual tap operators can get a bit messy
Conclusion
Both of these approaches are fairly equivalent. I would probably prefer the forkJoin approach, but I wanted to demonstrate the power and flexibility of RxJS by giving you a second example.
DEMO: https://stackblitz.com/edit/angular-7rrmtn
The demo sets up 5 observables, each with a different delay. The observables are processed as the results are returned, and they both log when they complete.
As you can see, they are functionally equivalent.
Try to add change detection strategy
and run detectChanges function as soon as you update variable with the first data point

Trying to use axios, vuejs and a dummy api for my chartjs and googlecharts (get requests only)

I am trying to use axios in combination with a link containing this data: { "2015": 226, "2016": 152, "2017": 259, "2018": 265, "2019": 275}, written in JSON.
I want to implement those data, the year for example: 2017 and the revenue: 259 in this chart:
//BARCHART
var ctx = document.getElementById("myChart");
var barChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["2016", "2017", "2018", "2019", "2020"],
datasets: [
{
label: 'Vergangenheit', //Vergangenheit = Past
data: [226, 152, 259, 265, 0],
backgroundColor: 'rgba(110, 205, 126, 1)',
borderColor: 'rgba(110, 205, 126, 1)',
borderWidth: 1,
}
]
},
options: {
responsive: true,
responsiveAnimationDuration: 0,
maintainAspectRatio: true,
aspectRatio: 2,
oneResie: null,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true
}
}
]
}
}
});
With the combination of vue and axios a get request should look like this:
var vm = new Vue({
el: '#get',
data: {
messages: [],
message: ""
},
mounted: function () {
this.getMessages(); // get all messages automatically when the page is loaded
},
methods: {
getMessages: function() {
axios.get('(hiddenhttps:/api/GewinnNachJahr')
.then( (res) => {
this.messages = res.data;
console.log(response.data)
})
},
}
});
I don't want any button to press for the get request, it should always get that data when reloading the page. I already tried the a few code snippets from stackoverflow, the official axios github don't help me at all.
So to summarize i want that axios getrequest on my http datas, then saving and sorting this data and implementing it in my chart.js barchart. I think its enough to just working withing my java.js.
I apologize for the time and effort involved. Thank you in advance.
You can implement chart.js into your vue app. I have created this code it should work.
var vm = new Vue({
el: "#get",
data: {
messages: [],
message: "",
labels: [],
data_set: [],
barChart: ""
},
mounted: function() {
var ctx = document.getElementById("myChart");
this.barChart = new Chart(ctx, {
type: "bar",
data: {
labels: this.labels,
datasets: [
{
label: "Vergangenheit", //Vergangenheit = Past
data: this.data_set,
backgroundColor: "rgba(110, 205, 126, 1)",
borderColor: "rgba(110, 205, 126, 1)",
borderWidth: 1
}
]
},
options: {
responsive: true,
responsiveAnimationDuration: 0,
maintainAspectRatio: true,
aspectRatio: 2,
oneResie: null,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true
}
}
]
}
}
});
},
created: function() {
this.getMessages(); // get all messages automatically when the page is loaded
},
methods: {
getMessages: function() {
axios
.get(
"https://webenggroup06ln3.free.beeceptor.com/zalando/api/GewinnNachJahr"
)
.then(res => {
console.log(res.data);
for (let [key, value] of Object.entries(res.data)) {
this.labels.push(key);
this.data_set.push(value);
}
this.$nextTick(function() {
this.barChart.update();
});
});
}
}
});
the for loop splits your key and your value seperate and then it pushes it into the data array. After everything is pushed inside the array the chart just needs to get updated with this.barChart.update()
mounted or created is the correct place to implement bootstrapping logic for this case. However your code has some problems in definitions and typo:
'(hiddenhttps:/api/GewinnNachJahr': the initial parenthesis should be omitted
console.log(response.data): response should become res for matching callback parameter.
See a working example with a dummy api call and how it loads the data:
var vm = new Vue({
el: '#app',
data: {
messages: [],
message: ""
},
mounted() {
this.getMessages(); // get all messages automatically when the page is loaded
},
methods: {
getMessages() {
axios.get('http://dummy.restapiexample.com/api/v1/employees')
.then((res) => {
this.messages = res.data;
console.log(res.data)
})
},
}
});
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul>
<li v-for="m in messages">{{JSON.stringify(m)}}</li>
</ul>
</div>

Updating Chartjs with new data

My goal is to update my chart with new data from the server. Here's my code:
(function () {
'use strict';
let color = Chart.helpers.color;
window.chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
let timeAxis = [{
type: 'time',
}];
let percentAxis = [{
ticks: {
beginAtZero: false,
callback: function(value) {
return Math.round(value * 1000) / 10 + '%';
}
}
}];
let buildChartObject = function (ctx, type, xAxes, yAxes) {
return new Chart(ctx, {
type: type,
data: null,
options: {
responsive: true,
title: {
display: true,
fontStyle: 'normal',
padding: 10,
fontSize: 12
},
scales: {
xAxes: xAxes,
yAxes: yAxes
},
legend: {
display: false
}
}
});
};
let loadChartData = function (endpoint, chart, params) {
$.ajax({
url: '/api/v1/' + endpoint,
method: 'GET',
dataType: 'json',
params: params,
success: function (d) {
let bgColors = null, bdColors = null;
if (chart.config.type === 'line') {
bgColors = color(window.chartColors.blue).alpha(0.5).rgbString();
bdColors = window.chartColors.blue;
} else {
bgColors = d.data.map(
(value) => value < 0 ? color(window.chartColors.red).alpha(0.5).rgbString() :
color(window.chartColors.green).alpha(0.5).rgbString()
);
bdColors = d.data.map(
(value) => value < 0 ? window.chartColors.red : window.chartColors.green
);
}
if (chart.options.scales.xAxes[0].type === 'time') {
let dateUnits = {
daily: 'day',
weekly: 'week',
monthly: 'month',
yearly: 'year'
};
chart.options.scales.xAxes[0].time.unit = dateUnits[d.params.convertTo];
}
chart.options.title.text = d.name;
chart.data.labels = d.index;
chart.data.datasets[0] = {
backgroundColor: bgColors,
borderColor: bdColors,
borderWidth: 1,
data: d.data
};
chart.update();
}
});
};
let loadCharts = function () {
let params = {
convertTo: $('#convert-to').val()
}
let returnsChart = buildChartObject($('#chart'), 'bar', timeAxis, percentAxis);
loadChartData('endpoint', returnsChart, params);
}
loadCharts();
$('#convert-to').on('change', function() {
loadCharts();
});
}());
The initial call to loadCharts() correctly populates the chart. However when when the #convert-to event is triggered, the loadCharts reloads the data but I have this flickering effect of both charts drawn on the same canvas. This is not a bug or a related issue, rather a canvas drawing one.
Have a look here: https://www.dropbox.com/s/9onofdazkvp9uas/clip.mov?dl=0
I've read countless threads on this and it seems like chart.update() should solve the issue. From the docs: "[update()] triggers an update of the chart. This can be safely called after updating the data object. This will update all scales, legends, and then re-render the chart."
What am I doing wrong?
You don't need to call buildChartObject(...) again when you are trying to just update the data for the chart. If you held onto a reference of the chart you would be fine to skip that call. Doing this will allow Chart.js to just update the chart when you call chart.update() instead of creating a new chart and then updating it.
...
let returnsChart = buildChartObject($('#chart'), 'bar', timeAxis, percentAxis);
let loadCharts = function () {
let params = {
convertTo: $('#convert-to').val()
};
loadChartData('endpoint', returnsChart, params);
}
loadCharts();
$('#convert-to').on('change', function() {
loadCharts();
});
...

HighCharts. Angular. Redraw Chart with new Series on Event Click

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;

Categories