Repository: VIkill33/SwiftUI-ContributionChart
Branch: main
Commit: 1a5456abe211
Files: 18
Total size: 40.0 KB
Directory structure:
gitextract_at9suabs/
├── .gitignore
├── .swiftpm/
│ └── xcode/
│ └── package.xcworkspace/
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── DemoApp/
│ └── DemoApp/
│ ├── DemoApp/
│ │ ├── Assets.xcassets/
│ │ │ ├── AccentColor.colorset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── ContentView.swift
│ │ ├── DemoAppApp.swift
│ │ └── Preview Content/
│ │ └── Preview Assets.xcassets/
│ │ └── Contents.json
│ ├── DemoApp.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── DemoAppTests/
│ │ └── DemoAppTests.swift
│ └── DemoAppUITests/
│ ├── DemoAppUITests.swift
│ └── DemoAppUITestsLaunchTests.swift
├── Package.swift
├── README.md
└── Sources/
└── ContributionChart/
├── ContributionChartTest.swift
└── ContributionChartView.swift
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
================================================
FILE: .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: DemoApp/DemoApp/DemoApp/Assets.xcassets/AccentColor.colorset/Contents.json
================================================
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: DemoApp/DemoApp/DemoApp/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: DemoApp/DemoApp/DemoApp/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: DemoApp/DemoApp/DemoApp/ContentView.swift
================================================
//
// ContentView.swift
// DemoApp
//
// Created by Qu Tian on 2024/7/31.
//
import SwiftUI
import ContributionChart
struct ContentView: View {
@State private var data = [0.87, 0.17, 0.6, 0.21, 0.88, 0.41, 0.37, 0.39, 0.34, 0.91, 0.45, 0.51, 0.1, 0.97, 0.32, 0.72, 0.15, 0.2, 0.87, 0.86, 0.35, 0.12, 0.77, 0.56]
var body: some View {
RecordBlock {
ContributionChartView(data: data, rows: 3, columns: 8, targetValue: 1.0)
}
.frame(width: 210, height: 95)
.padding()
}
}
fileprivate struct RecordBlock<Content:View>: View {
@ViewBuilder var content:Content
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 16)
.fill(Color.white)
.shadow(color: Color.black.opacity(0.3), radius: 16.0, y: 16.0)
content
}
}
}
#Preview {
ContentView()
}
================================================
FILE: DemoApp/DemoApp/DemoApp/DemoAppApp.swift
================================================
//
// DemoAppApp.swift
// DemoApp
//
// Created by Qu Tian on 2024/7/31.
//
import SwiftUI
@main
struct DemoAppApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
================================================
FILE: DemoApp/DemoApp/DemoApp/Preview Content/Preview Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: DemoApp/DemoApp/DemoApp.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
C00592122C59D22F00FAE9E2 /* DemoAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00592112C59D22F00FAE9E2 /* DemoAppApp.swift */; };
C00592142C59D22F00FAE9E2 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00592132C59D22F00FAE9E2 /* ContentView.swift */; };
C00592162C59D23000FAE9E2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C00592152C59D23000FAE9E2 /* Assets.xcassets */; };
C00592192C59D23000FAE9E2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C00592182C59D23000FAE9E2 /* Preview Assets.xcassets */; };
C00592232C59D23100FAE9E2 /* DemoAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00592222C59D23100FAE9E2 /* DemoAppTests.swift */; };
C005922D2C59D23100FAE9E2 /* DemoAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C005922C2C59D23100FAE9E2 /* DemoAppUITests.swift */; };
C005922F2C59D23100FAE9E2 /* DemoAppUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C005922E2C59D23100FAE9E2 /* DemoAppUITestsLaunchTests.swift */; };
C005923E2C59D5BC00FAE9E2 /* ContributionChart in Frameworks */ = {isa = PBXBuildFile; productRef = C005923D2C59D5BC00FAE9E2 /* ContributionChart */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
C005921F2C59D23000FAE9E2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C00592062C59D22F00FAE9E2 /* Project object */;
proxyType = 1;
remoteGlobalIDString = C005920D2C59D22F00FAE9E2;
remoteInfo = DemoApp;
};
C00592292C59D23100FAE9E2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C00592062C59D22F00FAE9E2 /* Project object */;
proxyType = 1;
remoteGlobalIDString = C005920D2C59D22F00FAE9E2;
remoteInfo = DemoApp;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
C005920E2C59D22F00FAE9E2 /* DemoApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
C00592112C59D22F00FAE9E2 /* DemoAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppApp.swift; sourceTree = "<group>"; };
C00592132C59D22F00FAE9E2 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
C00592152C59D23000FAE9E2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C00592182C59D23000FAE9E2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
C005921E2C59D23000FAE9E2 /* DemoAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C00592222C59D23100FAE9E2 /* DemoAppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppTests.swift; sourceTree = "<group>"; };
C00592282C59D23100FAE9E2 /* DemoAppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C005922C2C59D23100FAE9E2 /* DemoAppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppUITests.swift; sourceTree = "<group>"; };
C005922E2C59D23100FAE9E2 /* DemoAppUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppUITestsLaunchTests.swift; sourceTree = "<group>"; };
C005923C2C59D57200FAE9E2 /* SwiftUI-ContributionChart */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "SwiftUI-ContributionChart"; path = ../..; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C005920B2C59D22F00FAE9E2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C005923E2C59D5BC00FAE9E2 /* ContributionChart in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C005921B2C59D23000FAE9E2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
C00592252C59D23100FAE9E2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C00592052C59D22F00FAE9E2 = {
isa = PBXGroup;
children = (
C00592102C59D22F00FAE9E2 /* DemoApp */,
C00592212C59D23100FAE9E2 /* DemoAppTests */,
C005922B2C59D23100FAE9E2 /* DemoAppUITests */,
C005920F2C59D22F00FAE9E2 /* Products */,
C005923B2C59D57200FAE9E2 /* Frameworks */,
);
sourceTree = "<group>";
};
C005920F2C59D22F00FAE9E2 /* Products */ = {
isa = PBXGroup;
children = (
C005920E2C59D22F00FAE9E2 /* DemoApp.app */,
C005921E2C59D23000FAE9E2 /* DemoAppTests.xctest */,
C00592282C59D23100FAE9E2 /* DemoAppUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
C00592102C59D22F00FAE9E2 /* DemoApp */ = {
isa = PBXGroup;
children = (
C00592112C59D22F00FAE9E2 /* DemoAppApp.swift */,
C00592132C59D22F00FAE9E2 /* ContentView.swift */,
C00592152C59D23000FAE9E2 /* Assets.xcassets */,
C00592172C59D23000FAE9E2 /* Preview Content */,
);
path = DemoApp;
sourceTree = "<group>";
};
C00592172C59D23000FAE9E2 /* Preview Content */ = {
isa = PBXGroup;
children = (
C00592182C59D23000FAE9E2 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
C00592212C59D23100FAE9E2 /* DemoAppTests */ = {
isa = PBXGroup;
children = (
C00592222C59D23100FAE9E2 /* DemoAppTests.swift */,
);
path = DemoAppTests;
sourceTree = "<group>";
};
C005922B2C59D23100FAE9E2 /* DemoAppUITests */ = {
isa = PBXGroup;
children = (
C005922C2C59D23100FAE9E2 /* DemoAppUITests.swift */,
C005922E2C59D23100FAE9E2 /* DemoAppUITestsLaunchTests.swift */,
);
path = DemoAppUITests;
sourceTree = "<group>";
};
C005923B2C59D57200FAE9E2 /* Frameworks */ = {
isa = PBXGroup;
children = (
C005923C2C59D57200FAE9E2 /* SwiftUI-ContributionChart */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C005920D2C59D22F00FAE9E2 /* DemoApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = C00592322C59D23100FAE9E2 /* Build configuration list for PBXNativeTarget "DemoApp" */;
buildPhases = (
C005920A2C59D22F00FAE9E2 /* Sources */,
C005920B2C59D22F00FAE9E2 /* Frameworks */,
C005920C2C59D22F00FAE9E2 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = DemoApp;
packageProductDependencies = (
C005923D2C59D5BC00FAE9E2 /* ContributionChart */,
);
productName = DemoApp;
productReference = C005920E2C59D22F00FAE9E2 /* DemoApp.app */;
productType = "com.apple.product-type.application";
};
C005921D2C59D23000FAE9E2 /* DemoAppTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = C00592352C59D23100FAE9E2 /* Build configuration list for PBXNativeTarget "DemoAppTests" */;
buildPhases = (
C005921A2C59D23000FAE9E2 /* Sources */,
C005921B2C59D23000FAE9E2 /* Frameworks */,
C005921C2C59D23000FAE9E2 /* Resources */,
);
buildRules = (
);
dependencies = (
C00592202C59D23000FAE9E2 /* PBXTargetDependency */,
);
name = DemoAppTests;
productName = DemoAppTests;
productReference = C005921E2C59D23000FAE9E2 /* DemoAppTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
C00592272C59D23100FAE9E2 /* DemoAppUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = C00592382C59D23100FAE9E2 /* Build configuration list for PBXNativeTarget "DemoAppUITests" */;
buildPhases = (
C00592242C59D23100FAE9E2 /* Sources */,
C00592252C59D23100FAE9E2 /* Frameworks */,
C00592262C59D23100FAE9E2 /* Resources */,
);
buildRules = (
);
dependencies = (
C005922A2C59D23100FAE9E2 /* PBXTargetDependency */,
);
name = DemoAppUITests;
productName = DemoAppUITests;
productReference = C00592282C59D23100FAE9E2 /* DemoAppUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C00592062C59D22F00FAE9E2 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1540;
TargetAttributes = {
C005920D2C59D22F00FAE9E2 = {
CreatedOnToolsVersion = 15.4;
};
C005921D2C59D23000FAE9E2 = {
CreatedOnToolsVersion = 15.4;
TestTargetID = C005920D2C59D22F00FAE9E2;
};
C00592272C59D23100FAE9E2 = {
CreatedOnToolsVersion = 15.4;
TestTargetID = C005920D2C59D22F00FAE9E2;
};
};
};
buildConfigurationList = C00592092C59D22F00FAE9E2 /* Build configuration list for PBXProject "DemoApp" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = C00592052C59D22F00FAE9E2;
productRefGroup = C005920F2C59D22F00FAE9E2 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C005920D2C59D22F00FAE9E2 /* DemoApp */,
C005921D2C59D23000FAE9E2 /* DemoAppTests */,
C00592272C59D23100FAE9E2 /* DemoAppUITests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C005920C2C59D22F00FAE9E2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C00592192C59D23000FAE9E2 /* Preview Assets.xcassets in Resources */,
C00592162C59D23000FAE9E2 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C005921C2C59D23000FAE9E2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
C00592262C59D23100FAE9E2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C005920A2C59D22F00FAE9E2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C00592142C59D22F00FAE9E2 /* ContentView.swift in Sources */,
C00592122C59D22F00FAE9E2 /* DemoAppApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C005921A2C59D23000FAE9E2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C00592232C59D23100FAE9E2 /* DemoAppTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C00592242C59D23100FAE9E2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C005922D2C59D23100FAE9E2 /* DemoAppUITests.swift in Sources */,
C005922F2C59D23100FAE9E2 /* DemoAppUITestsLaunchTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
C00592202C59D23000FAE9E2 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C005920D2C59D22F00FAE9E2 /* DemoApp */;
targetProxy = C005921F2C59D23000FAE9E2 /* PBXContainerItemProxy */;
};
C005922A2C59D23100FAE9E2 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C005920D2C59D22F00FAE9E2 /* DemoApp */;
targetProxy = C00592292C59D23100FAE9E2 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
C00592302C59D23100FAE9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
C00592312C59D23100FAE9E2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
C00592332C59D23100FAE9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"DemoApp/Preview Content\"";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.qutian.DemoApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
C00592342C59D23100FAE9E2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"DemoApp/Preview Content\"";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.qutian.DemoApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
C00592362C59D23100FAE9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.qutian.DemoAppTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DemoApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/DemoApp";
};
name = Debug;
};
C00592372C59D23100FAE9E2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.qutian.DemoAppTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DemoApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/DemoApp";
};
name = Release;
};
C00592392C59D23100FAE9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.qutian.DemoAppUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = DemoApp;
};
name = Debug;
};
C005923A2C59D23100FAE9E2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.qutian.DemoAppUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = DemoApp;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C00592092C59D22F00FAE9E2 /* Build configuration list for PBXProject "DemoApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C00592302C59D23100FAE9E2 /* Debug */,
C00592312C59D23100FAE9E2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C00592322C59D23100FAE9E2 /* Build configuration list for PBXNativeTarget "DemoApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C00592332C59D23100FAE9E2 /* Debug */,
C00592342C59D23100FAE9E2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C00592352C59D23100FAE9E2 /* Build configuration list for PBXNativeTarget "DemoAppTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C00592362C59D23100FAE9E2 /* Debug */,
C00592372C59D23100FAE9E2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C00592382C59D23100FAE9E2 /* Build configuration list for PBXNativeTarget "DemoAppUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C00592392C59D23100FAE9E2 /* Debug */,
C005923A2C59D23100FAE9E2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
C005923D2C59D5BC00FAE9E2 /* ContributionChart */ = {
isa = XCSwiftPackageProductDependency;
productName = ContributionChart;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = C00592062C59D22F00FAE9E2 /* Project object */;
}
================================================
FILE: DemoApp/DemoApp/DemoApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: DemoApp/DemoApp/DemoApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: DemoApp/DemoApp/DemoAppTests/DemoAppTests.swift
================================================
//
// DemoAppTests.swift
// DemoAppTests
//
// Created by Qu Tian on 2024/7/31.
//
import XCTest
@testable import DemoApp
final class DemoAppTests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}
func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
================================================
FILE: DemoApp/DemoApp/DemoAppUITests/DemoAppUITests.swift
================================================
//
// DemoAppUITests.swift
// DemoAppUITests
//
// Created by Qu Tian on 2024/7/31.
//
import XCTest
final class DemoAppUITests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// UI tests must launch the application that they test.
let app = XCUIApplication()
app.launch()
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testLaunchPerformance() throws {
if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
// This measures how long it takes to launch your application.
measure(metrics: [XCTApplicationLaunchMetric()]) {
XCUIApplication().launch()
}
}
}
}
================================================
FILE: DemoApp/DemoApp/DemoAppUITests/DemoAppUITestsLaunchTests.swift
================================================
//
// DemoAppUITestsLaunchTests.swift
// DemoAppUITests
//
// Created by Qu Tian on 2024/7/31.
//
import XCTest
final class DemoAppUITestsLaunchTests: XCTestCase {
override class var runsForEachTargetApplicationUIConfiguration: Bool {
true
}
override func setUpWithError() throws {
continueAfterFailure = false
}
func testLaunch() throws {
let app = XCUIApplication()
app.launch()
// Insert steps here to perform after app launch but before taking a screenshot,
// such as logging into a test account or navigating somewhere in the app
let attachment = XCTAttachment(screenshot: app.screenshot())
attachment.name = "Launch Screen"
attachment.lifetime = .keepAlways
add(attachment)
}
}
================================================
FILE: Package.swift
================================================
// swift-tools-version: 5.6
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "ContributionChart",
platforms: [
.iOS(.v13), .macOS(.v10_15), .tvOS(.v13), .watchOS(.v6)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "ContributionChart",
targets: ["ContributionChart"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "ContributionChart",
dependencies: [])
]
)
================================================
FILE: README.md
================================================
# ContributionChart
A contribution chart (aka. heatmap, GitHub-like) library for iOS, macOS, and watchOS.
100% written in SwiftUI.
<img src="https://user-images.githubusercontent.com/78488529/183985880-614250a8-7d9d-4bfe-96b3-08d95d90d6e1.png" width="120" height="150"><img src="https://user-images.githubusercontent.com/78488529/183985888-6724caf4-4f77-4467-9d0b-4e202159ef89.png" width="120" height="150"><img src="https://user-images.githubusercontent.com/78488529/183985895-22ae2cd3-15d7-404f-acd8-2ecee6c74ae3.png" width="120" height="150">
- [It Supports](#it-supports)
* [Custom Block Number](#custom-block-number)
* [Custom Block Color](#custom-block-color)
* [Dark mode](#dark-mode)
- [Installation](#installation)
- [Usage](#usage)
- [Demo Code](#demo-code)
Updates
- 7/31/24 Support input array with any length and add a demo app inside.
# It Supports
## Custom Block Number
Of course, you can also custom the **size** of blocks and **spacing** between blocks.
<img src="https://user-images.githubusercontent.com/78488529/183973081-d743c369-8f61-4c72-a211-b51183bf28f2.JPEG" width="255" height="482"> <img src="https://user-images.githubusercontent.com/78488529/183973087-22c09508-c9d1-4a77-b87c-dfbd4a4ded63.JPEG" width="255" height="482">
## Custom Block Color
Here are examples using **system colors** as below, and you can custom any color you like.
<img src="https://user-images.githubusercontent.com/78488529/183974533-5c3ae4ae-3530-458e-999a-f87a3924b185.JPEG" width="255" height="482"> <img src="https://user-images.githubusercontent.com/78488529/183974538-4e14da58-bb4e-4c6a-9c2b-61aab28d3aef.JPEG" width="255" height="482"> <img src="https://user-images.githubusercontent.com/78488529/183974546-04dd557d-5a59-42fc-bbde-4fbb0b9566ab.JPEG" width="255" height="482">
## Dark mode
Adjust to dark mode color automatically.
<img src="https://user-images.githubusercontent.com/78488529/183975854-60e806c4-5aa8-4adf-8e7c-840fe75c598c.JPEG" width="255" height="482">
# Installation
Require iOS 13, macOS 10.15, watchOS 6 and Xcode 11 or higher.
In Xcode go to `File -> Swift Packages -> Add Package Dependency`
and paste in the repo's url:
`https://github.com/VIkill33/SwiftUI-ContributionChart.git`
Or you can download the code of this repo, then `Add Local...` in Xcode, and open the folder of the repo.
# Usage
- Import this package after you installed by `import ContributionChart`
- Use the chart like
```swift
ContributionChartView(data: yourData,
rows: yourRows,
columns: yourColumns,
targetValue: yourTargetValue,
blockColor: .green)
```
yourData is (**a double array**), and the targetValue is recommanded to set to the max value of the array.
The color of a block will appear as exactly the color as parameter `blockColor` when its value is equal to `targetValue`, and appears light gray when is equal to zero.
The top-Leading block represents the first value in array, while the bottom-trailing represents the last. And the order follows as below:
<img src="https://user-images.githubusercontent.com/78488529/183982320-7c8b9d00-7bfb-4701-b2a6-b371cb9996c2.JPEG" width="255" height="482">
# Demo Code
```swift
import SwiftUI
import ContributionChart
struct ContentView: View {
var data: [Double]
let rows = 7
let columns = 14
init() {
data = [0.3, 0.4, 0.4, 0.4, 0.1, 0.5, 0.0, 0.1, 0.0, 0.2, 0.2, 0.2, 0.0, 0.2, 0.2, 0.5, 0.4, 0.2, 0.4, 0.5, 0.2, 0.2, 0.4, 0.3, 0.3, 0.2, 0.4, 0.0, 0.0, 0.5, 0.4, 0.3, 0.5, 0.3, 0.0, 0.0, 0.1, 0.0, 0.2, 0.3, 0.0, 0.0, 0.0, 0.5, 0.3, 0.3, 0.0, 0.3, 0.0, 0.5, 0.3, 0.3, 0.4, 0.5, 0.5, 0.3, 0.4, 0.1, 0.4, 0.2, 0.5, 0.1, 0.4, 0.2, 0.5, 0.4, 0.3, 0.5, 0.0, 0.4, 0.3, 0.2, 0.1, 0.5, 0.2, 0.0, 0.2, 0.5, 0.5, 0.3, 0.4, 0.0, 0.3, 0.3, 0.1, 0.2, 0.5, 0.2, 0.1, 0.4, 0.4, 0.0, 0.5, 0.3, 0.3, 0.5, 0.0, 0.2]
}
var body: some View {
ContributionChartView(data: data,
rows: rows,
columns: columns,
targetValue: 0.5,
blockColor: .green)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
```
================================================
FILE: Sources/ContributionChart/ContributionChartTest.swift
================================================
//
// SwiftUIView.swift
//
//
// Created by Vikill Blacks on 2023/2/2.
//
import SwiftUI
struct SwiftUIView: View {
var body: some View {
ContributionChartView(data: [0,3,4,2,4,2,5,1,3], rows: 3, columns: 3, targetValue: 5, RectangleRadius: 2.0)
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
//.preferredColorScheme(.dark)
}
}
================================================
FILE: Sources/ContributionChart/ContributionChartView.swift
================================================
import SwiftUI
@available(iOS 13, macOS 10.15, watchOS 6, *)
public struct ContributionChartView: View {
var data: [Double]
var rows: Int
var columns: Int
var targetValue: Double
var blockColor: Color = Color.green
var blockBackgroundColor: Color = Color.background
var heatMapRectangleWidth: Double = 20.0
var heatMapRectangleSpacing: Double = 2.0
var heatMapRectangleRadius: Double = 5.0
public init(data: [Double], rows: Int, columns: Int, targetValue: Double, blockColor: Color = Color.green, blockBackgroundColor: Color, RectangleWidth: Double = 20.0, RectangleSpacing: Double = 2.0, RectangleRadius: Double = 5.0){
self.data = data
self.rows = rows
self.columns = columns
self.targetValue = targetValue
self.blockColor = blockColor
self.blockBackgroundColor = blockBackgroundColor
self.heatMapRectangleWidth = RectangleWidth
self.heatMapRectangleSpacing = RectangleSpacing
self.heatMapRectangleRadius = RectangleRadius
}
public init(data: [Double], rows: Int, columns: Int, targetValue: Double, blockColor: Color = Color.green, RectangleWidth: Double = 20.0, RectangleSpacing: Double = 2.0, RectangleRadius: Double = 5.0){
self.data = data
self.rows = rows
self.columns = columns
if data.count < rows * columns {
let elementsToAdd = Array(repeating: 0.0, count: rows * columns - data.count)
self.data.append(contentsOf: elementsToAdd)
}
self.targetValue = targetValue
self.blockColor = blockColor
self.heatMapRectangleWidth = RectangleWidth
self.heatMapRectangleSpacing = RectangleSpacing
self.heatMapRectangleRadius = RectangleRadius
}
public var body: some View {
VStack {
// Chart
GeometryReader { geo in
ZStack {
HStack(spacing: heatMapRectangleSpacing) {
ForEach(0..<columns, id: \.self) { i in
let start = i * rows
let end = (i + 1) * rows
let splitedData = Array(data[start..<end])
ContributionChartRowView(rowData: splitedData,
rows: rows,
targetValue: targetValue,
blockColor: blockColor,
blockBackgroundColor: blockBackgroundColor,
heatMapRectangleWidth: heatMapRectangleWidth,
heatMapRectangleSpacing: heatMapRectangleSpacing,
heatMapRectangleRadius: heatMapRectangleRadius
)
}
}
}
.frame(width: geo.size.width, height: geo.size.height, alignment: .center)
.onAppear {
print(geo.size.width, geo.size.height)
}
}
}
.padding()
}
}
struct ContributionChartRowView: View {
@Environment(\.colorScheme) var colorScheme
var rowData: [Double]
var rows: Int
var targetValue: Double
var blockColor: Color
var blockBackgroundColor: Color
var heatMapRectangleWidth: Double
var heatMapRectangleSpacing: Double
var heatMapRectangleRadius: Double
var body: some View {
VStack(spacing: heatMapRectangleSpacing) {
ForEach(0..<rows, id: \.self) { index in
ZStack {
RoundedRectangle(cornerRadius: heatMapRectangleRadius)
.frame(width: heatMapRectangleWidth, height: heatMapRectangleWidth, alignment: .center
)
.foregroundColor(blockBackgroundColor)
RoundedRectangle(cornerRadius: heatMapRectangleRadius)
.frame(width: heatMapRectangleWidth, height: heatMapRectangleWidth, alignment: .center)
.foregroundColor(blockColor
.opacity(opacityRatio(index: index)))
}
}
}
.onAppear() {
print(rowData)
}
}
func opacityRatio(index: Int) -> Double {
let opacityRatio: Double = Double(rowData[index]) / Double(targetValue)
return opacityRatio > 1.0 ? 1.0 : opacityRatio
}
}
extension Color {
init(hexString: String) {
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int = UInt64()
Scanner(string: hex).scanHexInt64(&int)
let r, g, b: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(r, g, b) = (int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(r, g, b) = (0, 0, 0)
}
self.init(red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255)
}
#if os(macOS)
static let background = Color(NSColor.windowBackgroundColor)
static let secondaryBackground = Color(NSColor.underPageBackgroundColor)
static let tertiaryBackground = Color(NSColor.controlBackgroundColor)
#endif
#if os(iOS)
static let background = Color(UIColor.systemBackground)
static let secondaryBackground = Color(UIColor.secondarySystemBackground)
static let tertiaryBackground = Color(UIColor.tertiarySystemBackground)
#endif
#if os(watchOS)
static let background = Color.black
#endif
}
gitextract_at9suabs/
├── .gitignore
├── .swiftpm/
│ └── xcode/
│ └── package.xcworkspace/
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── DemoApp/
│ └── DemoApp/
│ ├── DemoApp/
│ │ ├── Assets.xcassets/
│ │ │ ├── AccentColor.colorset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── ContentView.swift
│ │ ├── DemoAppApp.swift
│ │ └── Preview Content/
│ │ └── Preview Assets.xcassets/
│ │ └── Contents.json
│ ├── DemoApp.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── DemoAppTests/
│ │ └── DemoAppTests.swift
│ └── DemoAppUITests/
│ ├── DemoAppUITests.swift
│ └── DemoAppUITestsLaunchTests.swift
├── Package.swift
├── README.md
└── Sources/
└── ContributionChart/
├── ContributionChartTest.swift
└── ContributionChartView.swift
Condensed preview — 18 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (46K chars).
[
{
"path": ".gitignore",
"chars": 165,
"preview": ".DS_Store\n/.build\n/Packages\n/*.xcodeproj\nxcuserdata/\nDerivedData/\n.swiftpm/config/registries.json\n.swiftpm/xcode/package"
},
{
"path": ".swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "DemoApp/DemoApp/DemoApp/Assets.xcassets/AccentColor.colorset/Contents.json",
"chars": 123,
"preview": "{\n \"colors\" : [\n {\n \"idiom\" : \"universal\"\n }\n ],\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }"
},
{
"path": "DemoApp/DemoApp/DemoApp/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 177,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"platform\" : \"ios\",\n \"size\" : \"1024x1024\"\n }\n ],\n \"i"
},
{
"path": "DemoApp/DemoApp/DemoApp/Assets.xcassets/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "DemoApp/DemoApp/DemoApp/ContentView.swift",
"chars": 904,
"preview": "//\n// ContentView.swift\n// DemoApp\n//\n// Created by Qu Tian on 2024/7/31.\n//\n\nimport SwiftUI\nimport ContributionChart"
},
{
"path": "DemoApp/DemoApp/DemoApp/DemoAppApp.swift",
"chars": 220,
"preview": "//\n// DemoAppApp.swift\n// DemoApp\n//\n// Created by Qu Tian on 2024/7/31.\n//\n\nimport SwiftUI\n\n@main\nstruct DemoAppApp:"
},
{
"path": "DemoApp/DemoApp/DemoApp/Preview Content/Preview Assets.xcassets/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "DemoApp/DemoApp/DemoApp.xcodeproj/project.pbxproj",
"chars": 23491,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 56;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "DemoApp/DemoApp/DemoApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "DemoApp/DemoApp/DemoApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "DemoApp/DemoApp/DemoAppTests/DemoAppTests.swift",
"chars": 1217,
"preview": "//\n// DemoAppTests.swift\n// DemoAppTests\n//\n// Created by Qu Tian on 2024/7/31.\n//\n\nimport XCTest\n@testable import De"
},
{
"path": "DemoApp/DemoApp/DemoAppUITests/DemoAppUITests.swift",
"chars": 1369,
"preview": "//\n// DemoAppUITests.swift\n// DemoAppUITests\n//\n// Created by Qu Tian on 2024/7/31.\n//\n\nimport XCTest\n\nfinal class De"
},
{
"path": "DemoApp/DemoApp/DemoAppUITests/DemoAppUITestsLaunchTests.swift",
"chars": 799,
"preview": "//\n// DemoAppUITestsLaunchTests.swift\n// DemoAppUITests\n//\n// Created by Qu Tian on 2024/7/31.\n//\n\nimport XCTest\n\nfin"
},
{
"path": "Package.swift",
"chars": 1037,
"preview": "// swift-tools-version: 5.6\n// The swift-tools-version declares the minimum version of Swift required to build this pack"
},
{
"path": "README.md",
"chars": 4344,
"preview": "# ContributionChart\n\nA contribution chart (aka. heatmap, GitHub-like) library for iOS, macOS, and watchOS.\n\n100% written"
},
{
"path": "Sources/ContributionChart/ContributionChartTest.swift",
"chars": 430,
"preview": "//\n// SwiftUIView.swift\n// \n//\n// Created by Vikill Blacks on 2023/2/2.\n//\n\nimport SwiftUI\n\nstruct SwiftUIView: View "
},
{
"path": "Sources/ContributionChart/ContributionChartView.swift",
"chars": 5940,
"preview": "import SwiftUI\n\n@available(iOS 13, macOS 10.15, watchOS 6, *)\npublic struct ContributionChartView: View {\n \n var d"
}
]
About this extraction
This page contains the full source code of the VIkill33/SwiftUI-ContributionChart GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 18 files (40.0 KB), approximately 13.3k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.