I am trying to combine controls of amcharts to the react audio player.
Here, I have amcharts line graph with a slider. Now I am trying control the slider in such a way that whenever I hit the play button of react audio player, I could move the slider with the audio player's seeker. I hope, this makes sense to you.
import React from "react";
import ReactAudioPlayer from "react-audio-player";
import audio from "/home/aniruddha/workspace/playwith_audio/anni_web_player/src/audio.flac";
import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";
import am4themes_spiritedaway from "@amcharts/amcharts4/themes/spiritedaway";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";
/* Chart code */
// Themes begin
am4core.useTheme(am4themes_spiritedaway);
am4core.useTheme(am4themes_animated);
class App extends React.Component {
constructor(props) {
super(props);
this.state = {slider: 1586169460800};
}
componentDidMount() {
let chart = am4core.create("chartdiv", am4charts.XYChart);
// Add data
chart.data = this.generateChartData();
// Create axes
let dateAxis = chart.xAxes.push(new am4charts.DateAxis());
let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
let series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = "visits";
series.dataFields.dateX = "date";
series.strokeWidth = 1;
series.minBulletDistance = 10;
series.tooltipText = "{valueY}";
series.fillOpacity = 0.1;
series.tooltip.pointerOrientation = "vertical";
series.tooltip.background.cornerRadius = 20;
series.tooltip.background.fillOpacity = 0.5;
series.tooltip.label.padding(12, 12, 12, 12);
let seriesRange = dateAxis.createSeriesRange(series);
seriesRange.contents.strokeDasharray = "2,3";
seriesRange.contents.stroke = chart.colors.getIndex(8);
seriesRange.contents.strokeWidth = 1;
let pattern = new am4core.LinePattern();
pattern.rotation = -45;
pattern.stroke = seriesRange.contents.stroke;
pattern.width = 1000;
pattern.height = 1000;
pattern.gap = 6;
seriesRange.contents.fill = pattern;
seriesRange.contents.fillOpacity = 0.5;
// Add scrollbar
chart.scrollbarX = new am4core.Scrollbar();
// add range
let range = dateAxis.axisRanges.push(new am4charts.DateAxisDataItem());
range.grid.stroke = chart.colors.getIndex(0);
range.grid.strokeOpacity = 1;
range.bullet = new am4core.ResizeButton();
range.bullet.background.fill = chart.colors.getIndex(0);
range.bullet.background.states.copyFrom(
chart.zoomOutButton.background.states
);
range.bullet.minX = 0;
range.bullet.adapter.add("minY", function (minY, target) {
target.maxY = chart.plotContainer.maxHeight;
target.maxX = chart.plotContainer.maxWidth;
return chart.plotContainer.maxHeight;
});
range.bullet.events.on("dragged", function () {
range.value = dateAxis.xToValue(range.bullet.pixelX);
seriesRange.value = range.value;
console.log(seriesRange.value)
});
let firstTime = chart.data[0].date.getTime();
let lastTime = chart.data[chart.data.length - 1].date.getTime();
let date = new Date(firstTime + (lastTime - firstTime) / 2);
range.date = date;
seriesRange.date = date;
seriesRange.endDate = chart.data[chart.data.length - 1].date;
this.chart = chart
console.log(this.state.slider);
this.setState({ seriesRange } )
console.log(this.state.slider);
range.value = this.state.slider;
seriesRange.value = this.state.slider;
}
generateChartData() {
let chartData = [];
let firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 200);
let visits = 1200;
for (var i = 0; i < 200; i++) {
let newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
visits += Math.round(
(Math.random() < 0.5 ? 1 : -1) * Math.random() * 10
);
chartData.push({
date: newDate,
visits: visits,
});
}
return chartData;
}
sound(event){
console.log(event.timeStamp);
//this.setState({slider: 1586025000000 })
}
seek(event){
console.log(event);
}
lis(event){
console.log(event);
}
componentWillUnmount() {
if (this.chart) {
this.chart.dispose();
}
}
render() {
return (
<div>
<div id="chartdiv" style={{ width: "100%", height: "500px" }}></div>
<ReactAudioPlayer src={audio} onPlay={this.sound} onListen={this.lis} onSeeked={this.seek} controls></ReactAudioPlayer>
</div>
);
}
}
export default App;
I am not able to access this.setState({slider: 1586025000000 })
in the sound
function. I am quite new to react. Please any suggestion is welcome;
You need to wrap your callbacks with arrow functions that call your methods directly (or call bind: this.sound.bind(this)
) so that it resolves to the correct this
scope:
<ReactAudioPlayer
src="{audio}"
onPlay={(ev) => this.sound(ev)}
onListen={(ev) => this.lis(ev)}
onSeeked={(ev) => this.seek(ev)}
controls></ReactAudioPlayer>