this is my button
Button(action: {
SearchSomeone()
},label: {
NavigationLink(destination: mySearchList()){
HStack(alignment: .center) {
Text("Search")
.font(.system(size: 17))
.fontWeight(.bold)
.foregroundColor(.white)
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.background(
RoundedRectangle(cornerRadius: 25)
.fill(Color("Color"))
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
}
and this button does the function and search together at the same time and since search would take time so I won't see the list, how can I do the function and then after 8 seconds I do the navigation after it ? thank you
According to the information, you'd like to switch to a new view after 8 seconds. This code should work for you.
import SwiftUI
struct ContentView: View {
//Variable to see if view should change or not
#State var viewIsShowing = false
var body: some View {
//Detecting if variable is false
if viewIsShowing == false {
//Showing a button that sets the variable to true
Button(action: {
//Makes it wait 8 seconds before making the variable true
DispatchQueue.main.asyncAfter(deadline: .now() + 8.0) {
viewIsShowing = true
}
}) {
//Button text
Text("Search")
.font(.system(size: 17))
.fontWeight(.bold)
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.background(
RoundedRectangle(cornerRadius: 25)
.fill(Color("Color"))
.shadow(color: .gray, radius: 2, x: 0, y: 2)
)
}
} else {
//If the variable equals false, go here
View2()
}
}
}
//Your other view you want to go to
struct View2: View {
var body: some View {
Text("abc")
}
}
Related
Environments:macOS Ventura Developer Beta 3Xcode 14.0 beta 3MacBook Pro (13 inch M1, 2020)
References: https://www.youtube.com/watch?v=aMes-DVVJg4https://github.com/TuenTuenna/SwiftUI_Alamofire_RandomUser_tutorial/tree/01_Alamofire
Hello. I'm building a simple ESD for macOS using SwiftUI.
I'm gonna get informations from json by my server, and show informations what it got from api like this:
GameESD_View
Game Informations, installation
but it doesn't show anything like this:
Not working
This is my code. You can see entire code here: https://github.com/bmplatina/BitmapMac
game.json (JSON file to decode and parse, watch http://developer.prodbybitmap.com/game.json):
{
"games": [
{
"gameIndex": 0,
"gameTitle": "The Humanity",
"gamePlatform": "Windows, macOS",
"gameEngine": "Unity",
"gameGenre": "어드벤처",
"gameDeveloper": "입학했더니 무한 팀플과 과제가 쌓여버린 건에 대하여",
"gamePublisher": "Bitmap Production",
"isEarlyAccess": true,
"gameReleasedDate": 20211210,
"gameWebsite": "http://prodbybitmap.com/wiki/The%20Humanity",
"gameImageURL": "http://www.prodbybitmap.com/w/images/9/99/TheHumanityPoster1.png",
"gameDescription": "Desc"
},
{
"gameIndex": 1,
"gameTitle": "OX",
"gamePlatform": "Windows",
"gameEngine": "Unreal Engine 5",
"gameGenre": "몰입형 VR 퍼즐 게임",
"gameDeveloper": "Team. Assertive",
"gamePublisher": "ENTER, Bitmap Production",
"isEarlyAccess": true,
"gameReleasedDate": 20220624,
"gameWebsite": "http://prodbybitmap.com/wiki/OX",
"gameImageURL": "http://www.prodbybitmap.com/w/images/f/f9/OX_CMYK.JPG",
"gameDescription": "Desc"
}
]
}
GameESD_View.swift:
import Foundation
import SwiftUI
import URLImage
struct GameESD_View: View {
#State private var searchField: String = ""
#ObservedObject var gameViewmodel = gameInfoViewmodel()
let gameInfoExam = exampleGameInfo()
let columnLayout = Array(repeating: GridItem(), count: 4)
var body: some View {
VStack {
ZStack {
Rectangle()
.fill(Color.init(hex: "4188F1"))
.frame(height: 42)
.shadow(radius: 4)
HStack {
Spacer()
Image("bitmapWebLogo")
.resizable()
.scaledToFit()
.frame(height: 30)
Spacer()
// if true {
// Text("Online")
// }
// else {
// Text("Offline Mode")
// }
TextField("Filter".localized(), text: $searchField)
}
}
ScrollView {
VStack(alignment: .leading) {
Text("Seoul Institute of the Arts Collection")
.font(.largeTitle)
.bold()
.padding([.top, .leading])
Text("collection.")
.padding(.leading)
Divider()
LazyVGrid(columns: columnLayout, alignment: .center, spacing: 2) {
// List(gameViewmodel.gameInfos) { aGameInfos in }
ForEach(0..<gameViewmodel.gameInfos.count, id: \.self) { aGameInfos in
GameButtons(gameViewmodel.gameInfos[aGameInfos])
}
}
Divider()
Text("Other Games")
.font(.largeTitle)
.bold()
.padding([.top, .leading])
Text("여러 창작자의 다양한 인디 컨텐츠.")
.padding(.leading)
}
}
.navigationTitle("Games".localized())
}
}
}
struct GameButtons: View {
#State private var showingPopover = false
var gameInfos: gameInfo
init(_ gameInfos: gameInfo) {
self.gameInfos = gameInfos
}
var body: some View {
VStack { }
Button {
showingPopover = true
} label: {
ZStack {
Image("unknownImage")
.resizable()
.scaledToFit()
.frame(width: 300)
URLImage(URL(string: gameInfos.gameImageURL)!) { image in
image
.resizable()
.scaledToFit()
.frame(width:300)
}
LinearGradient(gradient: Gradient(colors: [.clear, Color.black.opacity(0.5)]), startPoint: .top, endPoint: .bottom).frame(width: 300, height: 424)
VStack(alignment: .leading) {
Spacer()
Text(gameInfos.gameTitle)
.foregroundColor(.white)
.font(Font.largeTitle)
.bold()
Divider()
Text("Dev".localized() + ": " + gameInfos.gameDeveloper)
.foregroundColor(.white)
}
.frame(width:256)
.padding()
}
.cornerRadius(24)
.shadow(radius: 4)
.padding()
}
.buttonStyle(PlainButtonStyle())
.sheet(isPresented: $showingPopover) {
VStack(alignment: .leading) {
HStack {
VStack(alignment: .leading) {
Text("Bitmap Games")
.font(Font.largeTitle)
.bold()
Text("Bitmap Store".localized())
}
Spacer()
Button(action: { showingPopover = false }) {
Image(systemName: "x.circle")
.font(.title2)
}
.padding()
.background(Color.red)
.foregroundColor(.white)
.clipShape(Capsule())
.buttonStyle(PlainButtonStyle())
}
.padding()
GameDetailsView(gameIndex: gameInfos.gameIndex)
}
.frame(width: 1000, height: 600)
.fixedSize()
}
}
}
struct GameDetailsView: View {
#State private var installAlert = false
let gameInfo: exampleGameInfo = exampleGameInfo()
var gameIndex: Int
var body: some View {
Text("Temp")
}
}
#if DEBUG
struct ESD_Previews: PreviewProvider {
static var previews: some View {
GameESD_View()
// digitalArtsFestivalWebView()
}
}
#endif
FetchGameInformation.swift:
import Foundation
import Combine
import Alamofire
struct gameInfo: Codable, Identifiable {
var id = UUID()
var gameIndex: Int
var gameTitle: String
var gamePlatform: String
var gameEngine: String
var gameGenre: String
var gameDeveloper: String
var gamePublisher: String
var isEarlyAccess: Bool
var gameReleasedDate: Int
var gameWebsite: String
var gameImageURL: String
var gameDescription: String
var gameImage: URL {
get {
URL(string: gameImageURL)!
}
}
static func makeDummy() -> Self {
print(#fileID, #function, #line, "")
return gameInfo(gameIndex: 1, gameTitle: "OX", gamePlatform: "Windows", gameEngine: "Unreal Engine 5", gameGenre: "몰입형 VR 퍼즐 게임", gameDeveloper: "Team. Assertive", gamePublisher: "ENTER, Bitmap Production", isEarlyAccess: true, gameReleasedDate: 20220624, gameWebsite: "http://prodbybitmap.com/wiki/OX", gameImageURL: "http://www.prodbybitmap.com/w/images/f/f9/OX_CMYK.JPG", gameDescription: "This is Description")
}
}
struct gameResult: Codable, CustomStringConvertible {
var games: [gameInfo]
var description: String {
return "gameInfo.count: \(games.count)"
}
}
struct gamesResponse: Codable, CustomStringConvertible {
var games: [gameInfo]
var description: String {
return "games.count: \(games.count) / info : \(games[0].gameTitle)"
}
}
class gameInfoViewmodel: ObservableObject {
// MARK: Properties
var subscription = Set<AnyCancellable>()
#Published var gameInfos = [gameInfo]()
var url = "http://developer.prodbybitmap.com/game.json"
init() {
print(#fileID, #function, #line, "")
fetchGameInfo()
}
func fetchGameInfo() {
print(#fileID, #function, #line, "")
AF.request(url, method: .get)
.publishDecodable(type: gamesResponse.self)
.compactMap { $0.value }
.map { $0.games }
.sink(receiveCompletion: { completion in
print("Datastream Done")
}, receiveValue: { [weak self](receivedValue: [gameInfo]) in
guard let self = self else { return }
print("Data Value: \(receivedValue.description)")
self.gameInfos = receivedValue
}).store(in: &subscription)
}
}
I am trying to import a custom plugin into my chart.
Got this plugin from my previous question: Question
Its a plugin so that I can use Grace in my version of Chart.js.
The version of Chart.js I am using is V2.9.4.
I am using vue-chartjs in Nuxt!.
Couldn't really find an answer anywhere else.
This is how it looks now
This is how I want it to look
Thanks in advance. :)
I made a Component called 'BarChart' in my Components folder.
I made a normal .vue file in my pages directory. In the <template> tag I added my <Barchart/> component.
In that same .vue file I added a script in the <script> tag.
The plugin code is included in the codes below, I didn't include it anywhere yet.
Barchart.vue (Component)
<script>
import {Bar} from "vue-chartjs";
export default {
extends: Bar,
props: {
data: {
type: String,
default: () => {},
},
options: {
type: Object,
default: () => {},
},
},
computed: {
Chart() {
return['data', 'options'];
},
},
mounted() {
this.renderChart(this.data, this.options);
},
};
</script>
.vue file (Include component)
<div class="chart">
<BarChart :data="barChartData" :options="barChartOptions" :height="200"/>
</div>
.vue file (script tags)
<script>
import BarChart from "~/components/plugins/BarChart";
export default {
components: {
BarChart,
},
data() {
return {
barChartData: {
labels: ["Verzonden", "Ontvangen", "Geopend", "Kliks"],
datasets: [
{
data: [25, 20, 20, 18],
backgroundColor: [
'#7782FF',
'#403DD3',
'#FFB930',
'#00E437',
],
barThickness : 50,
},
],
},
barChartOptions: {
responsive: true,
legend: {
display: false,
},
scales: {
xAxes: [
{
gridLines: {
display: false,
},
ticks: {
fontColor: "black",
fontSize: 14,
},
},
],
yAxes: [
{
ticks: {
beginAtZero: true,
min: 0,
stepSize: 5,
fontColor: '#ABACB3',
},
gridLines: {
display: true,
borderDash: [4, 4],
color: '#EEEDFB',
drawBorder: false,
},
},
],
},
},
};
},
};
</script>
Plugin code (where do I put this and how do I make it work?)
const plugin = {
id: "customScale",
beforeLayout: (chart, options, c) => {
let max = Number.MIN_VALUE;
let min = Number.MAX_VALUE
let grace = options.grace || 0
chart.data.datasets.forEach((dataset) => {
max = Math.max(max, Math.max(...dataset.data));
min = Math.min(min, Math.min(...dataset.data))
})
if (typeof grace === 'string' && grace.includes('%')) {
grace = Number(grace.replace('%', '')) / 100
chart.options.scales.yAxes[0].ticks.suggestedMax = max + (max * grace)
chart.options.scales.yAxes[0].ticks.suggestedMin = min - (min * grace)
} else if (typeof grace === 'number') {
chart.options.scales.yAxes[0].ticks.suggestedMax = max + grace
chart.options.scales.yAxes[0].ticks.suggestedMin = min - grace
}
}
}
According to the vue-chartjs documentation you can do this in 2 ways.
If you want the plugin to be available for all your charts you can use the global registration like so:
import Chart from 'chart.js'
Chart.pluginService.register({
id: "customScale",
beforeLayout: (chart, options, c) => {
let max = Number.MIN_VALUE;
let min = Number.MAX_VALUE
let grace = options.grace || 0
chart.data.datasets.forEach((dataset) => {
max = Math.max(max, Math.max(...dataset.data));
min = Math.min(min, Math.min(...dataset.data))
})
if (typeof grace === 'string' && grace.includes('%')) {
grace = Number(grace.replace('%', '')) / 100
chart.options.scales.yAxes[0].ticks.suggestedMax = max + (max * grace)
chart.options.scales.yAxes[0].ticks.suggestedMin = min - (min * grace)
} else if (typeof grace === 'number') {
chart.options.scales.yAxes[0].ticks.suggestedMax = max + grace
chart.options.scales.yAxes[0].ticks.suggestedMin = min - grace
}
}
});
This way of importing and registering should work from anywhere in your app.
The second way is an inline plugin. This needs to be done in your BarChart.vue and goes like this:
mounted() {
this.addPlugin(
Chart.pluginService.register({
id: "customScale",
beforeLayout: (chart, options, c) => {
let max = Number.MIN_VALUE;
let min = Number.MAX_VALUE
let grace = options.grace || 0
chart.data.datasets.forEach((dataset) => {
max = Math.max(max, Math.max(...dataset.data));
min = Math.min(min, Math.min(...dataset.data))
})
if (typeof grace === 'string' && grace.includes('%')) {
grace = Number(grace.replace('%', '')) / 100
chart.options.scales.yAxes[0].ticks.suggestedMax = max + (max * grace)
chart.options.scales.yAxes[0].ticks.suggestedMin = min - (min * grace)
} else if (typeof grace === 'number') {
chart.options.scales.yAxes[0].ticks.suggestedMax = max + grace
chart.options.scales.yAxes[0].ticks.suggestedMin = min - grace
}
}
});
)
}
When i try to generate a word cloud using d3,js, the g element is rendered ouside of svg when i give data to it via api call. But when i supply data locally, it is working properly.The angular ts code is below:
import { Component, OnInit } from '#angular/core';
import * as D3 from 'd3';
import { PopulatTopicsService } from '../services/populat-topics.service';
declare let d3: any;
#Component({
selector: 'app-populat-topics',
templateUrl: './populat-topics.component.html',
styleUrls: ['./populat-topics.component.css']
})
export class PopulatTopicsComponent implements OnInit {
constructor(private popularService : PopulatTopicsService){}
//local data- works fine
// data = [
// {text: 'Bob',size:33,cuscolor: '#abaaea'},
// {text: 'Robin',size:12,cuscolor: '#abaaea'},
// {text: 'Anne',size:41,cuscolor: '#abaaea'},
// {text: 'Mark',size:16,cuscolor: '#abaaea'},
// {text: 'Joe',size:39,cuscolor: '#abaaea'}
// ];
network ="FB";
startDate ="01/04/2018";
endDate ="07/04/2018";
brandId ="720";
userId ="20615";
period ="LASTWEEK";
data =[];
wdata = "u gh h xfg fg gf";
ngOnInit() {
this.popularService.wordCloud(this.userId,this.startDate,this.endDate,this.brandId,this.period,this.network).subscribe(res =>
{
console.log(res);
this.data = res;
console.log(this.data['term']);
let cls = this;
// this.data = this.wdata.split(' ').map(function(d) {
// return {text: d, size: cls.getRandom()};
// });
this.setup();
this.buildSVG();
this.populate();
}
);
}
// data = [{'number':1},{'number':2}];
private svg; // SVG in which we will print our chart
private margin: { // Space between the svg borders and the actual chart graphic
top: number,
right: number,
bottom: number,
left: number
};
private width: number; // Component width
private height: number; // Component height
private fillScale; // D3 scale for text color
tempData = [];
private getRandom() {
let cls = this;
let size = 10 + Math.random() * 100;
if(size > 70 && this.tempData.length <= 10) {
this.tempData.push(size);
}
if(this.tempData.length > 10 && size > 14) {
return 12;
}
return size;
}
private setup() {
this.margin = {
top : 10,
right : 10,
bottom: 10,
left : 10
};
this.width = 1200;
this.height = 450;
let minFontSize: number = 18 ;
let maxFontSize: number = 96 ;
this.fillScale = D3.scaleOrdinal(D3.schemeCategory10);
// this.fillScale = ['#abaaea','#abaaea','#abaaea','#abaaea','#abaaea'];
}
private buildSVG() {
this.svg = D3.select("#wordCloud")
.append('svg')
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', 'translate(' + ~~(this.width / 2) + ',' + ~~(this.height / 2) + ')');
}
private populate() {
let fontFace: string = 'Roboto';
let fontWeight: string = 'normal';
let spiralType: string = 'archimedean';
d3.layout.cloud()
.size([this.width, this.height])
.words(this.data)
.padding(0)
.rotate(() => (~~(Math.random() * 2) * 0))
.font(fontFace)
.fontWeight(fontWeight)
.fontSize(d => (d.size))
.spiral(spiralType)
.on('end', () => {
this.drawWordCloud(this.data);
})
.start();
}
private drawWordCloud(words) {
this.svg
.selectAll('text')
.data(words)
.enter()
.append('text')
.style('font-size', d => 20 + 'px')
.style('fill', this.fillScale)
.attr('text-anchor', 'middle')
.attr('transform', d => 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')')
.attr('class', 'word-cloud')
.text(d => {
return d.term;
});
}
}
MY HTML IS GIVEN BELOW:
<div class ="tag_cloud-wrap" id ="wordCloud" ></div>
MY CSS:
.tag_cloud-wrap {
clear: both;
margin: 40px;
text-align: center;
}
JSON DATA obtained throug api call is:
0
:
{term: "#NYIAS", score: "-Infinity", normalizedScore: 0, totalTermFreq: 2, totalDocFreq: 2, …}
1
:
{term: "TORQUE", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
2
:
{term: "RS", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
3
:
{term: "SPORTBACK", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
4
:
{term: "COLOR", score: 0, normalizedScore: 0, totalTermFreq: 1, totalDocFreq: 1, …}
I am assigning term as text to word cloud.
Thanks in advance.
Class Variable Name: addPointY
"addPointY" Using Function:
setInterval(function () {
var y = Math.round(Math.random() * 100);
series.addPoint(this.addPointY, true, true);
}, 3000);
I have to find a way to use it.
This is a customer requirement and has not been resolved.
Please tell me another way.
The class variable must be used in any of its methods.
But I could not get the class variable.
Do not you have a smart developer who solved the same problem?
#Injectable()
export class HighChartService implements ChartService {
private addPointY: number = 0;
shiftAddPoint(data: number) {
this.addPointY = data;
console.log(this.addPointY);
}
/**
* #see DynamicChart start function
* #param obj chart Object
* #param title Top Title
* #param type ChartType
* #param yAxisTitle Left Title
* #param series Chart data
* #author jskang
* #since 2017/10/12
*/
dynamicInitOptions(title: string, type: string, yAxisTitle: string, series: Object[]) {
if (!type) { type = "line"; }
let obj = new Chart({
chart: {
type: type,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var y = Math.round(Math.random() * 100);
series.addPoint(this.addPointY, true, true);
}, 3000);
}
}
},
title: { text: title },
xAxis: {
categories: [0,1,2,3,4,5,6],
labels: {
formatter: function () {
let xAxis = "";
if(this.value % 7 == 0){ xAxis = "일"; }
else if(this.value % 7 == 1){ xAxis = "월"; }
else if(this.value % 7 == 2){ xAxis = "화"; }
else if(this.value % 7 == 3){ xAxis = "수"; }
else if(this.value % 7 == 4){ xAxis = "목"; }
else if(this.value % 7 == 5){ xAxis = "금"; }
else if(this.value % 7 == 6){ xAxis = "토"; }
return xAxis;
}
}
},
yAxis: {
title: {
text: yAxisTitle
},
labels: {
formatter: function () {
return this.value;
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
series: series
});
return obj;
}
}
The this inside your callback function for setInterval does not point to the current class instance because when you use function () {} syntax it creates its own binding for this based on how it is called.
To fix this use arrow functions which preserves the context and you can access your class properties inside the callback:
load: () => { // Notice arrow function here
// set up the updating of the chart each second
var series = this.series[0];
setInterval(() => { // Notice arrow function here
var y = Math.round(Math.random() * 100);
series.addPoint(this.addPointY, true, true);
}, 3000);
}
Another way you can solve this is by using the that pattern where you capture your this where it points to your class instance and use it wherever you need to refer to your instance:
dynamicInitOptions(title: string, type: string, yAxisTitle: string, series: Object[]) {
if (!type) { type = "line"; }
let that = this; // Capture `this` here
let obj = new Chart({
chart: {
type: type,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var y = Math.round(Math.random() * 100);
series.addPoint(that.addPointY, true, true); // Use `that` instead of `this here
}, 3000);
}
}
}
// ...
});
}
I have a simple line graph with data in the format:
[
{
label: "lebel1",
x: 0,
y: 128
},
{
label: "lebel1",
x: 1,
y: 128
},
....
{
label: "lebel2",
x: 25,
y: 128
},
....
{
label: "lebel8",
x: 285,
y: 128
},
....
}
and I pass this into my nvd3 object:
nv.addGraph(function()
{
var chart = nv.models.lineChart();
chart.xAxis
.axisLabel("My X-Axis")
.ticks(36)
.tickFormat(function(d) { return d; });
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(d3.format('.02f'));
d3.select('div svg')
.datum(myData)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(function() { d3.select(gridSvgId).call(chart) });
return chart;
});
How can I have my x-axis ticks to show:
* eight labels: label1 - label8
Rather than have the grids broken up into a variable number of lines?
Try something like this
chart.xAxis.tickValues(['Label 1','Label 2','Label 3','Label 4','Label 5','Label 6','Label 7','Label 8']);
or if you want to get it from the dataset, you could try something like this,
chart.xAxis.tickValues(function(d) {
// do all you stuff and return an array
var dataset = ['Build Array from data'];
return dataset;
};)
Hope it helps