Skip to content
This repository was archived by the owner on Dec 5, 2025. It is now read-only.

Commit 5c2635c

Browse files
author
Isa Noguchi
committed
Merge branch 'main-nuxt' of github.com:kodadot/nft-gallery into 984-add-serviceworker
2 parents afaae5b + 90412cb commit 5c2635c

File tree

13 files changed

+920
-473
lines changed

13 files changed

+920
-473
lines changed

.github/workflows/lint.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: Lint Files
22

33
on:
44
push:
5-
branches: [ main ]
5+
branches: [ main, main-nuxt ]
66
pull_request:
7-
branches: [ main ]
7+
branches: [ main, main-nuxt ]
88

99
jobs:
1010
lint:
@@ -16,10 +16,10 @@ jobs:
1616
- name: Setup Node.js
1717
uses: actions/setup-node@v1
1818
with:
19-
node-version: "14"
19+
node-version: "16"
2020

2121
- name: Install Dependencies
2222
run: yarn
2323

24-
- name: Lint Code
25-
run: yarn lint
24+
- name: Run Code Lint
25+
run: yarn lint:quiet

coingecko.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,39 @@ import Axios from 'axios'
33
export const BASE_URL = 'https://api.coingecko.com/api/v3'
44

55
const api = Axios.create({
6-
baseURL: BASE_URL,
7-
headers: {
8-
'Content-Type': 'application/json'
9-
},
10-
withCredentials: false
11-
})
6+
baseURL: BASE_URL,
7+
headers: {
8+
'Content-Type': 'application/json',
9+
},
10+
withCredentials: false,
11+
})
12+
13+
export const getKsmPrice = async (): Promise<void> => {
14+
try {
15+
const { data } = await api.get('/simple/price', {
16+
params: {
17+
ids: 'kusama',
18+
vs_currencies: 'usd',
19+
}
20+
})
21+
22+
return data
23+
} catch (error) {
24+
console.log(error)
25+
}
26+
}
1227

1328
export const getKSMUSD = async (): Promise<number> => {
14-
const coinId: string = 'kusama'
29+
const coinId = 'kusama'
1530
try {
16-
const { data } = await api.get(`/simple/price`, {
31+
const { data } = await api.get('/simple/price', {
1732
params: {
1833
ids: coinId,
1934
vs_currencies: 'usd'
2035
}
2136
})
2237

23-
return data[coinId]['usd'];
38+
return data[coinId]['usd']
2439
} catch (error) {
2540
console.log(error)
2641
return 1
Lines changed: 139 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,177 @@
11
<template>
22
<div class="price-chart mt-4">
3-
<p class="label">
4-
{{ $t('Price Chart') }}
5-
</p>
6-
<div id="chart" ref="chart" class="echart"></div>
3+
<div class="is-flex is-align-items-center is-justify-content-space-between">
4+
<p class="label">
5+
{{ $t('Price Chart') }}
6+
</p>
7+
<b-button type="is-primary" @click="resetZoom">Reset zoom</b-button>
8+
</div>
9+
<div class="mt-5">
10+
<canvas
11+
id="collectionPriceChart"
12+
@mousedown="onCanvasMouseDown"
13+
@mouseup="onCanvasMouseUp"
14+
@mouseleave="onCanvasMouseLeave"
15+
/>
16+
</div>
717
</div>
818
</template>
919

1020
<script lang="ts">
11-
import { Component, Vue, Prop, Watch } from 'nuxt-property-decorator'
21+
import { Component, mixins, Prop, Watch } from 'nuxt-property-decorator';
22+
import { Debounce } from 'vue-debounce-decorator';
23+
import Chart from 'chart.js/auto';
24+
import 'chartjs-adapter-luxon';
25+
import zoomPlugin from 'chartjs-plugin-zoom';
26+
import ChainMixin from '@/utils/mixins/chainMixin';
1227
13-
import * as ECharts from 'echarts/core'
14-
import { GridComponent } from 'echarts/components'
15-
import { LineChart } from 'echarts/charts'
16-
import { UniversalTransition } from 'echarts/features'
17-
import { CanvasRenderer } from 'echarts/renderers'
18-
import { TooltipComponent } from 'echarts/components'
19-
import { DataZoomComponent } from 'echarts/components'
28+
import { getChartData } from '@/utils/chart';
2029
21-
import { LegendComponent } from 'echarts/components'
30+
Chart.register(zoomPlugin);
2231
23-
ECharts.use([GridComponent, LineChart, CanvasRenderer, UniversalTransition, TooltipComponent, DataZoomComponent, LegendComponent])
24-
25-
const components = {
26-
}
32+
const components = {};
2733
2834
@Component({ components })
29-
export default class PriceChart extends Vue {
30-
@Prop() public priceData!: any[];
31-
// @Prop() public eventData!: Date[];
35+
export default class PriceChart extends mixins(ChainMixin) {
36+
@Prop() public priceData!: [Date, number][][];
3237
3338
protected chartOptionsLine: any = {};
34-
protected Chart!: ECharts.ECharts;
39+
protected Chart!: Chart<'line', any, unknown>;
40+
41+
@Debounce(200)
42+
protected resetZoom(): void {
43+
this.Chart.resetZoom();
44+
}
3545
3646
protected onWindowResize() {
3747
if (this.Chart) {
38-
this.Chart.resize({ width: 'auto', height: 400 })
48+
this.Chart.resize();
3949
}
4050
}
4151
52+
protected onCanvasMouseDown(): void {
53+
document!.getElementById('collectionPriceChart')!.style.cursor = 'grabbing';
54+
}
55+
56+
protected onCanvasMouseUp(): void {
57+
document!.getElementById('collectionPriceChart')!.style.cursor = 'auto';
58+
}
59+
60+
protected onCanvasMouseLeave(): void {
61+
document!.getElementById('collectionPriceChart')!.style.cursor = 'auto';
62+
}
63+
4264
public async created() {
43-
window.addEventListener('resize', this.onWindowResize)
65+
window.addEventListener('resize', this.onWindowResize);
4466
}
4567
4668
public async mounted() {
47-
this.priceChart()
69+
this.priceChart();
4870
}
4971
5072
protected priceChart() {
51-
52-
this.Chart = ECharts.init(this.$refs.chart as HTMLElement)
53-
this.Chart.setOption({
54-
tooltip: {
55-
trigger: 'item',
56-
formatter: (params: { data: string[], seriesName: string }) => {
57-
const date = this.parseDate(
58-
params.data[0] as unknown as Date
59-
)
60-
const price = params.data[1] + ' KSM'
61-
62-
return '<center>' + date + '<br>' + price + '</center>'
63-
},
64-
backgroundColor: '#363636',
65-
textStyle: {
66-
color: '#fff',
67-
fontFamily: 'Fira Code',
73+
if (this.priceData.length) {
74+
const ctx = (
75+
document?.getElementById('collectionPriceChart') as HTMLCanvasElement
76+
)?.getContext('2d')!;
77+
const chart = new Chart(ctx, {
78+
type: 'line',
79+
data: {
80+
datasets: [
81+
{
82+
label: 'Floor Price',
83+
data: getChartData(this.priceData[0]),
84+
borderColor: '#d32e79',
85+
tension: 0.3,
86+
pointBackgroundColor: 'white',
87+
pointBorderColor: 'blue',
88+
pointRadius: 4,
89+
pointHoverRadius: 6,
90+
},
91+
{
92+
label: 'Sold NFT Price',
93+
data: getChartData(this.priceData[1]),
94+
borderColor: '#00BB7F',
95+
tension: 0.3,
96+
pointBackgroundColor: 'white',
97+
pointBorderColor: 'blue',
98+
pointRadius: 4,
99+
pointHoverRadius: 6,
100+
},
101+
],
68102
},
69-
},
70-
legend: {
71-
data: ['Floor Price', 'Sold NFT Price'],
72-
itemGap: 15,
73-
inactiveColor: '#',
74-
textStyle: {
75-
color: '#fff',
76-
}
77-
},
78-
xAxis: {
79-
type: 'time',
80-
boundaryGap: false,
81-
axisLabel: {
82-
fontFamily: 'Fira Code',
83-
color: '#fff',
84-
hideOverlap: true,
85-
},
86-
},
87-
yAxis: {
88-
type: 'value',
89-
axisLabel: {
90-
formatter: '{value} KSM',
91-
fontFamily: 'Fira Code',
92-
color: '#fff',
93-
},
94-
splitLine: {
95-
lineStyle: {
96-
color: '#f8f8f8',
97-
opacity: '.2'
98-
}
99-
},
100-
nameTextStyle: {
101-
color: '#fff',
102-
fontFamily: 'Fira Code',
103-
},
104-
},
105-
dataZoom: {
106-
type: 'slider',
107-
bottom: '2%',
108-
},
109-
series: [
110-
{
111-
name: 'Floor Price',
112-
type: 'line',
113-
smooth: 'true',
114-
lineStyle: {
115-
color: '#d32e79',
103+
options: {
104+
plugins: {
105+
zoom: {
106+
limits: {
107+
x: { min: 0 },
108+
y: { min: 0 },
109+
},
110+
pan: {
111+
enabled: true,
112+
},
113+
zoom: {
114+
wheel: {
115+
enabled: true,
116+
},
117+
pinch: {
118+
enabled: true,
119+
},
120+
mode: 'xy',
121+
onZoomComplete({ chart }) {
122+
chart.update('none');
123+
},
124+
},
125+
},
116126
},
117-
data: this.priceData[0],
118-
},
119-
{
120-
name: 'Sold NFT Price',
121-
type: 'line',
122-
smooth: 'true',
123-
lineStyle: {
124-
color: '#00BB7F',
127+
scales: {
128+
x: {
129+
type: 'time',
130+
time: {
131+
unit: 'day',
132+
stepSize: 7,
133+
},
134+
grid: {
135+
drawOnChartArea: false,
136+
drawTicks: false,
137+
drawBorder: false,
138+
},
139+
ticks: {
140+
callback: (value) => {
141+
return value;
142+
},
143+
major: {
144+
enabled: true,
145+
},
146+
maxRotation: 0,
147+
minRotation: 0,
148+
color: '#fff',
149+
},
150+
},
151+
y: {
152+
ticks: {
153+
callback: (value) => {
154+
return `${Number(value).toFixed(2)} ${this.unit}`;
155+
},
156+
maxTicksLimit: 7,
157+
158+
color: '#fff',
159+
},
160+
grid: {
161+
color: '#3a3a3a',
162+
},
163+
},
125164
},
126-
data: this.priceData[1],
127165
},
128-
],
129-
})
130-
131-
this.Chart.resize({ width: 'auto', height: 400 })
132-
}
133-
134-
protected parseDate(date: Date) {
135-
const utcDate: string = date.toUTCString()
136-
return utcDate.substring(4)
137-
}
166+
});
138167
139-
protected formatDate(date: Date) {
140-
const yyyy = date.getUTCFullYear()
141-
const mm = this.padDigits(date.getUTCMonth() + 1)
142-
const dd = this.padDigits(date.getUTCDate())
143-
const hrs = this.padDigits(date.getUTCHours())
144-
const mins = this.padDigits(date.getUTCMinutes())
145-
const secs = this.padDigits(date.getUTCSeconds())
146-
const YYYY_MM_DD_HRS_MINS_SECS =
147-
yyyy + '/' + mm + '/' + dd + '\n' + hrs + ':' + mins + ':' + secs
148-
return YYYY_MM_DD_HRS_MINS_SECS
149-
}
150-
151-
protected padDigits(time: number) {
152-
return time.toString().padStart(2, '0')
168+
this.Chart = chart;
169+
}
153170
}
154171
155172
@Watch('priceData')
156173
async watchData(newPriceData: string[], oldPriceData: string[]) {
157-
this.priceChart()
174+
this.priceChart();
158175
}
159176
}
160177
</script>

0 commit comments

Comments
 (0)