<commit_before>import { Config } from "./config";
import { NmapLog, DeviceInfo } from "./db";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { lazy } from "./lazy";
import { levelInvert, DateRounder, roundDate, assignDeep } from "./util";
import * as Highcharts from "highcharts";

function aggregate(
	datas: NmapLog[],
	rounder: DateRounder,
): Map<number, Map<string, number>> {
	const map = new Map<number, Map<string, number>>();
	lazy(datas)
		.flatMap(log => {
			const rounded = rounder(new Date(log.time));
			return rounded
				? [
						{
							time: rounded.getTime(),
							devices: log.devices,
						},
				  ]
				: [];
		})
		.sort(log => log.time)
		.forEach(data => {
			if (!map.has(data.time)) map.set(data.time, new Map());
			const map2 = map.get(data.time)!;
			for (const dev of data.devices)
				map2.set(dev, (map2.get(dev) || 0) + 1);
		});
	return map;
}
class ReactChart extends React.Component<{ options: Highcharts.Options }, {}> {
	chart: Highcharts.ChartObject | null = null;
	container = React.createRef<HTMLDivElement>();
	// When the DOM is ready, create the chart.
	componentDidMount() {
		if (!this.container.current) {
			throw Error("no current!");
		}
		this.chart = new Highcharts.Chart(
			this.container.current!,
			this.props.options,
		);
	}
	//Destroy chart before unmount.
	componentWillUnmount() {
		if (this.chart) this.chart.destroy();
	}
	componentDidUpdate(oldProps: { options: Highcharts.Options }) {
		if (!this.chart) return;
		if (oldProps.options === this.props.options) return;
		if (this.chart.series.length > 0) {
			//this.chart.destroy();
			lazy(this.chart.series)
				.zipWith(this.props.options.series!, (series, newData) => {
					series.setData(newData.data!);
				})
				.collect();
		} else
			this.chart = new Highcharts.Chart(
				this.container,
				this.props.options,
			);
	}
	//Create the div which the chart will be rendered to.
	render() {
		return <div ref={this.container} />;
	}
}
type CommonChartData = {
	data: NmapLog[];
	config: Config;
	deviceInfos: Map<string, DeviceInfo & { upCount: number }>;
};<commit_msg>use highcharts react<commit_after>import { Config } from "./config";
import { NmapLog, DeviceInfo } from "./db";
import * as React from "react";
import { lazy } from "./lazy";
import { levelInvert, DateRounder, roundDate, assignDeep } from "./util";
import * as Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";

function aggregate(
	datas: NmapLog[],
	rounder: DateRounder,
): Map<number, Map<string, number>> {
	const map = new Map<number, Map<string, number>>();
	lazy(datas)
		.flatMap(log => {
			const rounded = rounder(new Date(log.time));
			return rounded
				? [
						{
							time: rounded.getTime(),
							devices: log.devices,
						},
				  ]
				: [];
		})
		.sort(log => log.time)
		.forEach(data => {
			if (!map.has(data.time)) map.set(data.time, new Map());
			const map2 = map.get(data.time)!;
			for (const dev of data.devices)
				map2.set(dev, (map2.get(dev) || 0) + 1);
		});
	return map;
}
class ReactChart extends React.Component<{ options: Highcharts.Options }, {}> {
	componentDidUpdate(oldProps: { options: Highcharts.Options }) {
		/*if (!this.chart) return;
		if (oldProps.options === this.props.options) return;
		if (this.chart.series.length > 0) {
			//this.chart.destroy();
			lazy(this.chart.series)
				.zipWith(this.props.options.series!, (series, newData) => {
					series.setData(newData.data!);
				})
				.collect();
		} else
			this.chart = new Highcharts.Chart(
				this.container,
				this.props.options,
			);*/
	}
	//Create the div which the chart will be rendered to.
	render() {
		return (
			<HighchartsReact
				highcharts={Highcharts}
				options={this.props.options}
			/>
		);
	}
}
type CommonChartData = {
	data: NmapLog[];
	config: Config;
	deviceInfos: Map<string, DeviceInfo & { upCount: number }>;
};
{'fraction_non_alphanumeric': 0.16357161027728315, 'fraction_numerical': 0.0030526583566522513, 'mean_word_length': 3.422947131608549, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2504999', 'n_tokens_mistral': 1540, 'n_tokens_neox': 1325, 'n_words': 317}