实现图表完整功能;接入2个新的数据接口

This commit is contained in:
wangyifeng 2025-05-30 23:21:20 +08:00
parent 208a426324
commit 664b66b414
17 changed files with 1376 additions and 228 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,137 +1,34 @@
<template> <script setup>
<div class="custom-echarts"> import { computed } from 'vue'
<div id="myEcharts" class="myChart"></div> import { useWindowSize } from '@vueuse/core'
</div>
</template> import size375 from '@/components/customEcharts/size375/index.vue'
<script setup> import size768 from '@/components/customEcharts/size375/index.vue'
import { onMounted } from 'vue' import size1440 from '@/components/customEcharts/size1920/index.vue'
import * as echarts from 'echarts' import size1920 from '@/components/customEcharts/size1920/index.vue'
import { useRouter } from 'vue-router'
//eCharts import { useI18n } from 'vue-i18n'
const initEcharts = () => {
// domecharts const router = useRouter()
var myCharts = echarts.init(document.getElementById('myEcharts')) const { width } = useWindowSize()
// const { t } = useI18n()
myCharts.setOption({
title: { const viewComponent = computed(() => {
text: 'FiEE, Inc. Stock Price History', const viewWidth = width.value
}, if (viewWidth <= 500) {
tooltip: { return size375
trigger: 'axis', } else if (viewWidth <= 960) {
axisPointer: { return size768
type: 'line', } else if (viewWidth <= 1500) {
snap: true, return size1440
label: { } else if (viewWidth <= 1920 || viewWidth > 1920) {
backgroundColor: '#6a7985' return size1920
} }
}, })
formatter: function (params) { </script>
const p = params[0];
return `${p.axisValue}<br/>Price: ${p.data}`; <template>
} <component :is="viewComponent" />
}, </template>
xAxis: {
data: ['2013', '2015', '2017', '2019', '2021', '2023', '2025'], <style scoped lang="scss"></style>
type: 'category',
boundaryGap: false,
},
yAxis: {
type: 'value',
position: 'right',
interval: 25,
max: 75.0,
show: true,
},
series: [
{
name: '销量',
type: 'line',
data: [5, 20, 36, 10, 10, 20],
symbol: 'none',
lineStyle: {
color: '#2c6288'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#2c6288'
},
{
offset: 1,
color: '#F4F6F8'
}
]
},
},
},
],
dataZoom: [
{
type: 'inside',
},
{
type: 'slider',
show: true,
dataBackground: {
lineStyle: {
color: '#2C6288'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 1, color: '#2c6288' },
{ offset: 0, color: '#F4F6F8' }
]
}
}
},
selectedDataBackground: {
lineStyle: {
color: '#2C6288'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 1, color: '#2c6288' },
{ offset: 0, color: '#F4F6F8' }
]
}
}
},
fillerColor: 'rgba(44, 98, 136, 0.3)',
realtime: false,
},
],
})
}
onMounted(() => {
initEcharts()
})
</script>
<style lang="scss" scoped>
.custom-echarts {
.myChart {
width: 1000px;
height: 400px;
}
}
</style>

View File

@ -0,0 +1,593 @@
<template>
<div class="custom-echarts">
<div>
<div class="echarts-header">
<div class="echarts-header-title">
<span>FiEE, Inc. Stock Price History</span>
</div>
<div class="echarts-search-area">
<div class="echarts-search-byRange">
<text style="font-size: 0.9rem; font-weight: 400; color: #666666;">
Range
</text>
<div class="search-range-list">
<div
class="search-range-list-each"
v-for="(item, index) in state.searchRange"
:key="index"
@click="changeSearchRange(item)"
>
<span>{{ item }}</span>
</div>
</div>
</div>
<div class="echarts-search-byDate">
<n-date-picker
v-model:value="state.selectHistoricStartDate"
type="date"
:is-date-disabled="disableAfterDate"
@update:value="changeSearchRangeStartDate"
input-readonly
/>
<!-- <n-icon size="16">
<ArrowForwardOutline />
</n-icon> -->
<span>to</span>
<n-date-picker
v-model:value="state.selectHistoricEndDate"
type="date"
:is-date-disabled="disablePreviousDate"
@update:value="changeSearchRangeEndDate"
input-readonly
/>
</div>
</div>
</div>
</div>
<div id="myEcharts" class="myChart"></div>
</div>
</template>
<script setup>
import { onMounted, watch, reactive } from 'vue'
import * as echarts from 'echarts'
import markPointerIcon from '@/assets/image/icon/echarts_markPointer.png'
import axios from 'axios'
import { NDatePicker, NIcon } from 'naive-ui'
import { ArrowForwardOutline } from '@vicons/ionicons5'
const state = reactive({
searchRange: ['1m', '3m', 'YTD', '1Y', '5Y', '10Y', 'Max'],
selectHistoricStartDate: '2009-10-07',
selectHistoricEndDate: new Date(),
})
let myCharts = null
let historicData = []
let xAxisData = []
//eCharts
const initEcharts = (data) => {
historicData = data
xAxisData = data.map((item) => {
return new Date(item.date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
})
const yAxisData = data.map((item) => item.price)
console.error(xAxisData, yAxisData)
// domecharts
myCharts = echarts.init(document.getElementById('myEcharts'))
//
myCharts.setOption({
// title: {
// text: 'FiEE, Inc. Stock Price History',
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
snap: true,
label: {
backgroundColor: '#6a7985',
},
},
formatter: function (params) {
const p = params[0]
return `<span style="font-size: 1.1rem; font-weight: 600;">${p.axisValue}</span><br/><span style="font-size: 0.9rem; font-weight: 400;">Price: ${p.data}</span>`
},
},
xAxis: {
data: xAxisData,
type: 'category',
boundaryGap: false,
inverse: true,
axisLine: {
lineStyle: {
color: '#CCD6EB',
},
},
axisLabel: {
color: '#323232',
fontWeight: 'bold',
// formatter: function (value) {
// return value ? value.split('-')[0] : ''
// },
// interval: function (index, value) {
// if (index === 0) return true;
// const axisData = this && this.axis && this.axis.data ? this.axis.data : [];
// if (!axisData[index - 1]) return true;
// return value.split('-')[0] !== axisData[index - 1].split('-')[0];
// },
},
},
yAxis: {
type: 'value',
position: 'right',
interval: 25,
// max: 75.0,
show: true,
axisLabel: {
color: '#323232',
fontWeight: 'bold',
formatter: function (value) {
return value > 0 ? value.toFixed(2) : value
},
},
},
series: [
{
data: yAxisData,
type: 'line',
sampling: 'lttb',
symbol: 'none',
lineStyle: {
color: '#2c6288',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#2c6288',
},
{
offset: 1,
color: '#F4F6F8',
},
],
},
},
markPoint: {
symbol: 'image://' + markPointerIcon,
symbolSize: 24,
data: [],
},
},
],
dataZoom: [
{
type: 'inside',
},
{
type: 'slider',
show: true,
dataBackground: {
lineStyle: {
color: '#2C6288',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 1, color: '#2c6288' },
{ offset: 0, color: '#F4F6F8' },
],
},
},
},
selectedDataBackground: {
lineStyle: {
color: '#2C6288',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 1, color: '#2c6288' },
{ offset: 0, color: '#F4F6F8' },
],
},
},
},
fillerColor: 'rgba(44, 98, 136, 0.3)',
realtime: false,
},
],
})
// showTip markPoint
myCharts.on('showTip', function (params) {
if (params) {
const dataIndex = params.dataIndex
const x = myCharts.getOption().xAxis[0].data[dataIndex]
const y = myCharts.getOption().series[0].data[dataIndex]
myCharts.setOption({
series: [
{
markPoint: {
symbol: 'image://' + markPointerIcon,
symbolSize: 24,
data: [{ coord: [x, y] }],
},
},
],
})
}
})
// markPoint
myCharts.on('globalout', function () {
myCharts.setOption({
series: [
{
markPoint: {
symbol: 'image://' + markPointerIcon,
symbolSize: 24,
data: [],
},
},
],
})
})
myCharts.on('dataZoom', function (params) {
// dataZoom
const option = myCharts.getOption()
const xAxisData = option.xAxis[0].data
const dataZoom = option.dataZoom[1] || option.dataZoom[0]
// dataZoom startValue endValue
let startValue = dataZoom.endValue
let endValue = dataZoom.startValue
//
if (typeof startValue === 'number') {
startValue = xAxisData[startValue]
}
if (typeof endValue === 'number') {
endValue = xAxisData[endValue]
}
//
state.selectHistoricStartDate = new Date(startValue)
state.selectHistoricEndDate = new Date(endValue)
})
}
onMounted(() => {
getHistoricalData()
})
//
const getHistoricalData = async () => {
let now = new Date()
let toDate =
now.getFullYear() +
'-' +
String(now.getMonth() + 1).padStart(2, '0') +
'-' +
String(now.getDate()).padStart(2, '0')
let url =
'https://common.szjixun.cn/api/stock/history/base/list?from=2009-10-07&to=' +
toDate
const res = await axios.get(url)
if (res.status === 200) {
if (res.data.status === 0) {
initEcharts(res.data.data)
}
}
}
//
function findClosestDateIndex(data, targetDateStr) {
let left = 0,
right = data.length - 1
const target = new Date(targetDateStr).getTime()
let res = data.length - 1 //
while (left <= right) {
const mid = Math.floor((left + right) / 2)
const midTime = new Date(data[mid].date).getTime()
if (midTime > target) {
left = mid + 1
} else {
res = mid
right = mid - 1
}
}
return res
}
//
function findClosestDateIndexDescLeft(data, targetDateStr) {
let left = 0,
right = data.length - 1
const target = new Date(targetDateStr).getTime()
let res = -1 // -1
while (left <= right) {
const mid = Math.floor((left + right) / 2)
const midTime = new Date(data[mid].date).getTime()
if (midTime < target) {
right = mid - 1 //
} else {
res = mid //
left = mid + 1 //
}
}
return res
}
//
const changeSearchRange = (range, dateTime) => {
const now = new Date()
let startDate = ''
let endDate = ''
if (range === '1m') {
const last = new Date(now)
last.setMonth(now.getMonth() - 1)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '3m') {
const last = new Date(now)
last.setMonth(now.getMonth() - 3)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === 'YTD') {
startDate = new Date(now.getFullYear(), 0, 1).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '1Y') {
const last = new Date(now)
last.setFullYear(now.getFullYear() - 1)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '5Y') {
const last = new Date(now)
last.setFullYear(now.getFullYear() - 5)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '10Y') {
const last = new Date(now)
last.setFullYear(now.getFullYear() - 10)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === 'Max') {
startDate = ''
endDate = ''
} else if (range === 'startDateTime') {
startDate = dateTime
endDate = ''
} else if (range === 'endDateTime') {
startDate = ''
endDate = dateTime
}
if (startDate || endDate) {
// historicData xAxisData initEcharts
if (
typeof historicData !== 'undefined' &&
typeof xAxisData !== 'undefined'
) {
let startValue = xAxisData[0]
if (startDate) {
const idx = findClosestDateIndex(historicData, startDate)
// historicData[idx].date xAxisData
startValue = new Date(historicData[idx].date).toLocaleDateString(
'en-US',
{
month: 'short',
day: 'numeric',
year: 'numeric',
},
)
}
let endValue = endDate
if (endDate) {
console.warn(endDate)
const idx = findClosestDateIndexDescLeft(historicData, endDate)
console.warn(idx)
// historicData[idx].date xAxisData
endValue = new Date(historicData[idx].date).toLocaleDateString(
'en-US',
{
month: 'short',
day: 'numeric',
year: 'numeric',
},
)
console.warn(endValue)
}
if (startDate) {
myCharts.setOption({
dataZoom: {
endValue: startValue,
},
})
state.selectHistoricStartDate = new Date(startValue)
}
if (endDate) {
myCharts.setOption({
dataZoom: {
startValue: endValue,
},
})
state.selectHistoricEndDate = new Date(endValue)
}
}
} else {
myCharts.setOption({
dataZoom: {
startValue: '',
endValue: '',
},
})
state.selectHistoricStartDate = new Date('2009-10-07')
state.selectHistoricEndDate = new Date()
}
}
// 2009-10-07
const disableAfterDate = (date) => {
return date < new Date('2009-10-06') || date > new Date()
}
//
const disablePreviousDate = (date) => {
return date < new Date(state.selectHistoricStartDate) || date > new Date()
}
//
const changeSearchRangeStartDate = (date) => {
console.error(date)
changeSearchRange(
'startDateTime',
new Date(date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
}),
)
}
//
const changeSearchRangeEndDate = (date) => {
console.error(date)
changeSearchRange(
'endDateTime',
new Date(date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
}),
)
}
</script>
<style lang="scss" scoped>
.custom-echarts {
.myChart {
width: 100%;
height: 25rem;
}
.echarts-header {
.echarts-header-title {
span {
font-size: 2rem;
font-weight: 600;
color: #323232;
}
}
.echarts-search-area {
padding: 2rem 0 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.echarts-search-byRange {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 10px;
.search-range-list {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 10px;
.search-range-list-each {
padding: 5px 10px;
border-radius: 5px;
background-color: #f3f4f6;
cursor: pointer;
span {
font-weight: 600;
font-size: 0.9rem;
}
}
}
}
.echarts-search-byDate {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 0.4rem;
}
}
}
}
</style>

View File

@ -0,0 +1,595 @@
<template>
<div class="custom-echarts">
<div>
<div class="echarts-header">
<div class="echarts-header-title">
<span>FiEE, Inc. Stock Price History</span>
</div>
<div class="echarts-search-area">
<div class="echarts-search-byRange">
<text style="font-size: 0.9rem; font-weight: 400; color: #666666;">
Range
</text>
<div class="search-range-list">
<div
class="search-range-list-each"
v-for="(item, index) in state.searchRange"
:key="index"
@click="changeSearchRange(item)"
>
<span>{{ item }}</span>
</div>
</div>
</div>
<div class="echarts-search-byDate">
<n-date-picker
v-model:value="state.selectHistoricStartDate"
type="date"
:is-date-disabled="disableAfterDate"
@update:value="changeSearchRangeStartDate"
input-readonly
/>
<!-- <n-icon size="30">
<ArrowForwardOutline />
</n-icon> -->
<span>to</span>
<n-date-picker
v-model:value="state.selectHistoricEndDate"
type="date"
:is-date-disabled="disablePreviousDate"
@update:value="changeSearchRangeEndDate"
input-readonly
/>
</div>
</div>
</div>
</div>
<div id="myEcharts" class="myChart"></div>
</div>
</template>
<script setup>
import { onMounted, watch, reactive } from 'vue'
import * as echarts from 'echarts'
import markPointerIcon from '@/assets/image/icon/echarts_markPointer.png'
import axios from 'axios'
import { NDatePicker } from 'naive-ui'
import { ArrowForwardOutline } from '@vicons/ionicons5'
const state = reactive({
searchRange: ['1m', '3m', 'YTD', '1Y', '5Y', '10Y', 'Max'],
selectHistoricStartDate: '2009-10-07',
selectHistoricEndDate: new Date(),
})
let myCharts = null
let historicData = []
let xAxisData = []
//eCharts
const initEcharts = (data) => {
historicData = data
xAxisData = data.map((item) => {
return new Date(item.date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
})
const yAxisData = data.map((item) => item.price)
console.error(xAxisData, yAxisData)
// domecharts
myCharts = echarts.init(document.getElementById('myEcharts'))
//
myCharts.setOption({
// title: {
// text: 'FiEE, Inc. Stock Price History',
// },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
snap: true,
label: {
backgroundColor: '#6a7985',
},
},
formatter: function (params) {
const p = params[0]
return `<span style="font-size: 1.1rem; font-weight: 600;">${p.axisValue}</span><br/><span style="font-size: 0.9rem; font-weight: 400;">Price: ${p.data}</span>`
},
},
xAxis: {
data: xAxisData,
type: 'category',
boundaryGap: false,
inverse: true,
axisLine: {
lineStyle: {
color: '#CCD6EB',
},
},
axisLabel: {
color: '#323232',
fontWeight: 'bold',
// formatter: function (value) {
// return value ? value.split('-')[0] : ''
// },
// interval: function (index, value) {
// if (index === 0) return true;
// const axisData = this && this.axis && this.axis.data ? this.axis.data : [];
// if (!axisData[index - 1]) return true;
// return value.split('-')[0] !== axisData[index - 1].split('-')[0];
// },
},
},
yAxis: {
type: 'value',
position: 'right',
interval: 25,
// max: 75.0,
show: true,
axisLabel: {
color: '#323232',
fontWeight: 'bold',
formatter: function (value) {
return value > 0 ? value.toFixed(2) : value
},
},
},
series: [
{
data: yAxisData,
type: 'line',
sampling: 'lttb',
symbol: 'none',
lineStyle: {
color: '#2c6288',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#2c6288',
},
{
offset: 1,
color: '#F4F6F8',
},
],
},
},
markPoint: {
symbol: 'image://' + markPointerIcon,
symbolSize: 24,
data: [],
},
},
],
dataZoom: [
{
type: 'inside',
},
{
type: 'slider',
show: true,
dataBackground: {
lineStyle: {
color: '#2C6288',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 1, color: '#2c6288' },
{ offset: 0, color: '#F4F6F8' },
],
},
},
},
selectedDataBackground: {
lineStyle: {
color: '#2C6288',
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 1, color: '#2c6288' },
{ offset: 0, color: '#F4F6F8' },
],
},
},
},
fillerColor: 'rgba(44, 98, 136, 0.3)',
realtime: false,
},
],
})
// showTip markPoint
myCharts.on('showTip', function (params) {
if (params) {
const dataIndex = params.dataIndex
const x = myCharts.getOption().xAxis[0].data[dataIndex]
const y = myCharts.getOption().series[0].data[dataIndex]
myCharts.setOption({
series: [
{
markPoint: {
symbol: 'image://' + markPointerIcon,
symbolSize: 24,
data: [{ coord: [x, y] }],
},
},
],
})
}
})
// markPoint
myCharts.on('globalout', function () {
myCharts.setOption({
series: [
{
markPoint: {
symbol: 'image://' + markPointerIcon,
symbolSize: 24,
data: [],
},
},
],
})
})
myCharts.on('dataZoom', function (params) {
// dataZoom
const option = myCharts.getOption()
const xAxisData = option.xAxis[0].data
const dataZoom = option.dataZoom[1] || option.dataZoom[0]
// dataZoom startValue endValue
let startValue = dataZoom.endValue
let endValue = dataZoom.startValue
//
if (typeof startValue === 'number') {
startValue = xAxisData[startValue]
}
if (typeof endValue === 'number') {
endValue = xAxisData[endValue]
}
//
state.selectHistoricStartDate = new Date(startValue)
state.selectHistoricEndDate = new Date(endValue)
})
}
onMounted(() => {
getHistoricalData()
})
//
const getHistoricalData = async () => {
let now = new Date()
let toDate =
now.getFullYear() +
'-' +
String(now.getMonth() + 1).padStart(2, '0') +
'-' +
String(now.getDate()).padStart(2, '0')
let url =
'https://common.szjixun.cn/api/stock/history/base/list?from=2009-10-07&to=' +
toDate
const res = await axios.get(url)
if (res.status === 200) {
if (res.data.status === 0) {
initEcharts(res.data.data)
}
}
}
//
function findClosestDateIndex(data, targetDateStr) {
let left = 0,
right = data.length - 1
const target = new Date(targetDateStr).getTime()
let res = data.length - 1 //
while (left <= right) {
const mid = Math.floor((left + right) / 2)
const midTime = new Date(data[mid].date).getTime()
if (midTime > target) {
left = mid + 1
} else {
res = mid
right = mid - 1
}
}
return res
}
//
function findClosestDateIndexDescLeft(data, targetDateStr) {
let left = 0,
right = data.length - 1
const target = new Date(targetDateStr).getTime()
let res = -1 // -1
while (left <= right) {
const mid = Math.floor((left + right) / 2)
const midTime = new Date(data[mid].date).getTime()
if (midTime < target) {
right = mid - 1 //
} else {
res = mid //
left = mid + 1 //
}
}
return res
}
//
const changeSearchRange = (range, dateTime) => {
const now = new Date()
let startDate = ''
let endDate = ''
if (range === '1m') {
const last = new Date(now)
last.setMonth(now.getMonth() - 1)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '3m') {
const last = new Date(now)
last.setMonth(now.getMonth() - 3)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === 'YTD') {
startDate = new Date(now.getFullYear(), 0, 1).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '1Y') {
const last = new Date(now)
last.setFullYear(now.getFullYear() - 1)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '5Y') {
const last = new Date(now)
last.setFullYear(now.getFullYear() - 5)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === '10Y') {
const last = new Date(now)
last.setFullYear(now.getFullYear() - 10)
startDate = last.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
endDate = new Date(new Date()).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
} else if (range === 'Max') {
startDate = ''
endDate = ''
} else if (range === 'startDateTime') {
startDate = dateTime
endDate = ''
} else if (range === 'endDateTime') {
startDate = ''
endDate = dateTime
}
if (startDate || endDate) {
// historicData xAxisData initEcharts
if (
typeof historicData !== 'undefined' &&
typeof xAxisData !== 'undefined'
) {
let startValue = xAxisData[0]
if (startDate) {
const idx = findClosestDateIndex(historicData, startDate)
// historicData[idx].date xAxisData
startValue = new Date(historicData[idx].date).toLocaleDateString(
'en-US',
{
month: 'short',
day: 'numeric',
year: 'numeric',
},
)
}
let endValue = endDate
if (endDate) {
console.warn(endDate)
const idx = findClosestDateIndexDescLeft(historicData, endDate)
console.warn(idx)
// historicData[idx].date xAxisData
endValue = new Date(historicData[idx].date).toLocaleDateString(
'en-US',
{
month: 'short',
day: 'numeric',
year: 'numeric',
},
)
console.warn(endValue)
}
if (startDate) {
myCharts.setOption({
dataZoom: {
endValue: startValue,
},
})
state.selectHistoricStartDate = new Date(startValue)
}
if (endDate) {
myCharts.setOption({
dataZoom: {
startValue: endValue,
},
})
state.selectHistoricEndDate = new Date(endValue)
}
}
} else {
myCharts.setOption({
dataZoom: {
startValue: '',
endValue: '',
},
})
state.selectHistoricStartDate = new Date('2009-10-07')
state.selectHistoricEndDate = new Date()
}
}
// 2009-10-07
const disableAfterDate = (date) => {
return date < new Date('2009-10-06') || date > new Date()
}
//
const disablePreviousDate = (date) => {
return date < new Date(state.selectHistoricStartDate) || date > new Date()
}
//
const changeSearchRangeStartDate = (date) => {
console.error(date)
changeSearchRange(
'startDateTime',
new Date(date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
}),
)
}
//
const changeSearchRangeEndDate = (date) => {
console.error(date)
changeSearchRange(
'endDateTime',
new Date(date).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
}),
)
}
</script>
<style lang="scss" scoped>
.custom-echarts {
.myChart {
width: 100%;
height: 25rem;
}
.echarts-header {
.echarts-header-title {
span {
font-size: 2rem;
font-weight: 600;
color: #323232;
}
}
.echarts-search-area {
padding: 2rem 0 0;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
.echarts-search-byRange {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 0.7rem;
.search-range-list {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 0.7rem;
.search-range-list-each {
padding: 0.2rem 0.3rem;
border-radius: 5px;
background-color: #f3f4f6;
cursor: pointer;
span {
font-weight: 600;
font-size: 0.9rem;
}
}
}
}
.echarts-search-byDate {
padding: 1.5rem 0 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
gap: 0.4rem;
}
}
}
}
</style>

View File

@ -67,8 +67,15 @@ const getLastTradingDay = () => {
const formatted = ref(getLastTradingDay()) const formatted = ref(getLastTradingDay())
const getStockQuate= async()=>{ const getStockQuate= async()=>{
const res = await axios.get('https://saas-test.szjixun.cn/api/fiee/chart/forward/test') // const res = await axios.get('https://saas-test.szjixun.cn/api/fiee/chart/forward/test')
stockQuote.value=res.data const res = await axios.get('https://common.szjixun.cn/api/stock/company/data')
console.error(res)
if(res.status === 200){
if(res.data.status === 0){
stockQuote.value=res.data.data
console.error(stockQuote.value)
}
}
} }
return { return {
formatted, formatted,

View File

@ -1,15 +1,18 @@
<template> <template>
<div class="historic-data-container" style="margin-bottom: 40px"> <div class="historic-data-container" style="margin-bottom: 40px">
<img <!-- <img
src="@/assets/image/historic-stock.png" src="@/assets/image/historic-stock.png"
alt="1" alt="1"
style="max-width: 100%; margin: 0 auto" style="max-width: 100%; margin: 0 auto"
/> /> -->
<div class="echarts-container">
<customEcharts></customEcharts>
</div>
<div class="header mt-[20px]"> <div class="header mt-[20px]">
<div class="title">Historical Data</div> <div class="title">Historical Data</div>
<div class="filter-container"> <div class="filter-container">
<n-dropdown <!-- <n-dropdown
trigger="click" trigger="click"
:options="periodOptions" :options="periodOptions"
@select="handlePeriodChange" @select="handlePeriodChange"
@ -19,7 +22,7 @@
{{ state.selectedPeriod }} {{ state.selectedPeriod }}
<n-icon><chevron-down-outline /></n-icon> <n-icon><chevron-down-outline /></n-icon>
</n-button> </n-button>
</n-dropdown> </n-dropdown> -->
<n-dropdown <n-dropdown
trigger="click" trigger="click"
@ -92,6 +95,7 @@ import {
ArrowUpOutline, ArrowUpOutline,
} from "@vicons/ionicons5"; } from "@vicons/ionicons5";
import defaultTableData from "../data"; import defaultTableData from "../data";
import customEcharts from '@/components/customEcharts/index.vue'
console.log("defaultTableData", defaultTableData); console.log("defaultTableData", defaultTableData);
// //

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="historic-data-container" style="margin-bottom: 40px;"> <div class="historic-data-container" style="margin-bottom: 40px;">
<img <!-- <img
src="@/assets/image/historic-stock.png" src="@/assets/image/historic-stock.png"
alt="1" alt="1"
style="max-width: 100%; margin: 0 auto;" style="max-width: 100%; margin: 0 auto;"
/> /> -->
<div class="echarts-container"> <div class="echarts-container">
<customEcharts></customEcharts> <customEcharts></customEcharts>
</div> </div>
@ -12,7 +12,7 @@
<div class="header mt-[20px]"> <div class="header mt-[20px]">
<div class="title">Historical Data</div> <div class="title">Historical Data</div>
<div class="filter-container"> <div class="filter-container">
<n-dropdown <!-- <n-dropdown
trigger="click" trigger="click"
:options="periodOptions" :options="periodOptions"
@select="handlePeriodChange" @select="handlePeriodChange"
@ -22,7 +22,7 @@
{{ state.selectedPeriod }} {{ state.selectedPeriod }}
<n-icon><chevron-down-outline /></n-icon> <n-icon><chevron-down-outline /></n-icon>
</n-button> </n-button>
</n-dropdown> </n-dropdown> -->
<n-dropdown <n-dropdown
trigger="click" trigger="click"
@ -127,7 +127,7 @@ const pageSizeOptions = [
const state = reactive({ const state = reactive({
selectedPeriod: 'Daily', selectedPeriod: 'Daily',
selectedDuration: '3 Months', selectedDuration: '6 Months',
tableData: [], tableData: [],
currentPage: 1, currentPage: 1,
pageSize: 50, pageSize: 50,
@ -216,6 +216,7 @@ const handlePeriodChange = (key) => {
const handleDurationChange = (key) => { const handleDurationChange = (key) => {
state.selectedDuration = key state.selectedDuration = key
state.currentPage = 1
getPageData() getPageData()
} }
@ -299,42 +300,86 @@ const getPageDefaultData = async () => {
} }
const getPageData = async () => { const getPageData = async () => {
let range = '' let range = ''
let now = new Date()
const last = new Date(now)
last.setMonth(now.getMonth() - 6)
let fromDate = last
let toDate =
now.getFullYear() +
'-' +
String(now.getMonth() + 1).padStart(2, '0') +
'-' +
String(now.getDate()).padStart(2, '0')
if (state.selectedDuration === '3 Months') { if (state.selectedDuration === '3 Months') {
range = '3M' range = '3M'
const last = new Date(now)
last.setMonth(now.getMonth() - 3)
fromDate = last
} else if (state.selectedDuration === '6 Months') { } else if (state.selectedDuration === '6 Months') {
range = '6M' range = '6M'
const last = new Date(now)
last.setMonth(now.getMonth() - 6)
fromDate = last
} else if (state.selectedDuration === 'Year to Date') { } else if (state.selectedDuration === 'Year to Date') {
range = 'YTD' range = 'YTD'
fromDate = new Date(now.getFullYear(), 0, 1)
} else if (state.selectedDuration === '1 Year') { } else if (state.selectedDuration === '1 Year') {
range = '1Y' range = '1Y'
const last = new Date(now)
last.setFullYear(now.getFullYear() - 1)
fromDate = last
} else if (state.selectedDuration === '5 Years') { } else if (state.selectedDuration === '5 Years') {
range = '5Y' range = '5Y'
const last = new Date(now)
last.setFullYear(now.getFullYear() - 5)
fromDate = last
} else if (state.selectedDuration === '10 Years') { } else if (state.selectedDuration === '10 Years') {
range = '10Y' range = '10Y'
const last = new Date(now)
last.setFullYear(now.getFullYear() - 10)
fromDate = last
} else if (state.selectedDuration === 'Full History') { } else if (state.selectedDuration === 'Full History') {
range = 'Max' range = 'Max'
fromDate = new Date('2009-10-07')
} }
let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}` let finalFromDate =
fromDate.getFullYear() +
'-' +
String(fromDate.getMonth() + 1).padStart(2, '0') +
'-' +
String(fromDate.getDate()).padStart(2, '0')
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
let url =
'https://common.szjixun.cn/api/stock/history/list?from=' +
finalFromDate +
'&to=' +
toDate
const res = await axios.get(url) const res = await axios.get(url)
if (res.data.status === 200) { console.error(res)
// "Nov 26, 2024" if (res.status === 200) {
let resultData = res.data.data.map((item) => { if (res.data.status === 0) {
return { // "Nov 26, 2024"
date: new Date(item.t).toLocaleDateString('en-US', { let resultData = res.data.data.map((item) => {
month: 'short', return {
day: 'numeric', date: new Date(item.date).toLocaleDateString('en-US', {
year: 'numeric', month: 'short',
}), day: 'numeric',
open: item.o != null ? Number(item.o).toFixed(2) : '', year: 'numeric',
high: item.h != null ? Number(item.h).toFixed(2) : '', }),
low: item.l != null ? Number(item.l).toFixed(2) : '', open: item.open != null ? Number(item.open).toFixed(2) : '',
close: item.c != null ? Number(item.c).toFixed(2) : '', high: item.high != null ? Number(item.high).toFixed(2) : '',
adjClose: item.a != null ? Number(item.a).toFixed(2) : '', low: item.low != null ? Number(item.low).toFixed(2) : '',
change: item.ch != null ? Number(item.ch).toFixed(2) + '%' : '', close: item.close != null ? Number(item.close).toFixed(2) : '',
volume: item.v, adjClose: item.close != null ? Number(item.close).toFixed(2) : '',
} change:
}) item.changePercent != null
state.tableData = resultData ? Number(item.changePercent).toFixed(2) + '%'
: '',
volume: item.volume,
}
})
state.tableData = resultData
}
} }
} }
</script> </script>

View File

@ -1,15 +1,18 @@
<template> <template>
<div class="historic-data-container" style="margin-bottom: 40px"> <div class="historic-data-container" style="margin-bottom: 40px">
<img <!-- <img
src="@/assets/image/historic-stock-375.png" src="@/assets/image/historic-stock-375.png"
alt="1" alt="1"
style="max-width: 100%; margin: 0 auto" style="max-width: 100%; margin: 0 auto"
/> /> -->
<div class="echarts-container">
<customEcharts></customEcharts>
</div>
<div class="header mt-[80px]"> <div class="header mt-[80px]">
<div class="title">Historical Data</div> <div class="title">Historical Data</div>
<div class="filter-container"> <div class="filter-container">
<n-dropdown <!-- <n-dropdown
trigger="click" trigger="click"
:options="periodOptions" :options="periodOptions"
@select="handlePeriodChange" @select="handlePeriodChange"
@ -19,7 +22,7 @@
{{ state.selectedPeriod }} {{ state.selectedPeriod }}
<n-icon><chevron-down-outline /></n-icon> <n-icon><chevron-down-outline /></n-icon>
</n-button> </n-button>
</n-dropdown> </n-dropdown> -->
<n-dropdown <n-dropdown
trigger="click" trigger="click"
@ -90,6 +93,7 @@ import {
ArrowUpOutline, ArrowUpOutline,
} from "@vicons/ionicons5"; } from "@vicons/ionicons5";
import defaultTableData from "../data"; import defaultTableData from "../data";
import customEcharts from '@/components/customEcharts/index.vue'
console.log("defaultTableData", defaultTableData); console.log("defaultTableData", defaultTableData);
// //

View File

@ -1,15 +1,18 @@
<template> <template>
<div class="historic-data-container" style="margin-bottom: 40px"> <div class="historic-data-container" style="margin-bottom: 40px">
<img <!-- <img
src="@/assets/image/historic-stock.png" src="@/assets/image/historic-stock.png"
alt="1" alt="1"
style="max-width: 100%; margin: 0 auto" style="max-width: 100%; margin: 0 auto"
/> /> -->
<div class="echarts-container">
<customEcharts></customEcharts>
</div>
<div class="header mt-[20px]"> <div class="header mt-[20px]">
<div class="title">Historical Data</div> <div class="title">Historical Data</div>
<div class="filter-container"> <div class="filter-container">
<n-dropdown <!-- <n-dropdown
trigger="click" trigger="click"
:options="periodOptions" :options="periodOptions"
@select="handlePeriodChange" @select="handlePeriodChange"
@ -19,7 +22,7 @@
{{ state.selectedPeriod }} {{ state.selectedPeriod }}
<n-icon><chevron-down-outline /></n-icon> <n-icon><chevron-down-outline /></n-icon>
</n-button> </n-button>
</n-dropdown> </n-dropdown> -->
<n-dropdown <n-dropdown
trigger="click" trigger="click"
@ -92,6 +95,7 @@ import {
ArrowUpOutline, ArrowUpOutline,
} from "@vicons/ionicons5"; } from "@vicons/ionicons5";
import defaultTableData from "../data"; import defaultTableData from "../data";
import customEcharts from '@/components/customEcharts/index.vue'
console.log("defaultTableData", defaultTableData); console.log("defaultTableData", defaultTableData);
// //

View File

@ -107,7 +107,7 @@
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE") $t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value" <span style="font-size: 18px" class="data-value"
>${{ stockQuote.Open }}</span >${{ stockQuote.open }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -115,8 +115,7 @@
$t("HOME.CONTAINY.STOCK_INFO.CHANGE") $t("HOME.CONTAINY.STOCK_INFO.CHANGE")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value positive" <span style="font-size: 18px" class="data-value positive"
>{{ stockQuote.change?.[0] || "--" }} >{{ stockQuote.change || "--" }}</span
{{ stockQuote.change?.[1] || "--" }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -132,7 +131,7 @@
$t("HOME.CONTAINY.STOCK_INFO.VOLUME") $t("HOME.CONTAINY.STOCK_INFO.VOLUME")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value">{{ <span style="font-size: 18px" class="data-value">{{
stockQuote.Volume stockQuote.volume
}}</span> }}</span>
</div> </div>
<div class="data-row"> <div class="data-row">
@ -140,7 +139,7 @@
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP") $t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value" <span style="font-size: 18px" class="data-value"
>${{ stockQuote.MarketCap }}</span >${{ stockQuote.marketCap }}</span
> >
</div> </div>
</div> </div>

View File

@ -103,15 +103,14 @@
<span class="data-label">{{ <span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE") $t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
}}</span> }}</span>
<span class="data-value">${{ stockQuote.Open }}</span> <span class="data-value">${{ stockQuote.open }}</span>
</div> </div>
<div class="data-row"> <div class="data-row">
<span class="data-label">{{ <span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.CHANGE") $t("HOME.CONTAINY.STOCK_INFO.CHANGE")
}}</span> }}</span>
<span class="data-value positive" <span class="data-value positive"
>{{ stockQuote.change?.[0] || "--" }} >{{ stockQuote.change || "--" }}</span
{{ stockQuote.change?.[1] || "--" }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -124,13 +123,13 @@
<span class="data-label">{{ <span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.VOLUME") $t("HOME.CONTAINY.STOCK_INFO.VOLUME")
}}</span> }}</span>
<span class="data-value">{{ stockQuote.Volume }}</span> <span class="data-value">{{ stockQuote.volume }}</span>
</div> </div>
<div class="data-row"> <div class="data-row">
<span class="data-label">{{ <span class="data-label">{{
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP") $t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
}}</span> }}</span>
<span class="data-value">${{ stockQuote.MarketCap }}</span> <span class="data-value">${{ stockQuote.marketCap }}</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -107,7 +107,7 @@
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE") $t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value" <span style="font-size: 18px" class="data-value"
>${{ stockQuote.Open }}</span >${{ stockQuote.open }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -115,8 +115,7 @@
$t("HOME.CONTAINY.STOCK_INFO.CHANGE") $t("HOME.CONTAINY.STOCK_INFO.CHANGE")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value positive" <span style="font-size: 18px" class="data-value positive"
>{{ stockQuote.change?.[0] || "--" }} >{{ stockQuote.change || "--" }}</span
{{ stockQuote.change?.[1] || "--" }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -132,7 +131,7 @@
$t("HOME.CONTAINY.STOCK_INFO.VOLUME") $t("HOME.CONTAINY.STOCK_INFO.VOLUME")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value">{{ <span style="font-size: 18px" class="data-value">{{
stockQuote.Volume stockQuote.volume
}}</span> }}</span>
</div> </div>
<div class="data-row"> <div class="data-row">
@ -140,7 +139,7 @@
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP") $t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value" <span style="font-size: 18px" class="data-value"
>${{ stockQuote.MarketCap }}</span >${{ stockQuote.marketCap }}</span
> >
</div> </div>
</div> </div>

View File

@ -107,7 +107,7 @@
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE") $t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value" <span style="font-size: 18px" class="data-value"
>${{ stockQuote.Open }}</span >${{ stockQuote.open }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -115,8 +115,7 @@
$t("HOME.CONTAINY.STOCK_INFO.CHANGE") $t("HOME.CONTAINY.STOCK_INFO.CHANGE")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value positive" <span style="font-size: 18px" class="data-value positive"
>{{ stockQuote.change?.[0] || "--" }} >{{ stockQuote.change || "--" }}</span
{{ stockQuote.change?.[1] || "--" }}</span
> >
</div> </div>
<div class="data-row"> <div class="data-row">
@ -132,7 +131,7 @@
$t("HOME.CONTAINY.STOCK_INFO.VOLUME") $t("HOME.CONTAINY.STOCK_INFO.VOLUME")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value">{{ <span style="font-size: 18px" class="data-value">{{
stockQuote.Volume stockQuote.volume
}}</span> }}</span>
</div> </div>
<div class="data-row"> <div class="data-row">
@ -140,7 +139,7 @@
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP") $t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
}}</span> }}</span>
<span style="font-size: 18px" class="data-value" <span style="font-size: 18px" class="data-value"
>${{ stockQuote.MarketCap }}</span >${{ stockQuote.marketCap }}</span
> >
</div> </div>
</div> </div>

View File

@ -12,7 +12,7 @@ getStockQuate()
<main ref="main" class="flex pt-80px flex-col md:flex-row justify-center items-center gap-24 rounded-3xl"> <main ref="main" class="flex pt-80px flex-col md:flex-row justify-center items-center gap-24 rounded-3xl">
<!-- 左侧大号价格 --> <!-- 左侧大号价格 -->
<section class="flex flex-col items-center justify-center glass-card p-24 rounded-2xl shadow-xl"> <section class="flex flex-col items-center justify-center glass-card p-24 rounded-2xl shadow-xl">
<div class="text-8xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.[0].slice(0,4) }}</div> <div class="text-8xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.slice(0,4) }}</div>
<div class="mt-8 text-2xl text-gray-500 font-semibold tracking-widest mb-8px">NASDAQ: <span class="text-black">MINM</span></div> <div class="mt-8 text-2xl text-gray-500 font-semibold tracking-widest mb-8px">NASDAQ: <span class="text-black">MINM</span></div>
<div class="text-gray-500">{{ formatted }}</div> <div class="text-gray-500">{{ formatted }}</div>
</section> </section>
@ -20,29 +20,29 @@ getStockQuate()
<section class="grid grid-cols-2 gap-12"> <section class="grid grid-cols-2 gap-12">
<div class="info-card"> <div class="info-card">
<div class="text-base text-gray-400">Open</div> <div class="text-base text-gray-400">Open</div>
<div class="text-2xl font-bold">{{ stockQuote.Open }}</div> <div class="text-2xl font-bold">{{ stockQuote.open }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-base text-gray-400">Change</div> <div class="text-base text-gray-400">Change</div>
<div class="text-3xl font-bold" <div class="text-3xl font-bold"
:class="stockQuote.change?.[1]?.startsWith('-') ? 'text-red-500' : (stockQuote.change?.[1]?.startsWith('+') ? 'text-green-500' : '')"> :class="stockQuote.change?.includes('-') ? 'text-red-500' : (stockQuote.change?.includes('+') ? 'text-green-500' : '')">
{{ stockQuote.change?.join('') }}</div> {{ stockQuote.change }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-base text-gray-400">Day's Range</div> <div class="text-base text-gray-400">Day's Range</div>
<div class="text-2xl font-bold">{{ stockQuote.DaysRange }}</div> <div class="text-2xl font-bold">{{ stockQuote.daysRange }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-base text-gray-400">52-Week Range</div> <div class="text-base text-gray-400">52-Week Range</div>
<div class="text-2xl font-bold">{{ stockQuote.Week52Range }}</div> <div class="text-2xl font-bold">{{ stockQuote.week52Range }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-base text-gray-400">Volume</div> <div class="text-base text-gray-400">Volume</div>
<div class="text-2xl font-bold">{{ stockQuote.Volume }}</div> <div class="text-2xl font-bold">{{ stockQuote.volume }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-base text-gray-400">Market Cap</div> <div class="text-base text-gray-400">Market Cap</div>
<div class="text-2xl font-bold">{{ stockQuote.MarketCap }}</div> <div class="text-2xl font-bold">{{ stockQuote.marketCap }}</div>
</div> </div>
</section> </section>
</main> </main>

View File

@ -12,7 +12,7 @@ getStockQuate()
> >
<!-- 左侧大号价格 --> <!-- 左侧大号价格 -->
<section class="flex flex-col items-center justify-center glass-card p-32 rounded-2xl shadow-xl "> <section class="flex flex-col items-center justify-center glass-card p-32 rounded-2xl shadow-xl ">
<div class="text-9xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.[0].slice(0,4) }}</div> <div class="text-9xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.slice(0,4) }}</div>
<div class="mt-10 text-3xl text-gray-500 font-semibold tracking-widest mb-10px">NASDAQ: <span class="text-black">MINM</span></div> <div class="mt-10 text-3xl text-gray-500 font-semibold tracking-widest mb-10px">NASDAQ: <span class="text-black">MINM</span></div>
<div class="text-gray-500">{{ formatted }}</div> <div class="text-gray-500">{{ formatted }}</div>
</section> </section>
@ -20,29 +20,32 @@ getStockQuate()
<section class="grid grid-cols-2 gap-16"> <section class="grid grid-cols-2 gap-16">
<div class="info-card"> <div class="info-card">
<div class="text-lg text-gray-400">Open</div> <div class="text-lg text-gray-400">Open</div>
<div class="text-3xl font-bold">{{ stockQuote.Open }}</div> <div class="text-3xl font-bold">{{ stockQuote.open }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-lg text-gray-400">Change</div> <div class="text-lg text-gray-400">Change</div>
<div class="text-3xl font-bold" <!-- <div class="text-3xl font-bold"
:class="stockQuote.change?.[1]?.startsWith('-') ? 'text-red-500' : (stockQuote.change?.[1]?.startsWith('+') ? 'text-green-500' : '')"> :class="stockQuote.change?.[1]?.startsWith('-') ? 'text-red-500' : (stockQuote.change?.[1]?.startsWith('+') ? 'text-green-500' : '')">
{{ stockQuote.change?.join('') }}</div> {{ stockQuote.change?.join('') }}</div> -->
<div class="text-3xl font-bold"
:class="stockQuote.change?.includes('-') ? 'text-red-500' : (stockQuote.change?.includes('+') ? 'text-green-500' : '')">
{{ stockQuote.change }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-lg text-gray-400">Day's Range</div> <div class="text-lg text-gray-400">Day's Range</div>
<div class="text-3xl font-bold">{{ stockQuote.DaysRange }}</div> <div class="text-3xl font-bold">{{ stockQuote.daysRange }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-lg text-gray-400">52-Week Range</div> <div class="text-lg text-gray-400">52-Week Range</div>
<div class="text-3xl font-bold">{{ stockQuote.Week52Range }}</div> <div class="text-3xl font-bold">{{ stockQuote.week52Range }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-lg text-gray-400">Volume</div> <div class="text-lg text-gray-400">Volume</div>
<div class="text-3xl font-bold">{{ stockQuote.Volume }}</div> <div class="text-3xl font-bold">{{ stockQuote.volume }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-lg text-gray-400">Market Cap</div> <div class="text-lg text-gray-400">Market Cap</div>
<div class="text-3xl font-bold">{{ stockQuote.MarketCap }}</div> <div class="text-3xl font-bold">{{ stockQuote.marketCap }}</div>
</div> </div>
</section> </section>
</main> </main>

View File

@ -8,7 +8,7 @@ getStockQuate();
<main class="min-h-60vh flex flex-col items-center justify-start px-2 py-5 pt-500px"> <main class="min-h-60vh flex flex-col items-center justify-start px-2 py-5 pt-500px">
<!-- 价格卡片 --> <!-- 价格卡片 -->
<section class="w-full max-w-90vw flex flex-col items-center justify-center glass-card p-4 rounded-2xl shadow mb-5"> <section class="w-full max-w-90vw flex flex-col items-center justify-center glass-card p-4 rounded-2xl shadow mb-5">
<div class="text-4xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.[0].slice(0,4) }}</div> <div class="text-4xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.slice(0,4) }}</div>
<div class="mt-2 text-sm text-gray-500 font-semibold tracking-widest mb-0px">NASDAQ: <span class="text-black">MINM</span></div> <div class="mt-2 text-sm text-gray-500 font-semibold tracking-widest mb-0px">NASDAQ: <span class="text-black">MINM</span></div>
<div class="text-gray-500 text-60px">{{ formatted }}</div> <div class="text-gray-500 text-60px">{{ formatted }}</div>
</section> </section>
@ -16,30 +16,30 @@ getStockQuate();
<section class="w-full max-w-90vw grid grid-cols-2 gap-2"> <section class="w-full max-w-90vw grid grid-cols-2 gap-2">
<div class="info-card"> <div class="info-card">
<div class="text-xs text-gray-400">Open</div> <div class="text-xs text-gray-400">Open</div>
<div class="text-lg font-bold">{{ stockQuote.Open }}</div> <div class="text-lg font-bold">{{ stockQuote.open }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-xs text-gray-400">Change</div> <div class="text-xs text-gray-400">Change</div>
<div class="text-lg font-bold" <div class="text-lg font-bold"
:class="stockQuote.change?.[1]?.startsWith('-') ? 'text-red-500' : (stockQuote.change?.[1]?.startsWith('+') ? 'text-green-500' : '')"> :class="stockQuote.change?.includes('-') ? 'text-red-500' : (stockQuote.change?.includes('+') ? 'text-green-500' : '')">
{{ stockQuote.change?.join('') }}</div> {{ stockQuote.change }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-xs text-gray-400">Day's Range</div> <div class="text-xs text-gray-400">Day's Range</div>
<div class="text-lg font-bold">{{ stockQuote.DaysRange }}</div> <div class="text-lg font-bold">{{ stockQuote.daysRange }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-xs text-gray-400">52-Week Range</div> <div class="text-xs text-gray-400">52-Week Range</div>
<div class="text-lg font-bold">{{ stockQuote.Week52Range }}</div> <div class="text-lg font-bold">{{ stockQuote.week52Range }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-xs text-gray-400">Volume</div> <div class="text-xs text-gray-400">Volume</div>
<div class="text-lg font-bold">{{ stockQuote.Volume }}</div> <div class="text-lg font-bold">{{ stockQuote.volume }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-xs text-gray-400">Market Cap</div> <div class="text-xs text-gray-400">Market Cap</div>
<div class="text-lg font-bold">{{ stockQuote.MarketCap }}</div> <div class="text-lg font-bold">{{ stockQuote.marketCap }}</div>
</div> </div>
</section> </section>
</main> </main>

View File

@ -12,7 +12,7 @@ getStockQuate();
<main class="min-h-60vh flex flex-col items-center justify-start px-4 py-6 pt-500px"> <main class="min-h-60vh flex flex-col items-center justify-start px-4 py-6 pt-500px">
<!-- 价格卡片 --> <!-- 价格卡片 -->
<section class="w-full max-w-80vw flex flex-col items-center justify-center glass-card p-6 rounded-2xl shadow mb-6"> <section class="w-full max-w-80vw flex flex-col items-center justify-center glass-card p-6 rounded-2xl shadow mb-6">
<div class="text-5xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.[0].slice(0,4) }}</div> <div class="text-5xl font-extrabold text-#8A5AFB animate-bg-move select-none drop-shadow-lg">${{ stockQuote.change?.slice(0,4) }}</div>
<div class="mt-3 text-base text-gray-500 font-semibold tracking-widest mb-0px">NASDAQ: <span class="text-black">MINM</span></div> <div class="mt-3 text-base text-gray-500 font-semibold tracking-widest mb-0px">NASDAQ: <span class="text-black">MINM</span></div>
<div class="text-gray-500 text-70px">{{ formatted }}</div> <div class="text-gray-500 text-70px">{{ formatted }}</div>
</section> </section>
@ -20,29 +20,29 @@ getStockQuate();
<section class="w-full max-w-80vw grid grid-cols-3 gap-4"> <section class="w-full max-w-80vw grid grid-cols-3 gap-4">
<div class="info-card"> <div class="info-card">
<div class="text-sm text-gray-400">Open</div> <div class="text-sm text-gray-400">Open</div>
<div class="text-xl font-bold">{{ stockQuote.Open }}</div> <div class="text-xl font-bold">{{ stockQuote.open }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-sm text-gray-400">Change</div> <div class="text-sm text-gray-400">Change</div>
<div class="text-xl font-bold" <div class="text-xl font-bold"
:class="stockQuote.change?.[1]?.startsWith('-') ? 'text-red-500' : (stockQuote.change?.[1]?.startsWith('+') ? 'text-green-500' : '')"> :class="stockQuote.change?.includes('-') ? 'text-red-500' : (stockQuote.change?.includes('+') ? 'text-green-500' : '')">
{{ stockQuote.change?.join('') }}</div> {{ stockQuote.change }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-sm text-gray-400">Day's Range</div> <div class="text-sm text-gray-400">Day's Range</div>
<div class="text-xl font-bold">{{ stockQuote.DaysRange }}</div> <div class="text-xl font-bold">{{ stockQuote.daysRange }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-sm text-gray-400">52-Week Range</div> <div class="text-sm text-gray-400">52-Week Range</div>
<div class="text-xl font-bold">{{ stockQuote.Week52Range }}</div> <div class="text-xl font-bold">{{ stockQuote.week52Range }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-sm text-gray-400">Volume</div> <div class="text-sm text-gray-400">Volume</div>
<div class="text-xl font-bold">{{ stockQuote.Volume }}</div> <div class="text-xl font-bold">{{ stockQuote.volume }}</div>
</div> </div>
<div class="info-card"> <div class="info-card">
<div class="text-sm text-gray-400">Market Cap</div> <div class="text-sm text-gray-400">Market Cap</div>
<div class="text-xl font-bold">{{ stockQuote.MarketCap }}</div> <div class="text-xl font-bold">{{ stockQuote.marketCap }}</div>
</div> </div>
</section> </section>
</main> </main>