zrcadlo https://github.com/atscan/atscan
pds map
This commit is contained in:
rodič
f4281adf29
revize
f70768a75e
|
@ -2,6 +2,8 @@ static
|
|||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/prod-build
|
||||
world.json
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "atscan-fe",
|
||||
"version": "0.7.0-alpha",
|
||||
"version": "0.7.3-alpha",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "atscan-fe",
|
||||
"version": "0.7.0-alpha",
|
||||
"version": "0.7.3-alpha",
|
||||
"dependencies": {
|
||||
"i18next": "^23.2.6",
|
||||
"js-yaml": "^4.1.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "atscan-fe",
|
||||
"version": "0.7.3-alpha",
|
||||
"version": "0.7.4-alpha",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
|
|
|
@ -14,12 +14,8 @@
|
|||
<link href="/font-awesome/css/brands.min.css" rel="stylesheet" />
|
||||
<link href="/font-awesome/css/solid.min.css" rel="stylesheet" />
|
||||
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"
|
||||
integrity="sha512-VdqgeoWrVJcsDXFlQEKqE5MyhaIgB9yXUVaiUa8DR2J4Lr1uWcFm+ZH/YnzV5WqgKf4GPyHQ64vVLgzqGIchyw=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
></script>
|
||||
<script src="https://fastly.jsdelivr.net/npm/echarts@5/dist/echarts.min.js" defer></script>
|
||||
<script src="https://fastly.jsdelivr.net/npm/echarts@4.9.0/map/js/world.js" defer></script>
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover" data-theme="skeleton">
|
||||
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
<script lang="ts" context="module">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import * as echarts from 'echarts';
|
||||
import '$lib/world';
|
||||
|
||||
// console.log(echarts.registerMap())
|
||||
|
||||
export { echarts };
|
||||
|
||||
import * as world from '../world.json';
|
||||
|
||||
echarts.registerMap('world', world);
|
||||
|
||||
import * as darkTheme from '../theme-dark.json';
|
||||
import * as lightTheme from '../theme-light.json';
|
||||
|
||||
|
@ -17,6 +25,7 @@
|
|||
theme?: EChartsTheme;
|
||||
renderer?: EChartsRenderer;
|
||||
options: EChartsOptions;
|
||||
dispatch: any;
|
||||
};
|
||||
|
||||
const DEFAULT_OPTIONS: Partial<ChartOptions> = {
|
||||
|
@ -25,7 +34,7 @@
|
|||
};
|
||||
|
||||
export function chartable(element: HTMLElement, echartOptions: ChartOptions) {
|
||||
const { theme, renderer, options } = {
|
||||
const { theme, renderer, options, dispatch } = {
|
||||
...DEFAULT_OPTIONS,
|
||||
...echartOptions
|
||||
};
|
||||
|
@ -41,6 +50,10 @@
|
|||
echartsInstance.resize();
|
||||
}
|
||||
|
||||
echartsInstance.on('click', (params) => {
|
||||
dispatch('mapClick', params);
|
||||
});
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
return {
|
||||
|
@ -61,9 +74,10 @@
|
|||
<script lang="ts">
|
||||
export let options: echarts.EChartsOption;
|
||||
export let { theme, renderer } = DEFAULT_OPTIONS;
|
||||
const dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<div class="chart" use:chartable={{ renderer, theme, options }} />
|
||||
<div class="chart" use:chartable={{ renderer, theme, options, dispatch }} />
|
||||
|
||||
<style>
|
||||
.chart {
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<script>
|
||||
import Chart from '$lib/components/Chart.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
export let data;
|
||||
|
||||
const pdsMapData = data
|
||||
.map((item) => {
|
||||
//console.log(item)
|
||||
return {
|
||||
name: item.host,
|
||||
value: item?.ip?.loc
|
||||
? [
|
||||
...item.ip?.loc?.split(',').reverse(),
|
||||
item.didsCount > 10000 ? 18 : item.didsCount > 500 ? 13 : 8,
|
||||
item.status
|
||||
]
|
||||
: null
|
||||
};
|
||||
})
|
||||
.filter((i) => i.value);
|
||||
|
||||
const pdsMapChart = {
|
||||
//backgroundColor: '',
|
||||
/*tooltip: {
|
||||
trigger: 'item'
|
||||
},*/
|
||||
geo: {
|
||||
map: 'world',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
zoom: 1,
|
||||
silent: true,
|
||||
//roam: true,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
areaColor: 'rgba(125, 137, 154, 0.25)',
|
||||
borderColor: 'rgba(0, 0, 0, 0)',
|
||||
borderWidth: 1
|
||||
},
|
||||
emphasis: {
|
||||
areaColor: '#2a333d'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: {
|
||||
type: 'effectScatter',
|
||||
coordinateSystem: 'geo',
|
||||
data: pdsMapData,
|
||||
showEffectOn: 'emphasis',
|
||||
rippleEffect: {
|
||||
brushType: 'stroke'
|
||||
},
|
||||
encode: {
|
||||
value: 2
|
||||
},
|
||||
label: {
|
||||
formatter: '{b}',
|
||||
position: 'left'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: function ($) {
|
||||
const status = $.data.value[3];
|
||||
if (status === 'online') {
|
||||
return '#22c55e';
|
||||
}
|
||||
if (status === 'offline') {
|
||||
return '#ef4444';
|
||||
}
|
||||
if (status === 'degraded') {
|
||||
return '#f97316';
|
||||
}
|
||||
return '#71717a';
|
||||
},
|
||||
shadowColor: '#333'
|
||||
},
|
||||
symbolSize: function (val) {
|
||||
return val[2];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function onMapClick(ev) {
|
||||
const host = ev.detail.data.name;
|
||||
if (host) {
|
||||
goto(`/pds/${host}`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full aspect-video">
|
||||
<Chart options={pdsMapChart} on:mapClick={(ev) => onMapClick(ev)} />
|
||||
</div>
|
Rozdílový obsah nebyl zobrazen, protože některé řádky jsou příliš dlouhá
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import { dataTableHandler, tableMapperValues, tableSourceValues } from '@skeletonlabs/skeleton';
|
||||
import { dateDistance, formatNumber } from '$lib/utils.js';
|
||||
import { goto } from '$app/navigation';
|
||||
import { writable } from 'svelte/store';
|
||||
import { page } from '$app/stores';
|
||||
import PDSTable from '$lib/components/PDSTable.svelte';
|
||||
import PDSMap from '$lib/components/PDSMap.svelte';
|
||||
import BasicPage from '$lib/components/BasicPage.svelte';
|
||||
import { orderBy } from 'lodash';
|
||||
import { nats, connected, codec } from '$lib/sockets.js';
|
||||
|
@ -197,6 +197,8 @@
|
|||
<h2 class="h2">All instances</h2>
|
||||
{/if}
|
||||
|
||||
<PDSMap data={baseData} />
|
||||
|
||||
<form on:submit|preventDefault={formSubmit} class="flex gap-4">
|
||||
<input
|
||||
class="input"
|
||||
|
@ -215,11 +217,13 @@
|
|||
All PDS Instances ({formatNumber(sourceData.length)}):
|
||||
{/if}
|
||||
</div>
|
||||
<PDSTable
|
||||
{sourceData}
|
||||
{data}
|
||||
sorting="true"
|
||||
on:headSelected={(e) => onHeadSelected(e)}
|
||||
on:favoriteClick={(e) => onFavoriteClick(e)}
|
||||
/>
|
||||
<div class="min-h-screen">
|
||||
<PDSTable
|
||||
{sourceData}
|
||||
{data}
|
||||
sorting="true"
|
||||
on:headSelected={(e) => onHeadSelected(e)}
|
||||
on:favoriteClick={(e) => onFavoriteClick(e)}
|
||||
/>
|
||||
</div>
|
||||
</BasicPage>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import Chart from '$lib/components/Chart.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { request } from '$lib/api';
|
||||
import { TabGroup, Tab, TabAnchor } from '@skeletonlabs/skeleton';
|
||||
import { TabGroup, Tab, TabAnchor, ProgressRadial, SlideToggle } from '@skeletonlabs/skeleton';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export let data;
|
||||
|
@ -226,6 +226,12 @@
|
|||
<div class="w-full h-64">
|
||||
{#if chartResponseTimes}
|
||||
<Chart options={chartResponseTimes} />
|
||||
{:else}
|
||||
<div class="flex items-center justify-center w-full h-full">
|
||||
<div>
|
||||
<ProgressRadial />
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
|
Načítá se…
Odkázat v novém úkolu