├── .clang-format
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── custom.md
│ └── feature_request.md
└── workflows
│ ├── android.yml
│ ├── ios.yml
│ └── mirror.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── CMakeLists.txt
├── CNAME
├── CONTRIBUTING.md
├── F2.podspec
├── LEGAL.md
├── LICENSE
├── LICENSE.md
├── README.md
├── README_cn.md
├── android
└── f2native
│ ├── .gitignore
│ ├── build.gradle
│ └── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── antgroup
│ │ └── antv
│ │ └── f2
│ │ ├── F2InstrumentedTest.java
│ │ └── F2TestProxy.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── antgroup
│ │ └── antv
│ │ └── f2
│ │ ├── F2AndroidCanvasContext.java
│ │ ├── F2AndroidCanvasView.java
│ │ ├── F2BridgeRailing.java
│ │ ├── F2CSUtils.java
│ │ ├── F2CanvasView.java
│ │ ├── F2Chart.java
│ │ ├── F2ChartBridge.java
│ │ ├── F2ChartBridgeListener.java
│ │ ├── F2CommonUtils.java
│ │ ├── F2Config.java
│ │ ├── F2Constants.java
│ │ ├── F2DetectManager.java
│ │ ├── F2Event.java
│ │ ├── F2Function.java
│ │ ├── F2Geom.java
│ │ ├── F2Guide.java
│ │ ├── F2Log.java
│ │ ├── F2Util.java
│ │ ├── NativeChartProxy.java
│ │ ├── RequestAnimationFrameHandle.java
│ │ └── base
│ │ └── F2BaseCanvasView.java
│ └── res
│ └── values
│ └── strings.xml
├── build.gradle
├── core
├── CMakeLists.txt
├── Core.h
├── android
│ ├── BitmapCanvasContext.cpp
│ ├── BitmapCanvasContext.h
│ ├── BridgeRailingAndroid.cpp
│ ├── BridgeRailingAndroid.h
│ ├── CanvasImage.cpp
│ ├── F2NativeJNI.cpp
│ ├── F2NativeJNI.h
│ ├── JNIUtil.cpp
│ ├── JNIUtil.h
│ ├── JavaChartBridgeCallBack.cpp
│ ├── JavaChartBridgeCallBack.h
│ ├── JavaF2Function.h
│ ├── JavaRef.cpp
│ └── JavaRef.h
├── bridge
│ ├── AbstractBridgeRailing.h
│ ├── ChartBridge.cpp
│ └── ChartBridge.h
├── graphics
│ ├── XChart.cpp
│ ├── XChart.h
│ ├── adjust
│ │ ├── Dodge.h
│ │ └── Stack.h
│ ├── animate
│ │ ├── Animator.h
│ │ ├── GeomAnimate.cpp
│ │ ├── GeomAnimate.h
│ │ ├── TimeLine.cpp
│ │ └── TimeLine.h
│ ├── axis
│ │ ├── AxisController.cpp
│ │ └── AxisController.h
│ ├── canvas
│ │ ├── Canvas.cpp
│ │ ├── Canvas.h
│ │ ├── CanvasColorParser.cpp
│ │ ├── CanvasColorParser.h
│ │ ├── CanvasContext.h
│ │ ├── CanvasFillStrokeStyle.h
│ │ ├── CanvasFontParser.cpp
│ │ ├── CanvasFontParser.h
│ │ ├── CanvasImage.h
│ │ ├── Cartesian.h
│ │ ├── Container.h
│ │ ├── Coord.h
│ │ └── Polar.h
│ ├── event
│ │ └── EventController.h
│ ├── func
│ │ ├── Command.h
│ │ └── Func.h
│ ├── geom
│ │ ├── Area.cpp
│ │ ├── Area.h
│ │ ├── Candle.cpp
│ │ ├── Candle.h
│ │ ├── Geom.cpp
│ │ ├── Geom.h
│ │ ├── Interval.cpp
│ │ ├── Interval.h
│ │ ├── Line.cpp
│ │ ├── Line.h
│ │ ├── Path.h
│ │ ├── Point.cpp
│ │ ├── Point.h
│ │ ├── attr
│ │ │ └── AttrBase.h
│ │ └── shape
│ │ │ ├── Area.h
│ │ │ ├── Candle.h
│ │ │ ├── GeomShapeBase.h
│ │ │ ├── GeomShapeFactory.cpp
│ │ │ ├── GeomShapeFactory.h
│ │ │ ├── Interval.h
│ │ │ ├── Line.h
│ │ │ └── Point.h
│ ├── global.h
│ ├── guide
│ │ ├── Background.cpp
│ │ ├── Background.h
│ │ ├── Flag.cpp
│ │ ├── Flag.h
│ │ ├── GuideBase.cpp
│ │ ├── GuideBase.h
│ │ ├── GuideController.cpp
│ │ ├── GuideController.h
│ │ ├── Image.cpp
│ │ ├── Image.h
│ │ ├── Line.cpp
│ │ ├── Line.h
│ │ ├── Point.cpp
│ │ ├── Point.h
│ │ ├── Text.cpp
│ │ └── Text.h
│ ├── interaction
│ │ ├── InteractionBase.h
│ │ ├── InteractionContext.cpp
│ │ ├── InteractionContext.h
│ │ ├── Pan.cpp
│ │ ├── Pan.h
│ │ ├── Pinch.cpp
│ │ └── Pinch.h
│ ├── legend
│ │ ├── LegendController.cpp
│ │ └── LegendController.h
│ ├── scale
│ │ ├── Category.h
│ │ ├── Identity.h
│ │ ├── KLineCat.h
│ │ ├── Scale.cpp
│ │ ├── Scale.h
│ │ ├── ScaleController.cpp
│ │ ├── ScaleController.h
│ │ ├── TimeCategory.h
│ │ └── continuous
│ │ │ ├── Linear.cpp
│ │ │ ├── Linear.h
│ │ │ └── TimeSharingLinear.h
│ ├── shape
│ │ ├── Area.cpp
│ │ ├── Area.h
│ │ ├── Circle.cpp
│ │ ├── Circle.h
│ │ ├── Element.cpp
│ │ ├── Element.h
│ │ ├── Group.cpp
│ │ ├── Group.h
│ │ ├── Image.cpp
│ │ ├── Image.h
│ │ ├── Line.cpp
│ │ ├── Line.h
│ │ ├── Marker.cpp
│ │ ├── Marker.h
│ │ ├── Polygon.cpp
│ │ ├── Polygon.h
│ │ ├── Polyline.cpp
│ │ ├── Polyline.h
│ │ ├── Rect.cpp
│ │ ├── Rect.h
│ │ ├── Shape.cpp
│ │ ├── Shape.h
│ │ ├── Text.cpp
│ │ └── Text.h
│ ├── tooltip
│ │ ├── ToolTip.h
│ │ ├── TooltipController.cpp
│ │ └── TooltipController.h
│ └── util
│ │ ├── BBox.h
│ │ ├── Color.cpp
│ │ ├── Color.h
│ │ ├── Matrix.h
│ │ ├── Path.h
│ │ ├── Point.h
│ │ ├── Vector2d.h
│ │ ├── json.cpp
│ │ ├── json.h
│ │ ├── json_data.h
│ │ └── json_util.h
├── ios
│ ├── BridgeRailingIOS.h
│ ├── BridgeRailingIOS.mm
│ ├── CanvasImage.mm
│ ├── CoreGraphicsContext.h
│ ├── CoreGraphicsContext.mm
│ ├── F2Logger.h
│ └── F2Logger.mm
├── nlohmann
│ └── json.hpp
├── utils
│ ├── StringUtil.h
│ ├── Tracer.cpp
│ ├── Tracer.h
│ ├── common.cpp
│ ├── common.h
│ └── xtime.h
└── webassembly
│ ├── CanvasImage.cpp
│ ├── WebCanvasContext.cpp
│ ├── WebCanvasContext.h
│ └── XChart+WebAssembly.cpp
├── demos
├── android
│ ├── demos-kotlin
│ │ ├── build.gradle
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ └── gradle-wrapper.jar
│ │ ├── gradlew
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── androidTest
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── antgroup
│ │ │ │ └── antv
│ │ │ │ └── samples
│ │ │ │ └── ExampleInstrumentedTest.java
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── assets
│ │ │ │ ├── mockData_1688.json
│ │ │ │ ├── mockData_basePie.json
│ │ │ │ ├── mockData_klineDay.json
│ │ │ │ ├── mockData_line_kline.json
│ │ │ │ ├── mockData_multiAreasChart.json
│ │ │ │ ├── mockData_multiAxiesLine.json
│ │ │ │ ├── mockData_multiIntervalsChart.json
│ │ │ │ ├── mockData_multilines.json
│ │ │ │ ├── mockData_radarArea.json
│ │ │ │ ├── mockData_sectionInterval.json
│ │ │ │ ├── mockData_singleAreaChart.json
│ │ │ │ ├── mockData_singleAreaChart_2.json
│ │ │ │ ├── mockData_singleIntervalChart.json
│ │ │ │ ├── mockData_singleIntervalChart_2.json
│ │ │ │ ├── mockData_singleIntervalChart_under_zero.json
│ │ │ │ ├── mockData_singleLineChart.json
│ │ │ │ ├── mockData_singleLineChart_timeSharing_tooltip.json
│ │ │ │ ├── mockData_singlePointChart.json
│ │ │ │ ├── mockData_trendChart.json
│ │ │ │ ├── mockData_trendChart_flags.json
│ │ │ │ ├── mock_cube_data.json
│ │ │ │ ├── mock_cube_data2.json
│ │ │ │ └── wallet.png
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── antgroup
│ │ │ │ │ └── antv
│ │ │ │ │ └── f2
│ │ │ │ │ └── kotlinsamples
│ │ │ │ │ ├── BridgeActivity.kt
│ │ │ │ │ ├── BridgeControl.kt
│ │ │ │ │ ├── ChartListActivity.kt
│ │ │ │ │ ├── ChartModel.kt
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ ├── SampleActivity.kt
│ │ │ │ │ ├── SampleActivityHorizontal.kt
│ │ │ │ │ ├── Utils.kt
│ │ │ │ │ └── charts
│ │ │ │ │ ├── CandleChart_klineDay.kt
│ │ │ │ │ ├── CirclePieChart.kt
│ │ │ │ │ ├── MKTrendChart.kt
│ │ │ │ │ ├── MultiAreasChart.kt
│ │ │ │ │ ├── MultiIntervalChart.kt
│ │ │ │ │ ├── MultiIntervalChart_under_zero.kt
│ │ │ │ │ ├── MultiLinesChart_1.kt
│ │ │ │ │ ├── PieChart.kt
│ │ │ │ │ ├── RadarAreaChart.kt
│ │ │ │ │ ├── SectionIntervalChart.kt
│ │ │ │ │ ├── SingleAreaChart_1.kt
│ │ │ │ │ ├── SingleAreaChart_2.kt
│ │ │ │ │ ├── SingleIntervalChart_1.kt
│ │ │ │ │ ├── SingleIntervalChart_2.kt
│ │ │ │ │ ├── SingleIntervalChart_3.kt
│ │ │ │ │ ├── SingleLineChart_1.kt
│ │ │ │ │ ├── SingleLineChart_1688.kt
│ │ │ │ │ ├── SingleLineChart_2.kt
│ │ │ │ │ ├── SingleLineChart_KLine.kt
│ │ │ │ │ ├── SingleLineChart_TimeSharing_ToolTip.kt
│ │ │ │ │ └── SinglePointChart_1.kt
│ │ │ ├── jniLibs
│ │ │ │ ├── arm64-v8a
│ │ │ │ │ └── libc++_shared.so
│ │ │ │ └── armeabi-v7a
│ │ │ │ │ └── libc++_shared.so
│ │ │ └── res
│ │ │ │ ├── drawable-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── layout
│ │ │ │ ├── activity_bridge.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── activity_sample.xml
│ │ │ │ ├── activity_sample_horizontal.xml
│ │ │ │ ├── activity_stock_time_sharing.xml
│ │ │ │ ├── layout_chart_canvasview.xml
│ │ │ │ └── layout_chart_item.xml
│ │ │ │ ├── menu
│ │ │ │ └── menu.xml
│ │ │ │ └── values
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ └── test
│ │ │ └── java
│ │ │ └── com
│ │ │ └── antgroup
│ │ │ └── antv
│ │ │ └── samples
│ │ │ └── ExampleUnitTest.kt
│ └── demos
│ │ ├── build.gradle
│ │ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.jar
│ │ ├── gradlew
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── antgroup
│ │ │ └── antv
│ │ │ └── samples
│ │ │ └── ExampleInstrumentedTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── assets
│ │ │ ├── mockData_1688.json
│ │ │ ├── mockData_basePie.json
│ │ │ ├── mockData_klineDay.json
│ │ │ ├── mockData_line_kline.json
│ │ │ ├── mockData_multiAreasChart.json
│ │ │ ├── mockData_multiAxiesLine.json
│ │ │ ├── mockData_multiIntervalsChart.json
│ │ │ ├── mockData_multilines.json
│ │ │ ├── mockData_radarArea.json
│ │ │ ├── mockData_sectionInterval.json
│ │ │ ├── mockData_singleAreaChart.json
│ │ │ ├── mockData_singleAreaChart_2.json
│ │ │ ├── mockData_singleIntervalChart.json
│ │ │ ├── mockData_singleIntervalChart_2.json
│ │ │ ├── mockData_singleIntervalChart_under_zero.json
│ │ │ ├── mockData_singleLineChart.json
│ │ │ ├── mockData_singleLineChart_timeSharing_tooltip.json
│ │ │ ├── mockData_singlePointChart.json
│ │ │ ├── mockData_trendChart.json
│ │ │ ├── mockData_trendChart_flags.json
│ │ │ ├── mock_cube_data.json
│ │ │ ├── mock_cube_data2.json
│ │ │ └── wallet.png
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── antgroup
│ │ │ │ └── antv
│ │ │ │ └── f2
│ │ │ │ └── samples
│ │ │ │ ├── BridgeActivity.java
│ │ │ │ ├── BridgeControl.java
│ │ │ │ ├── ChartListActivity.java
│ │ │ │ ├── ChartModel.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── SampleActivity.java
│ │ │ │ ├── SampleActivityHorizontal.java
│ │ │ │ ├── Utils.java
│ │ │ │ └── charts
│ │ │ │ ├── CandleChart_klineDay.java
│ │ │ │ ├── CirclePieChart.java
│ │ │ │ ├── MKTrendChart.java
│ │ │ │ ├── MultiAreasChart.java
│ │ │ │ ├── MultiIntervalChart.java
│ │ │ │ ├── MultiIntervalChart_under_zero.java
│ │ │ │ ├── MultiLinesChart_1.java
│ │ │ │ ├── PieChart.java
│ │ │ │ ├── RadarAreaChart.java
│ │ │ │ ├── SectionIntervalChart.java
│ │ │ │ ├── SingleAreaChart_1.java
│ │ │ │ ├── SingleAreaChart_2.java
│ │ │ │ ├── SingleIntervalChart_1.java
│ │ │ │ ├── SingleIntervalChart_2.java
│ │ │ │ ├── SingleIntervalChart_3.java
│ │ │ │ ├── SingleLineChart_1.java
│ │ │ │ ├── SingleLineChart_1688.java
│ │ │ │ ├── SingleLineChart_2.java
│ │ │ │ ├── SingleLineChart_KLine.java
│ │ │ │ ├── SingleLineChart_TimeSharing_ToolTip.java
│ │ │ │ └── SinglePointChart_1.java
│ │ ├── jniLibs
│ │ │ ├── arm64-v8a
│ │ │ │ └── libc++_shared.so
│ │ │ └── armeabi-v7a
│ │ │ │ └── libc++_shared.so
│ │ └── res
│ │ │ ├── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── layout
│ │ │ ├── activity_bridge.xml
│ │ │ ├── activity_main.xml
│ │ │ ├── activity_sample.xml
│ │ │ ├── activity_sample_horizontal.xml
│ │ │ ├── activity_stock_time_sharing.xml
│ │ │ ├── layout_chart_canvasview.xml
│ │ │ └── layout_chart_item.xml
│ │ │ ├── menu
│ │ │ └── menu.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── antgroup
│ │ └── antv
│ │ └── samples
│ │ └── ExampleUnitTest.java
├── ios
│ ├── Demos-Swift
│ │ ├── Demos-Swift.xcodeproj
│ │ │ └── project.pbxproj
│ │ ├── Demos-Swift
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── AccentColor.colorset
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ ├── 128x128.png
│ │ │ │ │ ├── 16x16.png
│ │ │ │ │ ├── 180x180 1.png
│ │ │ │ │ ├── 180x180.png
│ │ │ │ │ ├── 256x256.png
│ │ │ │ │ ├── 32x32.png
│ │ │ │ │ ├── 512x512.png
│ │ │ │ │ ├── 64x64.png
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── ChartListViewController.swift
│ │ │ ├── DemoViewController.swift
│ │ │ ├── Info.plist
│ │ │ ├── Res
│ │ │ │ ├── mockData_baseArea.json
│ │ │ │ ├── mockData_baseInterval.json
│ │ │ │ ├── mockData_baseInterval2.json
│ │ │ │ ├── mockData_baseLine.json
│ │ │ │ ├── mockData_basePie.json
│ │ │ │ ├── mockData_klineDay.json
│ │ │ │ ├── mockData_marketMoving.json
│ │ │ │ ├── mockData_multiArea.json
│ │ │ │ ├── mockData_multiAxiesLine.json
│ │ │ │ ├── mockData_multiInterval.json
│ │ │ │ ├── mockData_multiLines.json
│ │ │ │ ├── mockData_radarArea.json
│ │ │ │ ├── mockData_setionInterval.json
│ │ │ │ ├── mockData_singleAreaChart_2.json
│ │ │ │ ├── mockData_singleIntervalChart_under_zero.json
│ │ │ │ ├── mockData_singlePointChart.json
│ │ │ │ └── mockData_timeSharing.json
│ │ │ ├── SceneDelegate.swift
│ │ │ ├── ViewController.swift
│ │ │ └── Views
│ │ │ │ ├── BaseAreaChart.swift
│ │ │ │ ├── BaseAreaChart2.swift
│ │ │ │ ├── BaseAreaChart3.swift
│ │ │ │ ├── BaseBarChart.swift
│ │ │ │ ├── BaseBarChart2.swift
│ │ │ │ ├── BaseLineChart.swift
│ │ │ │ ├── BaseLineChart2.swift
│ │ │ │ ├── BasePieChart.swift
│ │ │ │ ├── BasePointChart.swift
│ │ │ │ ├── CandleChart.swift
│ │ │ │ ├── ContrastLineChart.swift
│ │ │ │ ├── GroupBarChart.swift
│ │ │ │ ├── GroupBarChart2.swift
│ │ │ │ ├── GroupStackBarChart.swift
│ │ │ │ ├── HistogramBarChart.swift
│ │ │ │ ├── RadarAreaChart.swift
│ │ │ │ └── StackedAreaChart.swift
│ │ └── Podfile
│ └── Demos
│ │ ├── Demos.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Demos.xcscheme
│ │ ├── Demos
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── 128x128.png
│ │ │ │ ├── 16x16.png
│ │ │ │ ├── 180x180.png
│ │ │ │ ├── 256x256.png
│ │ │ │ ├── 32x32.png
│ │ │ │ ├── 512x512.png
│ │ │ │ ├── 64x64.png
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.storyboard
│ │ ├── BugFixViewController.h
│ │ ├── BugFixViewController.m
│ │ ├── ChartListViewController.h
│ │ ├── ChartListViewController.m
│ │ ├── DemoViewController.h
│ │ ├── DemoViewController.m
│ │ ├── Info.plist
│ │ ├── Res
│ │ │ ├── bugfix
│ │ │ │ ├── fund_chart.json
│ │ │ │ ├── indicator_chart.json
│ │ │ │ ├── kline_trend.json
│ │ │ │ ├── market_trend.json
│ │ │ │ ├── minute_trend_indicator.json
│ │ │ │ ├── minute_trend_price.json
│ │ │ │ ├── mockData_marketMovingBugfix1.json
│ │ │ │ └── mockData_timeSharingBugfix1.json
│ │ │ ├── mockData_baseArea.json
│ │ │ ├── mockData_baseInterval.json
│ │ │ ├── mockData_baseLine.json
│ │ │ ├── mockData_basePie.json
│ │ │ ├── mockData_klineDay.json
│ │ │ ├── mockData_marketMoving.json
│ │ │ ├── mockData_multiArea.json
│ │ │ ├── mockData_multiAxiesLine.json
│ │ │ ├── mockData_multiInterval.json
│ │ │ ├── mockData_multiLines.json
│ │ │ ├── mockData_radarArea.json
│ │ │ ├── mockData_setionInterval.json
│ │ │ ├── mockData_singleAreaChart_2.json
│ │ │ ├── mockData_singleIntervalChart_under_zero.json
│ │ │ ├── mockData_singlePointChart.json
│ │ │ └── mockData_timeSharing.json
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ ├── en.lproj
│ │ │ └── Localizable.strings
│ │ ├── main.m
│ │ ├── views
│ │ │ ├── BaseAreaChart.h
│ │ │ ├── BaseAreaChart.m
│ │ │ ├── BaseAreaChart2.h
│ │ │ ├── BaseAreaChart2.m
│ │ │ ├── BaseAreaChart3.h
│ │ │ ├── BaseAreaChart3.m
│ │ │ ├── BaseBarChart.h
│ │ │ ├── BaseBarChart.m
│ │ │ ├── BaseBarChart2.h
│ │ │ ├── BaseBarChart2.m
│ │ │ ├── BaseGuideChart.h
│ │ │ ├── BaseGuideChart.m
│ │ │ ├── BaseLineChart.h
│ │ │ ├── BaseLineChart.m
│ │ │ ├── BaseLineChart2.h
│ │ │ ├── BaseLineChart2.m
│ │ │ ├── BasePieChart.h
│ │ │ ├── BasePieChart.m
│ │ │ ├── BasePointChart.h
│ │ │ ├── BasePointChart.m
│ │ │ ├── CandleChart.h
│ │ │ ├── CandleChart.m
│ │ │ ├── ContrastLineChart.h
│ │ │ ├── ContrastLineChart.m
│ │ │ ├── CyclicPieChart.h
│ │ │ ├── CyclicPieChart.m
│ │ │ ├── GroupBarChart.h
│ │ │ ├── GroupBarChart.m
│ │ │ ├── GroupBarChart2.h
│ │ │ ├── GroupBarChart2.m
│ │ │ ├── GroupStackBarChart.h
│ │ │ ├── GroupStackBarChart.m
│ │ │ ├── HistogramBarChart.h
│ │ │ ├── HistogramBarChart.m
│ │ │ ├── MarketMovingChart.h
│ │ │ ├── MarketMovingChart.m
│ │ │ ├── RadarAreaChart.h
│ │ │ ├── RadarAreaChart.m
│ │ │ ├── StackedAreaChart.h
│ │ │ ├── StackedAreaChart.m
│ │ │ ├── StripChart.h
│ │ │ ├── StripChart.m
│ │ │ ├── TimeSharingChart.h
│ │ │ ├── TimeSharingChart.m
│ │ │ └── bugfix
│ │ │ │ ├── KLineTrendBugFix1.h
│ │ │ │ ├── KLineTrendBugFix1.m
│ │ │ │ ├── MarketMovingBugFix1.h
│ │ │ │ ├── MarketMovingBugFix1.m
│ │ │ │ ├── TimeSharingBugFix1.h
│ │ │ │ └── TimeSharingBugFix1.m
│ │ ├── zh-HK.lproj
│ │ │ └── LaunchScreen.strings
│ │ └── zh-Hans.lproj
│ │ │ ├── LaunchScreen.strings
│ │ │ └── Localizable.strings
│ │ ├── F2Native.entitlements
│ │ └── Podfile
├── videos
│ └── ios_demo.mp4
└── webassembly
│ ├── f2wasm.js
│ ├── f2wasm.wasm
│ ├── index.html
│ └── run.sh
├── docs
├── api
│ ├── API.en.md
│ ├── API.zh.md
│ ├── F2Area.en.md
│ ├── F2Area.zh.md
│ ├── F2Axis.en.md
│ ├── F2Axis.zh.md
│ ├── F2CanvasView.en.md
│ ├── F2CanvasView.zh.md
│ ├── F2Chart.en.md
│ ├── F2Chart.zh.md
│ ├── F2Guide.en.md
│ ├── F2Guide.zh.md
│ ├── F2Interval.en.md
│ ├── F2Interval.zh.md
│ ├── F2Legend.en.md
│ ├── F2Legend.zh.md
│ ├── F2Line.en.md
│ ├── F2Line.zh.md
│ ├── F2Scale.en.md
│ └── F2Scale.zh.md
├── examples
│ ├── area
│ │ ├── area.en.md
│ │ ├── area.zh.md
│ │ ├── stackedArea.en.md
│ │ └── stackedArea.zh.md
│ ├── bar.en.md
│ ├── bar.zh.md
│ ├── column
│ │ ├── column.en.md
│ │ ├── column.zh.md
│ │ ├── dodgeColumn.en.md
│ │ └── dodgeColumn.zh.md
│ ├── line
│ │ ├── line.en.md
│ │ ├── line.zh.md
│ │ ├── multiLine.en.md
│ │ └── multiLine.zh.md
│ ├── pie.en.md
│ └── pie.zh.md
└── tutorial
│ ├── getting-started.en.md
│ ├── getting-started.zh.md
│ └── manual
│ ├── attribute.en.md
│ ├── attribute.zh.md
│ ├── coordinate.en.md
│ ├── coordinate.zh.md
│ ├── data.en.md
│ ├── data.zh.md
│ ├── geometry.en.md
│ ├── geometry.zh.md
│ ├── grammar.en.md
│ ├── grammar.zh.md
│ ├── scale.en.md
│ ├── scale.zh.md
│ ├── understanding.en.md
│ └── understanding.zh.md
├── externals.d.ts
├── gatsby-browser.js
├── gatsby-config.js
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── ios
├── F2.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── F2.xcscheme
│ │ └── F2Tests.xcscheme
├── F2
│ ├── F2-Prefix.pch
│ ├── F2.h
│ ├── F2Callback.h
│ ├── F2Callback.mm
│ ├── F2CanvasContext.h
│ ├── F2CanvasContext.mm
│ ├── F2CanvasView.h
│ ├── F2CanvasView.mm
│ ├── F2Chart.h
│ ├── F2Chart.mm
│ ├── F2Coordinate.h
│ ├── F2Coordinate.mm
│ ├── F2Geom.h
│ ├── F2Geom.mm
│ ├── F2GestureListener.h
│ ├── F2GestureListener.m
│ ├── F2Guide.h
│ ├── F2Guide.mm
│ ├── F2Utils.h
│ └── F2Utils.m
├── F2Tests
│ ├── F2CanvasTests.mm
│ ├── F2ChartBridgeTests.mm
│ ├── F2ChartTests.mm
│ ├── F2ScalesTests.mm
│ ├── F2TestUtil.h
│ ├── F2TestUtil.m
│ ├── F2UtilsTests.mm
│ └── Info.plist
└── Info.plist
├── package-lock.json
├── package.json
├── settings.gradle
├── site
├── locale.json
└── pages
│ ├── index.en.tsx
│ └── index.zh.tsx
├── tests
├── CMakeLists.txt
├── e2e
│ ├── BaseInterval.h
│ ├── Baseline.h
│ ├── F2PixelMatch.h
│ ├── F2PixelMatch.mm
│ ├── MarketMoving.h
│ └── pixelmatch.hpp
├── main.cpp
├── res
│ ├── badcase.jpg
│ ├── black.png
│ ├── chart_bridge.json
│ ├── e2e
│ │ ├── baseInterval.jpeg
│ │ ├── baseLine.jpeg
│ │ ├── chartBridge.jpeg
│ │ └── marketMoving.jpeg
│ ├── kline_day.json
│ ├── kline_minutes_5.json
│ ├── kline_minutes_60.json
│ ├── mockData_baseInterval.json
│ ├── mockData_baseLine.json
│ ├── mockData_marketTrend.json
│ ├── red.png
│ ├── transparent.png
│ ├── white&black.png
│ ├── white&red.png
│ └── white.png
├── run.sh
└── unit
│ ├── XChart.h
│ ├── bridge
│ └── ChartBridge.h
│ ├── canvas
│ ├── CanvasColorParser.h
│ ├── CanvasFontParser.h
│ ├── Cartesian.h
│ └── Polar.h
│ ├── scale
│ ├── Category.h
│ ├── KLineCat.h
│ ├── Linear.h
│ ├── ScaleController.h
│ └── TimeSharingLinear.h
│ └── utils
│ ├── Point.h
│ ├── StringUtils.h
│ ├── Vector2d.h
│ ├── XTime.h
│ └── json.h
└── webassembly
└── CMakeLists.txt
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/custom.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Custom issue template
3 | about: Describe this issue template's purpose here.
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android Tests
2 |
3 | on:
4 | push:
5 | branches: [ "master" ]
6 | pull_request:
7 | branches: [ "master" ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: macos-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 | - name: set up JDK 11
17 | uses: actions/setup-java@v3
18 | with:
19 | java-version: '11'
20 | ndk-version: 22.1.7171670
21 | distribution: 'temurin'
22 | cache: gradle
23 |
24 | - name: Grant execute permission for gradlew
25 | run: chmod +x gradlew
26 | - name: Build with Gradle
27 | run: ./gradlew android:f2native:connectedAndroidTest
28 |
--------------------------------------------------------------------------------
/.github/workflows/ios.yml:
--------------------------------------------------------------------------------
1 | name: iOS Tests
2 |
3 | on:
4 | push:
5 | branches: [ "master", "2.x" ]
6 | pull_request:
7 | branches: [ "master", "2.x" ]
8 |
9 | jobs:
10 | build:
11 | name: Build and Test default scheme using any available iPhone simulator
12 | runs-on: macos-latest
13 |
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v3
17 | - name: Run Tests
18 | run: |
19 | cd ios
20 | ls
21 | xcodebuild test -project F2.xcodeproj -scheme F2Tests -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 12,OS=15.2'
22 |
--------------------------------------------------------------------------------
/.github/workflows/mirror.yml:
--------------------------------------------------------------------------------
1 | name: 🤖 Sync to Gitee Mirror
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: 🔁 Sync to Gitee
10 | uses: wearerequired/git-mirror-action@master
11 | env:
12 | # 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY
13 | SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}
14 | with:
15 | # 注意替换为你的 GitHub 源仓库地址
16 | source-repo: https://github.com/antvis/F2Native.git
17 | # 注意替换为你的 Gitee 目标仓库地址
18 | destination-repo: git@gitee.com:antv-f2native/antv-f2native.git
19 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | package.json
3 | package-lock.json
4 | public
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": true,
4 | "singleQuote": true,
5 | "tabWidth": 2
6 | }
7 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | add_subdirectory(core)
4 |
5 | #如何只在debug的时候增加
6 | #add_subdirectory(tests)
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | f2native.antv.vision
--------------------------------------------------------------------------------
/LEGAL.md:
--------------------------------------------------------------------------------
1 | Legal Disclaimer
2 |
3 | Within this source code, the comments in Chinese shall be the original, governing version. Any comment in other languages are for reference only. In the event of any conflict between the Chinese language version comments and other language version comments, the Chinese language version shall prevail.
4 |
5 | 法律免责声明
6 |
7 | 关于代码注释部分,中文注释为官方版本,其它语言注释仅做参考。中文注释可能与其它语言注释存在不一致,当中文注释与其它语言注释存在不一致时,请以中文注释为准。
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 AntV team
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/LICENSE.md
--------------------------------------------------------------------------------
/android/f2native/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/android/f2native/src/androidTest/java/com/antgroup/antv/f2/F2InstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class F2InstrumentedTest {
20 | @Test
21 | public void runAllTest() {
22 | if(BuildConfig.DEBUG) {
23 | System.loadLibrary("f2tests");
24 | F2TestProxy test = new F2TestProxy();
25 |
26 | //所有c++的单测都在JNI的runTest中
27 | assertEquals(test.runTest(), 1);
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/android/f2native/src/androidTest/java/com/antgroup/antv/f2/F2TestProxy.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 | public class F2TestProxy {
4 | public native int runTest();
5 | }
6 |
--------------------------------------------------------------------------------
/android/f2native/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2CSUtils.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 |
4 | /**
5 | * finanacechart 仓库sync.js脚本自动替换当前类
6 | */
7 | public class F2CSUtils {
8 |
9 | public static void showUseNativeCanvasToast(String content) {
10 | }
11 |
12 | // 是否开启白屏检测开关
13 | public static boolean isDetectEnable() {
14 | // kF2NativeReleaseProductDetKey
15 | return true;
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2ChartBridgeListener.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 | /**
4 | * cube bridge中invokeMethod调用的callback
5 | * author by luna
6 | * date on 2022/5/28
7 | */
8 |
9 | public abstract class F2ChartBridgeListener {
10 |
11 | private String methodName;
12 | private String bizId;
13 |
14 | public F2ChartBridgeListener(String methodName, String bizId) {
15 | this.methodName = methodName;
16 | this.bizId = bizId;
17 | }
18 |
19 | public String getMethodName() {
20 | return methodName;
21 | }
22 |
23 | public String getBizId() {
24 | return bizId;
25 | }
26 |
27 | public abstract void onResult(String methodName, String bizId, String result);
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2Constants.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 | /**
4 | * @author qingyuan.yl
5 | * @date 2020-09-22
6 | */
7 | public class F2Constants {
8 |
9 | public static final int CODE_SUCCESS = 0;
10 | public static final int CODE_FAIL_UNKNOWN = -1;
11 | public static final int CODE_INIT_EGL_FAIL = 1;
12 | public static final int CODE_INIT_CANVAS_CONTEXT_FAIL = 2;
13 | public static final int CODE_CREATE_CANVAS_2D_CONTEXT_FAIL = 3;
14 | public static final int CODE_RESUME_CANVAS_FAIL = 4;
15 |
16 | public static boolean isSuccessCode(int code) {
17 | return code == CODE_SUCCESS;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2DetectManager.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 |
4 | import android.graphics.Bitmap;
5 |
6 | /**
7 | * 用于检测白屏
8 | */
9 | public class F2DetectManager {
10 |
11 | public void sendRenderDetectEvent(Bitmap snapshotBitmap, String appId, String bizType, long renderDuration, boolean renderSuccess,
12 | int renderCmdCount, boolean drawSuccess,
13 | int width, int height, double ratio, String chartId) {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2Event.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 |
4 | /**
5 | * finanacechart 仓库脚本自动替换当前类
6 | *
7 | * @author qingyuan.yl
8 | */
9 | public class F2Event {
10 |
11 | // native canvas init调用
12 | public static void eventPage(String appId, String bizType, String desc) {
13 | }
14 |
15 | /**
16 | * native canvas绘制调用
17 | *
18 | * @param renderDuration c++渲染是时长
19 | * @param renderSuccess c++渲染是否成功
20 | * @param renderCmdCount c++侧渲染的指令
21 | * @param drawSuccess native侧上屏是否成功
22 | * @param bitmapBytes 白屏的二进制图片,非白屏的时候为null
23 | * @param detectDuration 截屏&分析白屏的时间消耗
24 | * @param desc chartId+扩展描述
25 | */
26 | public static void eventDetectRender(String appId, String bizType, long renderDuration, boolean renderSuccess,
27 | int renderCmdCount, boolean drawSuccess, byte[] bitmapBytes, long detectDuration,
28 | int width, int height, double ratio, String desc) {
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2Function.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 | import java.util.UUID;
4 |
5 | /**
6 | * @author qingyuan.yl
7 | * @date 2020/12/1
8 | */
9 | public abstract class F2Function {
10 |
11 | protected String functionId = null;
12 |
13 | public F2Function() {
14 | this.functionId = UUID.randomUUID().toString();
15 | }
16 |
17 | final void bindChart(F2Chart chart) {
18 | chart.bindChart(functionId, this);
19 | }
20 |
21 | public abstract F2Config execute(String param);
22 | }
23 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/F2Log.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * @author qingyuan.yl
7 | * @date 2020-09-18
8 | */
9 | public final class F2Log {
10 |
11 | private static final String TAG = "F2Native";
12 |
13 | public static void i(String traceId, String content) {
14 | Log.i(TAG + "[" + threadName() + "]|" + traceId, content);
15 | }
16 |
17 | public static void w(String traceId, String content) {
18 | Log.w(TAG + "[" + threadName() + "]|" + traceId, content);
19 | }
20 |
21 | public static void e(String traceId, String content) {
22 | Log.e(TAG + "[" + threadName() + "]|" + traceId, content);
23 | }
24 |
25 | public static void e(String traceId, String msg, Throwable t) {
26 | Log.e(TAG + "[" + threadName() + "]|" + traceId, msg, t);
27 | }
28 |
29 | private static String threadName() {
30 | return Thread.currentThread().getName();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/android/f2native/src/main/java/com/antgroup/antv/f2/base/F2BaseCanvasView.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2.base;
2 |
3 | import android.view.View;
4 |
5 | import com.antgroup.antv.f2.F2CanvasView;
6 | import com.antgroup.antv.f2.F2Config;
7 |
8 | /**
9 | * 业务层调用F2CanvasView的接口,antg和native canvas子类分别实现
10 | */
11 | public interface F2BaseCanvasView {
12 |
13 | // 单位是px
14 | void init(int widthPixel, int heightPixel, F2Config config);
15 |
16 | View getView();
17 |
18 | void setAdapter(F2CanvasView.Adapter adapter);
19 |
20 | void setOnCanvasTouchListener(F2CanvasView.OnCanvasTouchListener onCanvasTouchListener);
21 |
22 | void initCanvasContext();
23 |
24 | void initCanvasContext(F2Config config);
25 |
26 | long getNativeCanvas();
27 |
28 | boolean swapBuffer();
29 |
30 | void destroy();
31 |
32 | void postCanvasDraw();
33 |
34 | boolean hasAdapter();
35 |
36 | void sendRenderDetectEvent(long renderDuration, boolean renderSuccess, int renderCmdCount,
37 | boolean drawSuccess, String chartId);
38 |
39 | boolean isDrawSuccess();
40 |
41 | boolean hadOOM();
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/android/f2native/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | f2native
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = "1.4.31"
5 | repositories {
6 | google()
7 | jcenter()
8 |
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.5.3'
12 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | allprojects {
18 | project.ext.meta = [:]
19 | repositories {
20 | google()
21 | jcenter()
22 | maven { url 'https://jitpack.io' }
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
30 | rootProject.extensions.sdks = [
31 | 'Gradle' : '3.0.1',
32 | 'CompileSDK' : 28,
33 | 'BuildTool' : '28.0.3',
34 | 'MinSDK' : 18,
35 | 'TargetSDK' : 28,
36 | 'JUnit' : '4.12',
37 | 'Support' : '26.0.2',
38 | 'ABIs' : ["armeabi-v7a","arm64-v8a"],
39 | 'EXCLUDE_CPP_SHARED' : false
40 | ]
41 |
--------------------------------------------------------------------------------
/core/android/CanvasImage.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // CanvasImage.cpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2022/1/17.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #if defined(ANDROID)
10 |
11 | #include "graphics/canvas/CanvasImage.h"
12 |
13 | using namespace xg;
14 | using namespace xg::canvas;
15 |
16 | CanvasImage::~CanvasImage() {
17 | if (image_) {
18 | image_ = nullptr;
19 | }
20 | }
21 |
22 | void CanvasImage::OnLoad(std::function finished) {
23 | //通过JNI方法调用Java下载
24 | }
25 |
26 | float CanvasImage::GetWidth() {
27 | return 0;
28 | }
29 |
30 | float CanvasImage::GetHeight() {
31 | return 0;
32 | }
33 |
34 | #endif //ANDROID
35 |
--------------------------------------------------------------------------------
/core/android/F2NativeJNI.h:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 |
5 | #include "JNIUtil.h"
6 |
7 | #ifndef XG_F2_NATIVE_ANDROID_JNI_H
8 | #define XG_F2_NATIVE_ANDROID_JNI_H
9 |
10 | #define CODE_SUCCESS 0
11 | #define CODE_FAIL_UNKNOWN -1
12 | #define CODE_INIT_EGL_FAIL 1
13 | #define CODE_INIT_CANVAS_CONTEXT_FAIL 2
14 | #define CODE_CREATE_CANVAS_2D_CONTEXT_FAIL 3
15 | #define CODE_RESUME_CANVAS_FAIL 4
16 |
17 | #define LOG_BUFFER_SIZE 2048
18 |
19 | namespace xg {
20 | namespace jni {
21 |
22 | void InnerLog(int level, std::string traceId, const char *fmt, ...);
23 |
24 | } // namespace jni
25 | } // namespace xg
26 |
27 | #define F2_LOG_INFO 1
28 | #define F2_LOG_WARN 2
29 | #define F2_LOG_ERROR 3
30 |
31 | #define F2_LOG_I(traceId, ...) ((void)xg::jni::InnerLog(F2_LOG_INFO, traceId, __VA_ARGS__))
32 | #define F2_LOG_W(traceId, ...) ((void)xg::jni::InnerLog(F2_LOG_WARN, traceId, __VA_ARGS__))
33 | #define F2_LOG_E(traceId, ...) ((void)xg::jni::InnerLog(F2_LOG_ERROR, traceId, __VA_ARGS__))
34 |
35 | #endif // XG_F2_NATIVE_ANDROID_JNI_H
36 |
--------------------------------------------------------------------------------
/core/android/JNIUtil.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "JavaRef.h"
5 |
6 | #ifndef XG_F2_NATIVE_ANDROID_JNI_UTILS_H
7 | #define XG_F2_NATIVE_ANDROID_JNI_UTILS_H
8 |
9 | namespace xg {
10 | namespace jni {
11 | void InitJavaVM(JavaVM *vm);
12 |
13 | JavaVM *GetJVM();
14 |
15 | JNIEnv *GetJniEnv();
16 |
17 | JNIEnv *GetJniEnvSafe();
18 |
19 | JNIEnv *AttachCurrentThread();
20 |
21 | void DetachFromVM();
22 |
23 | ScopedJavaLocalRef StringToJavaString(JNIEnv *env, const std::string &str);
24 |
25 | ScopedJavaLocalRef VectorToJFloatArray(JNIEnv *env, const std::vector ¶ms);
26 |
27 | ScopedJavaLocalRef VectorToJIntArray(JNIEnv *env, const std::vector ¶ms);
28 |
29 | bool HasException(JNIEnv *env);
30 |
31 | bool ClearException(JNIEnv *env);
32 |
33 | std::string JavaStringToString(JNIEnv *env, jstring string);
34 |
35 | jstring StringToJString(JNIEnv *env, const std::string &u8_string);
36 |
37 | void native_clog(int level, const char *tag, const char *msg);
38 |
39 | // std::string GetJavaExceptionInfo(JNIEnv *env, jthrowable java_throwable);
40 | } // namespace jni
41 | } // namespace xg
42 |
43 | #endif // XG_F2_NATIVE_ANDROID_JNI_UTILS_H
44 |
--------------------------------------------------------------------------------
/core/android/JavaChartBridgeCallBack.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by luna on 2022/5/27.
3 | //
4 |
5 | #ifndef CHART_NATIVE_CORE_JAVACHARTBRIDGECALLBACK_H
6 | #define CHART_NATIVE_CORE_JAVACHARTBRIDGECALLBACK_H
7 |
8 | #include
9 | #include
10 | #include "JavaRef.h"
11 |
12 | namespace xg {
13 | namespace bridge {
14 | class JavaChartBridgeCallBack {
15 | public:
16 | /**
17 | * nativeBridgeObject 传入Android层的F2ChartBridge对象
18 | */
19 | JavaChartBridgeCallBack(jobject nativeBridgeObject);
20 |
21 | ~JavaChartBridgeCallBack();
22 |
23 | /**
24 | * chartbridge callback的函数,反射调用Android层的函数
25 | * @param message callback的数据
26 | */
27 | void BridgeCallback(const std::string &message);
28 |
29 | private:
30 | /**
31 | * load class
32 | */
33 | bool InitClass(JNIEnv *env);
34 |
35 | JNIEnv *env_ = nullptr;
36 | jmethodID invokeCallbackMethod_ = nullptr;
37 | // 用于反射callback
38 | xg::jni::ScopedJavaGlobalRef *nativeBridgeObject_ = nullptr;
39 |
40 | };
41 | }
42 | }
43 |
44 |
45 | #endif //CHART_NATIVE_CORE_JAVACHARTBRIDGECALLBACK_H
46 |
--------------------------------------------------------------------------------
/core/graphics/animate/TimeLine.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_ANIMATE_TIMELINE_H
2 | #define XG_GRAPHICS_ANIMATE_TIMELINE_H
3 |
4 | #include "Animator.h"
5 |
6 | namespace xg {
7 | class XChart;
8 | namespace animate {
9 | class TimeLine {
10 | public:
11 | TimeLine(XChart *chart) : chart_(chart) {}
12 |
13 | void Play();
14 |
15 | void Stop();
16 |
17 | void Clear() { playing_ = false; }
18 |
19 | void PushAnim(AnimInfo &&animInfo);
20 |
21 | ~TimeLine();
22 |
23 | protected:
24 | void OnUpdate();
25 |
26 | private:
27 | void frameLoop();
28 |
29 | private:
30 | XChart *chart_;
31 | bool playing_ = false;
32 | std::vector animInfos_;
33 | long long time_;
34 | };
35 | } // namespace animate
36 | } // namespace xg
37 |
38 | #endif // XG_GRAPHICS_ANIMATE_TIMELINE_H
39 |
--------------------------------------------------------------------------------
/core/graphics/canvas/Canvas.cpp:
--------------------------------------------------------------------------------
1 | #include "Canvas.h"
2 |
3 | using namespace xg;
4 |
5 | void canvas::Canvas::Draw(canvas::CanvasContext &context) {
6 | if (this->IsDestroyed()) {
7 | return;
8 | }
9 |
10 | context.ClearRect(origin.x, origin.y, size.width, size.height);
11 |
12 | this->DrawInner(context);
13 | }
14 |
--------------------------------------------------------------------------------
/core/graphics/canvas/Canvas.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_CANVAS_H
2 | #define XG_GRAPHICS_CANVAS_H
3 |
4 | #include "CanvasContext.h"
5 | #include "../shape/Group.h"
6 |
7 | namespace xg {
8 | namespace canvas {
9 |
10 | class Canvas : public shape::Group {
11 | public:
12 | Canvas() : Group() {}
13 |
14 | void ChangeSize(double x, double y, double width, double height) {
15 | origin = {x, y};
16 | size = {width, height};
17 | }
18 |
19 | void Draw(canvas::CanvasContext &context);
20 |
21 | void Destroy() override {
22 | Group::Destroy();
23 | }
24 |
25 | private:
26 | util::Point origin{0, 0};
27 | util::Size size{0, 0};
28 | };
29 | } // namespace canvas
30 | } // namespace xg
31 |
32 | #endif // XG_GRAPHICS_CANVAS_H
33 |
--------------------------------------------------------------------------------
/core/graphics/canvas/CanvasColorParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by ruize on 2022/1/7.
3 | //
4 |
5 | #ifndef XG_GRAPHICS_CANVAS_CANVASCOLORPARSER_H
6 | #define XG_GRAPHICS_CANVAS_CANVASCOLORPARSER_H
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | namespace xg {
14 |
15 | namespace canvas {
16 |
17 | struct CanvasColor {
18 | float r = 0;
19 | float g = 0;
20 | float b = 0;
21 | float a = 0;
22 | };
23 |
24 | class CanvasColorParser {
25 |
26 | public:
27 | /*
28 | *入口解析函数
29 | *支持解析#RRGGBBAA,#RGB,字符串(white,red),rgba(1, 1, 1, 1), rgb(1, 1, 1), hsl(0, 100%, 50%),hsla(120,100%,50%,0.3
30 | */
31 | static bool Parse(const std::string &str, CanvasColor &output);
32 |
33 | /*
34 | * 解析成安卓平台的ARGB格式
35 | */
36 | static int RGBAToHex(const CanvasColor &color);
37 | private:
38 | static void InitColorMapIfEmpty();
39 |
40 | private:
41 | static std::unordered_map colorMap;
42 | static std::mutex global_mutex;
43 | static std::string hex_digit;
44 | };
45 |
46 | } // namespace canvas
47 | } // namespace xg
48 |
49 | #endif // XG_GRAPHICS_CANVAS_CANVASCOLORPARSER_H
50 |
--------------------------------------------------------------------------------
/core/graphics/canvas/CanvasImage.h:
--------------------------------------------------------------------------------
1 | //
2 | // CanvasImage.hpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2022/1/17.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #ifndef XG_GRAPHICS_CANVAS_CANVASIMAGE_H
10 | #define XG_GRAPHICS_CANVAS_CANVASIMAGE_H
11 |
12 | #include
13 | #include
14 |
15 | namespace xg {
16 | namespace canvas {
17 |
18 | class CanvasImage {
19 | public:
20 | CanvasImage() = delete;
21 | CanvasImage(const std::string &url) : url_(url){};
22 | ~CanvasImage();
23 |
24 | void OnLoad(std::function finished);
25 |
26 | inline void *GetImage() { return image_; }
27 |
28 | float GetWidth();
29 |
30 | float GetHeight();
31 |
32 | inline const std::string &GetURL() { return url_; }
33 |
34 | inline bool IsValid() const { return image_ != nullptr; }
35 |
36 | private:
37 | //在ios上是CGImageRef
38 | void *image_ = nullptr;
39 | //在ios上是一个下载器
40 | void *downloader_ = nullptr;
41 | //图片的url地址
42 | std::string url_;
43 | };
44 |
45 | } // namespace canvas
46 | } // namespace xg
47 |
48 | #endif /* XG_GRAPHICS_CANVAS_CANVASIMAGE_H */
49 |
--------------------------------------------------------------------------------
/core/graphics/func/Command.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_FUNC_COMMAND_H
2 | #define XG_GRAPHICS_FUNC_COMMAND_H
3 |
4 | namespace xg {
5 | namespace func {
6 | struct Command {
7 | virtual void run() {}
8 |
9 | virtual ~Command() {}
10 | };
11 |
12 | template struct CommandImpl : Command {
13 | CommandImpl(Function _func) : func(_func) {}
14 | virtual void run() override { func(); }
15 | Function func;
16 | };
17 |
18 | template Command *CreateCommand(Function f) { return new CommandImpl(f); }
19 |
20 | } // namespace func
21 | } // namespace xg
22 |
23 | #endif // XG_GRAPHICS_FUNC_COMMAND_H
24 |
--------------------------------------------------------------------------------
/core/graphics/geom/Area.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GEOM_AREA_H
2 | #define XG_GRAPHICS_GEOM_AREA_H
3 |
4 | #include "Geom.h"
5 |
6 | namespace xg {
7 | class XChart;
8 | namespace geom {
9 |
10 | class Area : public AbstractGeom {
11 | public:
12 | Area(Group *_container, utils::Tracer *tracer) : AbstractGeom(_container, tracer) {
13 | type_ = "area";
14 | shapeType_ = "area";
15 | sortable_ = true;
16 | generatePoints_ = true;
17 | }
18 |
19 | void BeforeMapping(XChart &chart, XDataGroup &dataArray) override;
20 |
21 | private:
22 | nlohmann::json CreateShapePointsCfg(XChart &chart, XData &data);
23 |
24 | nlohmann::json GetAreaPoints(XChart &chart, XData &data, nlohmann::json &cfg);
25 | };
26 | } // namespace geom
27 | } // namespace xg
28 |
29 | #endif /* XG_GRAPHICS_GEOM_AREA_H */
30 |
--------------------------------------------------------------------------------
/core/graphics/geom/Candle.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GEOM_CANDLE_H
2 | #define XG_GRAPHICS_GEOM_CANDLE_H
3 |
4 | #include "Geom.h"
5 | #include "../util/json.h"
6 |
7 | namespace xg {
8 | namespace geom {
9 |
10 | class Candle : public AbstractGeom {
11 | public:
12 | Candle(Group *_container, utils::Tracer *tracer) : AbstractGeom(_container, tracer) {
13 | type_ = "candle";
14 | generatePoints_ = true;
15 | this->styleConfig_ = {
16 | {"lineWidth", 1}, // lineWidth
17 | {"fill", {"#1CAA3D", "#808080", "#F4333C"}}, // or {"strock", {"#1CAA3D", "#808080", "#F4333C"}}, colors: [down, equal, up]
18 | };
19 | }
20 |
21 | nlohmann::json CreateShapePointsCfg(XChart &chart, XData &item, size_t index);
22 |
23 | void BeforeMapping(XChart &chart, XDataGroup &dataArray) override;
24 |
25 | void Draw(XChart &chart, const XDataArray &groupData, std::size_t start, std::size_t end) const override;
26 |
27 | private:
28 | nlohmann::json getRectPoints(nlohmann::json &cfg);
29 | nlohmann::json getLinePoints(nlohmann::json &cfg);
30 | };
31 | } // namespace geom
32 | } // namespace xg
33 |
34 | #endif /* XG_GRAPHICS_GEOM_CANDLE_H */
35 |
--------------------------------------------------------------------------------
/core/graphics/geom/Interval.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GEOM_INTERVAL_H
2 | #define XG_GRAPHICS_GEOM_INTERVAL_H
3 |
4 | #include "Geom.h"
5 | #include "../util/json.h"
6 |
7 | namespace xg {
8 | namespace geom {
9 |
10 | class Interval : public AbstractGeom {
11 | public:
12 | Interval(Group *_container, utils::Tracer *tracer) : AbstractGeom(_container, tracer) {
13 | type_ = "interval";
14 | generatePoints_ = true;
15 | nlohmann::json defaultCfg ={{"lineWidth", 1}, {"stroke", "#ffffff"}, {"widthRatio", 0.5}};
16 | if(this->styleConfig_.is_object()) {
17 | this->styleConfig_.merge_patch(defaultCfg);
18 | }
19 | }
20 |
21 | float GetDefaultWidthRatio(XChart &chart);
22 |
23 | nlohmann::json CreateShapePointsCfg(XChart &chart, XData &item, size_t index); // {x, y, y0, size}
24 |
25 | void BeforeMapping(XChart &chart, XDataGroup &dataArray) override;
26 |
27 | nlohmann::json getRectPoints(nlohmann::json &cfg);
28 |
29 | virtual void Draw(XChart &chart, const XDataArray &groupData, std::size_t start, std::size_t end) const override;
30 |
31 | Interval &Tag(const std::string &json = "{}");
32 |
33 | private:
34 | nlohmann::json tagConfig_;
35 | };
36 | } // namespace geom
37 | } // namespace xg
38 |
39 | #endif /* XG_GRAPHICS_GEOM_INTERVAL_H */
40 |
--------------------------------------------------------------------------------
/core/graphics/geom/Line.cpp:
--------------------------------------------------------------------------------
1 | #include "Line.h"
2 | #include "../XChart.h"
3 |
4 | using namespace xg;
5 |
6 | void geom::Line::BeforeMapping(XChart &chart, XDataGroup &dataArray) {
7 | if(!styleConfig_.is_object() || styleConfig_.empty())
8 | return;
9 |
10 | auto &xScale = chart.GetScale(GetXScaleField());
11 |
12 | for(std::size_t index = 0; index < dataArray.size(); ++index) {
13 |
14 | auto &groupData = dataArray[index];
15 | std::size_t start = 0, end = groupData.size() - 1;
16 | if(scale::IsCategory(xScale.GetType())) {
17 | start = fmax(start, xScale.min);
18 | end = fmin(end, xScale.max);
19 | }
20 |
21 | for(std::size_t position = start; position <= end; ++position) {
22 | auto &item = groupData[position];
23 | item._style = styleConfig_;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/core/graphics/geom/Line.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GEOM_LINE_H
2 | #define XG_GRAPHICS_GEOM_LINE_H
3 |
4 | #include "Geom.h"
5 |
6 | namespace xg {
7 | namespace geom {
8 |
9 | class Line : public AbstractGeom {
10 | public:
11 | Line(Group *_container, utils::Tracer *tracer) : AbstractGeom(_container, tracer) {
12 | type_ = "line";
13 | sortable_ = true;
14 | }
15 |
16 | void BeforeMapping(XChart &chart, XDataGroup &dataArray) override;
17 | };
18 | } // namespace geom
19 | } // namespace xg
20 |
21 | #endif /* XG_GRAPHICS_GEOM_LINE_H */
22 |
--------------------------------------------------------------------------------
/core/graphics/geom/Path.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GEOM_PATH_H
2 | #define XG_GRAPHICS_GEOM_PATH_H
3 |
4 | #include "Geom.h"
5 |
6 | namespace xg {
7 | namespace geom {
8 |
9 | class Path : public AbstractGeom {
10 | public:
11 | Path(Group *_container, utils::Tracer *tracer) : AbstractGeom(_container, tracer) {
12 | type_ = "path";
13 | shapeType_ = "line";
14 | }
15 | };
16 | } // namespace geom
17 | } // namespace xg
18 |
19 | #endif /* XG_GRAPHICS_GEOM_PATH_H */
20 |
--------------------------------------------------------------------------------
/core/graphics/geom/Point.cpp:
--------------------------------------------------------------------------------
1 | #include "Point.h"
2 | #include "../XChart.h"
3 |
4 | using namespace xg;
5 |
6 | void geom::Point::BeforeMapping(XChart &chart, XDataGroup &dataArray) {
7 | auto &xScale = chart.GetScale(GetXScaleField());
8 | for(std::size_t index = 0; index < dataArray.size(); ++index) {
9 |
10 | auto &groupData = dataArray[index];
11 |
12 | std::size_t start = 0, end = groupData.size() - 1;
13 | if(scale::IsCategory(xScale.GetType())) {
14 | start = fmax(start, xScale.min);
15 | end = fmin(end, xScale.max);
16 | }
17 |
18 | for(std::size_t position = start; position <= end; ++position) {
19 | auto &item = groupData[position];
20 | item._style = this->styleConfig_;
21 | }
22 | }
23 | }
24 |
25 | void geom::Point::Draw(XChart &chart, const XDataArray &groupData, std::size_t start, std::size_t end) const {
26 | for(std::size_t i = start; i <= end; ++i) {
27 | auto &item = groupData[i];
28 | chart.geomShapeFactory_->DrawGeomShape(chart, type_, shapeType_, item, i, i + 1, *this->container_, this->connectNulls_);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/graphics/geom/Point.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GEOM_POINT_H
2 | #define XG_GRAPHICS_GEOM_POINT_H
3 |
4 | #include "Geom.h"
5 |
6 | namespace xg {
7 | class XChart;
8 |
9 | namespace geom {
10 | class Point : public AbstractGeom {
11 | public:
12 | Point(Group *_container, utils::Tracer *tracer) : AbstractGeom(_container, tracer) {
13 | type_ = "point";
14 | sortable_ = true;
15 | this->styleConfig_ = {};
16 | }
17 |
18 | void BeforeMapping(XChart &chart, XDataGroup &dataArray) override;
19 |
20 | void Draw(XChart &chart, const XDataArray &groupData, std::size_t start, std::size_t end) const override;
21 | };
22 | } // namespace geom
23 | } // namespace xg
24 |
25 | #endif // XG_GRAPHICS_GEOM_POINT_H
26 |
--------------------------------------------------------------------------------
/core/graphics/global.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GLOBAL_H
2 | #define XG_GRAPHICS_GLOBAL_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #if defined(__APPLE__)
9 | #include
10 | #endif
11 |
12 | #define GLOBAL_SIZES \
13 | std::vector { 4.f, 10.f }
14 | #define GLOBAL_LINE_DASH \
15 | std::vector { 4, 4 }
16 | #define SNAP_COUNT_ARRAY \
17 | std::vector { 1, 1.2, 1.5, 2, 2.2, 2.4, 2.5, 3, 4, 5, 6, 7.5, 8, 10 }
18 |
19 | namespace xg {
20 | //默认颜色
21 | constexpr const char *GLOBAL_COLORS[] = {"#1890FF", "#2FC25B", "#FACC14", "#223273",
22 | "#8543E0", "#13C2C2", "#3436C7", "#F04864"};
23 | //默认刻度数量
24 | constexpr int DEFAULT_COUNT = 5;
25 |
26 | //默认透明度
27 | constexpr float DEFAULT_OPACITY = NAN;
28 |
29 | #if TARGET_OS_MACCATALYST == 1
30 | constexpr float DEFAULT_FONTSIZE = 17.f;
31 | #else
32 | constexpr float DEFAULT_FONTSIZE = 10.f;
33 | #endif
34 |
35 | } // namespace xg
36 |
37 | #endif // XG_GRAPHICS_GLOBAL_H
38 |
--------------------------------------------------------------------------------
/core/graphics/guide/Background.cpp:
--------------------------------------------------------------------------------
1 | #include "Background.h"
2 | #include "../XChart.h"
3 |
4 | void xg::guide::Background::Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) {
5 | const std::string &xField = chart.GetXScaleField();
6 | std::vector yFields = chart.getYScaleFields();
7 | const std::string yField = yFields[0];
8 |
9 | util::Point leftBottom = this->GetPosition(chart, json::Get(this->config_, "leftBottom"), xField, yField);
10 | util::Point rightTop = this->GetPosition(chart, json::Get(this->config_, "rightTop"), xField, yField);
11 |
12 | std::string color = json::Get(this->config_, "color");
13 | util::Point p = {leftBottom.x, rightTop.y};
14 |
15 | auto rect = xg::make_unique(p, util::Size{fabs(rightTop.x - leftBottom.x), fabs(rightTop.y - leftBottom.y)});
16 | rect->SetFillColor(color);
17 | container->AddElement(std::move(rect));
18 | }
19 |
--------------------------------------------------------------------------------
/core/graphics/guide/Background.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef XG_GRAPHICS_GUIDE_BACKGROUND_H
3 | #define XG_GRAPHICS_GUIDE_BACKGROUND_H
4 |
5 | #include "GuideBase.h"
6 |
7 | namespace xg {
8 | namespace guide {
9 |
10 | class Background : public GuideBase {
11 | public:
12 | Background(nlohmann::json config = {}) : GuideBase("background", MergeDefaultCfg(config)) {}
13 |
14 | void Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) override;
15 | util::BBox GetBBox() override { return bbox_; }
16 |
17 | protected:
18 | static nlohmann::json MergeDefaultCfg(const nlohmann::json &cfg) {
19 | nlohmann::json defaultCfg = {{"color", "#1CAA3DB2"}};
20 | if(cfg.is_object()) {
21 | defaultCfg.merge_patch(cfg);
22 | }
23 | return defaultCfg;
24 | }
25 | };
26 |
27 | } // namespace guide
28 | } // namespace xg
29 |
30 | #endif // XG_GRAPHICS_GUIDE_BACKGROUND_H
31 |
--------------------------------------------------------------------------------
/core/graphics/guide/GuideBase.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GUIDE_BASE_H
2 | #define XG_GRAPHICS_GUIDE_BASE_H
3 |
4 | #include "../canvas/CanvasContext.h"
5 | #include "../shape/Group.h"
6 | #include "../util/BBox.h"
7 | #include "../util/Point.h"
8 | #include "../../nlohmann/json.hpp"
9 |
10 | namespace xg {
11 | class XChart;
12 |
13 | namespace guide {
14 |
15 | class GuideBase {
16 | public:
17 | GuideBase(std::string type, nlohmann::json config = {}) : type_(type), config_(config) {}
18 | virtual ~GuideBase() {}
19 | virtual void
20 | Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) = 0;
21 |
22 | virtual util::BBox GetBBox() { return bbox_; }
23 |
24 | std::string GetType() const noexcept { return this->type_; }
25 |
26 | //是否绘制在最顶层
27 | bool isTop() const noexcept {
28 | if (config_.contains("top")) {
29 | return config_["top"].get();
30 | }
31 | return true;
32 | }
33 |
34 | virtual util::Point GetPosition(XChart &chart, const nlohmann::json &position, const std::string &xField, const std::string &yField);
35 |
36 | protected:
37 | std::string type_ = "";
38 | nlohmann::json config_;
39 | util::BBox bbox_;
40 | };
41 | } // namespace guide
42 | } // namespace xg
43 |
44 | #endif // XG_GRAPHICS_GUIDE_BASE_H
45 |
--------------------------------------------------------------------------------
/core/graphics/guide/Image.h:
--------------------------------------------------------------------------------
1 | //
2 | // Image.hpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2021/9/1.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #ifndef XG_GRAPHICS_GUIDE_IMAGE_H
10 | #define XG_GRAPHICS_GUIDE_IMAGE_H
11 |
12 | #include "GuideBase.h"
13 |
14 | namespace xg {
15 | namespace guide {
16 |
17 | class Image : public GuideBase {
18 | public:
19 | Image(const nlohmann::json &config = {}) : GuideBase("image", MergeDefaultCfg(config)) {}
20 |
21 | void Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) override;
22 |
23 | util::BBox GetBBox() override { return bbox_; }
24 |
25 | protected:
26 | static nlohmann::json MergeDefaultCfg(const nlohmann::json &config) {
27 | nlohmann::json defaultCfg = {
28 | {"margin", {0, 0}}// margin: left & top
29 | };
30 | if(config.is_object()) {
31 | defaultCfg.merge_patch(config);
32 | }
33 | return defaultCfg;
34 | }
35 | };
36 |
37 | } // namespace guide
38 | } // namespace xg
39 |
40 |
41 |
42 | #endif /* Image_h */
43 |
--------------------------------------------------------------------------------
/core/graphics/guide/Line.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GUIDE_LINE_H
2 | #define XG_GRAPHICS_GUIDE_LINE_H
3 |
4 | #include "GuideBase.h"
5 |
6 | namespace xg {
7 | namespace guide {
8 |
9 | class Line : public GuideBase {
10 | public:
11 | Line(nlohmann::json cfg = {}) : GuideBase("line", MergeDefaultCfg(cfg)) {}
12 |
13 | void Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) override;
14 |
15 | util::BBox GetBBox() override { return bbox_; }
16 |
17 | protected:
18 | static nlohmann::json MergeDefaultCfg(const nlohmann::json &config) {
19 | nlohmann::json defaultCfg = {
20 | {"color", "#1890FF"}, {"lineWidth", 1.f}, {"orientation", "horizontal"} // [horizontal, vertical, crossed]
21 | };
22 | if(config.is_object()) {
23 | defaultCfg.merge_patch(config);
24 | }
25 | return defaultCfg;
26 | }
27 | };
28 | } // namespace guide
29 | } // namespace xg
30 |
31 | #endif // XG_GRAPHICS_GUIDE_LINE_H
32 |
--------------------------------------------------------------------------------
/core/graphics/guide/Point.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Circle.cpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2021/9/9.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #include "Point.h"
10 | #include "../XChart.h"
11 | #include "../global.h"
12 | #include "../shape/Circle.h"
13 |
14 | using namespace xg;
15 |
16 | void guide::Point::Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) {
17 | const std::string &xField = chart.GetXScaleField();
18 | std::vector yFields = chart.getYScaleFields();
19 | const std::string &yField = yFields[0];
20 |
21 | util::Point position = this->GetPosition(chart, json::GetArray(this->config_, "position"), xField, yField);
22 | double offsetX = json::GetNumber(config_, "offsetX");
23 | double offsetY = json::GetNumber(config_, "offsetY");
24 | double size = json::GetNumber(config_, "size") * context.GetDevicePixelRatio();
25 | const std::string &color = json::GetString(config_, "fill");
26 |
27 | position.x = position.x + offsetX * context.GetDevicePixelRatio();
28 | position.y = position.y + offsetY * context.GetDevicePixelRatio();
29 |
30 | auto circle = xg::make_unique(position, size, color);
31 | bbox_ = circle->GetBBox(context);
32 | container->AddElement(std::move(circle));
33 | }
34 |
--------------------------------------------------------------------------------
/core/graphics/guide/Point.h:
--------------------------------------------------------------------------------
1 | //
2 | // Circle.hpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2021/9/9.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #ifndef XG_GRAPHICS_GUIDE_POINT_H
10 | #define XG_GRAPHICS_GUIDE_POINT_H
11 |
12 | #include "GuideBase.h"
13 |
14 | namespace xg {
15 | namespace guide {
16 |
17 | class Point : public GuideBase {
18 | public:
19 | Point(const nlohmann::json &config = {}) : GuideBase("point", MergeDefaultCfg(config)) {}
20 |
21 | void Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) override;
22 |
23 | util::BBox GetBBox() override { return bbox_; }
24 |
25 | protected:
26 | static nlohmann::json MergeDefaultCfg(const nlohmann::json &config) {
27 | nlohmann::json defaultCfg = {
28 | {"size", 3}, {"shape", "circle"}, {"fill", GLOBAL_COLORS[0]}, {"offsetX", 0}, {"offsetY", 0},
29 | };
30 | if(config.is_object()) {
31 | defaultCfg.merge_patch(config);
32 | }
33 | return defaultCfg;
34 | }
35 | };
36 | } // namespace guide
37 | }
38 |
39 | #endif /* XG_GRAPHICS_GUIDE_POINT_H */
40 |
--------------------------------------------------------------------------------
/core/graphics/guide/Text.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_GUIDE_TEXT_H
2 | #define XG_GRAPHICS_GUIDE_TEXT_H
3 |
4 | #include "GuideBase.h"
5 |
6 | namespace xg {
7 | namespace guide {
8 | class Text : public GuideBase {
9 | public:
10 | Text(nlohmann::json config = {}) : GuideBase("text", MergeDefaultCfg(config)) {}
11 |
12 | void Render(XChart &chart, shape::Group *container, canvas::CanvasContext &context, const std::vector &dangerRects) override;
13 |
14 | util::BBox GetBBox() override { return bbox_; }
15 |
16 | protected:
17 | static nlohmann::json MergeDefaultCfg(const nlohmann::json &config) {
18 | nlohmann::json defaultCfg = {
19 | {"textColor", "#808080"}, {"textSize", DEFAULT_FONTSIZE}, {"content", ""}, {"margin", {0, 0}}, // margin: left & top
20 | {"textAlign", "start"}, {"textBaseline", "bottom"},
21 | };
22 | if(config.is_object()) {
23 | defaultCfg.merge_patch(config);
24 | }
25 | return defaultCfg;
26 | }
27 | };
28 | } // namespace guide
29 | } // namespace xg
30 |
31 | #endif // XG_GRAPHICS_GUIDE_TEXT_H
32 |
--------------------------------------------------------------------------------
/core/graphics/interaction/InteractionBase.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_EVENT_INTERACTION_BASE_H
2 | #define XG_GRAPHICS_EVENT_INTERACTION_BASE_H
3 |
4 | namespace xg {
5 | class XChart;
6 | namespace interaction {
7 | class InteractionBase {
8 | public:
9 | InteractionBase(XChart *chart) : chart_(chart) {}
10 |
11 | virtual ~InteractionBase() { chart_ = nullptr; }
12 |
13 | protected:
14 | XChart *chart_ = nullptr;
15 | };
16 | } // namespace interaction
17 | } // namespace xg
18 |
19 | #endif // XG_GRAPHICS_EVENT_INTERACTION_BASE_H
20 |
--------------------------------------------------------------------------------
/core/graphics/interaction/Pan.cpp:
--------------------------------------------------------------------------------
1 | #include "Pan.h"
2 | #include "../XChart.h"
3 |
4 | using namespace xg;
5 |
6 | interaction::Pan::Pan(XChart *chart) : InteractionBase(chart) {
7 | this->chart_->eventController_->AddCallback("panstart", XG_MEMBER_CALLBACK_1(interaction::Pan::OnPanStart));
8 | this->chart_->eventController_->AddCallback("pan", XG_MEMBER_CALLBACK_1(interaction::Pan::OnPan));
9 | this->chart_->eventController_->AddCallback("panend", XG_MEMBER_CALLBACK_1(interaction::Pan::onPanEnd));
10 | }
11 |
12 | bool interaction::Pan::OnPanStart(event::Event &event) {
13 | this->chart_->interactionContext_->Start();
14 | return false;
15 | }
16 |
17 | bool interaction::Pan::OnPan(event::Event &event) {
18 | // this->chart_->GetLogTracer()->trace("onPan type: %s direction: %s", event.eventType.data(), event.direction.data());
19 | if(event.direction == "none" || event.direction == "up" || event.direction == "down") {
20 | return false;
21 | }
22 |
23 | // double coordWidth = this->chart_->coord_->GetWidth();
24 | // double ratio = event.deltaX / coordWidth;
25 | return this->chart_->interactionContext_->DoMove(event.deltaX, event.deltaY);
26 | }
27 |
28 | bool interaction::Pan::onPanEnd(event::Event &event) {
29 | this->chart_->interactionContext_->UpdateTicks();
30 | return false;
31 | }
32 |
--------------------------------------------------------------------------------
/core/graphics/interaction/Pan.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_EVENT_INTERACTION_PAN_H
2 | #define XG_GRAPHICS_EVENT_INTERACTION_PAN_H
3 |
4 | #include "InteractionBase.h"
5 | #include "../event/EventController.h"
6 |
7 | namespace xg {
8 | class XChart;
9 | namespace interaction {
10 |
11 | class Pan : public InteractionBase {
12 | public:
13 | Pan(XChart *chart);
14 |
15 | bool OnPanStart(event::Event &event);
16 |
17 | bool OnPan(event::Event &event);
18 |
19 | bool onPanEnd(event::Event &event);
20 | };
21 | } // namespace interaction
22 | } // namespace xg
23 |
24 | #endif // XG_GRAPHICS_EVENT_INTERACTION_PAN_H
25 |
--------------------------------------------------------------------------------
/core/graphics/interaction/Pinch.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_EVENT_INTERACTION_PINCH_H
2 | #define XG_GRAPHICS_EVENT_INTERACTION_PINCH_H
3 |
4 | #include "InteractionBase.h"
5 | #include "../event/EventController.h"
6 |
7 | namespace xg {
8 | class XChart;
9 | namespace interaction {
10 |
11 | class Pinch : public InteractionBase {
12 | public:
13 | Pinch(XChart *chart);
14 |
15 | bool OnPinchStart(event::Event &event);
16 |
17 | bool OnPinch(event::Event &event);
18 |
19 | bool onPinchEnd(event::Event &event);
20 | };
21 | } // namespace interaction
22 | } // namespace xg
23 |
24 | #endif // XG_GRAPHICS_EVENT_INTERACTION_PINCH_H
25 |
--------------------------------------------------------------------------------
/core/graphics/scale/Identity.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SCALE_IDENTITY_H
2 | #define XG_GRAPHICS_SCALE_IDENTITY_H
3 |
4 | #include "Scale.h"
5 |
6 | namespace xg {
7 | namespace scale {
8 | /**
9 | * 常量度量
10 | */
11 | class Identity : public AbstractScale {
12 | public:
13 | Identity(const std::string &_field, const nlohmann::json &_values) : AbstractScale(_field, _values, {}) {
14 | this->ticks = this->CalculateTicks();
15 | }
16 |
17 | ScaleType GetType() const noexcept override { return ScaleType::Identity; }
18 |
19 | void Change(const nlohmann::json &cfg = {}) override {}
20 |
21 | double Scale(const nlohmann::json &key) override {
22 | if(values.size() > 0 && key.is_number() && values[0] == key) {
23 | return key;
24 | }
25 | return this->rangeMin;
26 | }
27 |
28 | nlohmann::json Invert(double key) override {
29 | if(values.size() > 0) {
30 | return values[0];
31 | }
32 | nlohmann::json ret;
33 | return ret;
34 | }
35 |
36 | protected:
37 | nlohmann::json CalculateTicks() override { return values; }
38 | };
39 | } // namespace scale
40 | } // namespace xg
41 |
42 | #endif // XG_GRAPHICS_SCALE_IDENTITY_H
43 |
--------------------------------------------------------------------------------
/core/graphics/scale/TimeCategory.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SCALE_TIME_CAT_H
2 | #define XG_GRAPHICS_SCALE_TIME_CAT_H
3 |
4 | #include
5 | #include "../scale/Category.h"
6 |
7 | namespace xg {
8 | namespace scale {
9 | class TimeCategory : public Category {
10 | public:
11 | TimeCategory(const std::string &_field,
12 | const nlohmann::json &_values,
13 | const nlohmann::json &config,
14 | std::string mask = "HH::mm")
15 | : Category(_field, _values, config), mask(mask) {}
16 |
17 | ScaleType GetType() const noexcept override { return ScaleType::TimeCat; }
18 |
19 | std::string GetTickText(const nlohmann::json &item, XChart *chart) override {
20 | if(item.is_string()) {
21 | return item.get();
22 | } else if(item.is_number()) {
23 | struct tm *p;
24 | time_t t;
25 | t = item.get();
26 | p = gmtime(&t);
27 | char s[100];
28 | strftime(s, 100, "%H:%M", p);
29 | return std::string(s);
30 | } else {
31 | return "";
32 | }
33 | }
34 |
35 | protected:
36 | std::string mask;
37 | };
38 | } // namespace scale
39 | } // namespace xg
40 |
41 | #endif // XG_GRAPHICS_SCALE_TIME_CAT_H
42 |
--------------------------------------------------------------------------------
/core/graphics/scale/continuous/Linear.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Linear.cpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #include "Linear.h"
10 | #include "../../XChart.h"
11 |
12 | using namespace xg::scale;
13 |
14 | std::string Linear::GetTickText(const nlohmann::json &item, XChart *chart) {
15 | if(!this->tickCallbackId.empty() && chart) {
16 | nlohmann::json content{{"content", item.dump()}};
17 | auto rst = xg::json::ParseString((chart->InvokeFunction(this->tickCallbackId, content.dump())));
18 | if(rst.is_object() && rst.contains("content")) {
19 | return rst["content"];
20 | }
21 | }
22 |
23 | // 处理 TickText 数值精度
24 | if(item.is_string()) {
25 | return item.get();
26 | } else if(item.is_number_integer()) {
27 | return std::to_string(item.get());
28 | } else if(item.is_number_float()) {
29 | float val = item.get();
30 | if(fabs(val) < XG_EPS) {
31 | return "0";
32 | }
33 | std::stringstream ss;
34 | ss << std::fixed << std::setprecision(precision) << val;
35 | return ss.str();
36 | } else {
37 | return ""; // TODO get Tick text from callback
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/graphics/shape/Area.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SHAPE_AREA_H
2 | #define XG_GRAPHICS_SHAPE_AREA_H
3 |
4 | #include "Shape.h"
5 |
6 | namespace xg {
7 | namespace shape {
8 |
9 | class Area : public Shape {
10 | public:
11 | Area(const vector &topPoints, const vector &bottomPoints, const bool smooth);
12 |
13 | BBox CalculateBox(canvas::CanvasContext &context) const override;
14 |
15 | protected:
16 | void CreatePath(canvas::CanvasContext &context) const override;
17 |
18 | public:
19 | vector topPoints_;
20 | vector bottomPoints_;
21 | vector mergePoints_;
22 | bool smooth_ = false;
23 | };
24 |
25 | } // namespace shape
26 | } // namespace xg
27 |
28 | #endif /* XG_GRAPHICS_SHAPE_AREA_H */
29 |
--------------------------------------------------------------------------------
/core/graphics/shape/Circle.cpp:
--------------------------------------------------------------------------------
1 | #include "Circle.h"
2 |
3 | void xg::shape::Circle::CreatePath(canvas::CanvasContext &context) const {
4 | context.BeginPath();
5 | context.Arc(point_.x, point_.y, radius_, 0.0, 2 * M_PI);
6 | context.ClosePath();
7 | }
8 |
9 | BBox xg::shape::Circle::CalculateBox(canvas::CanvasContext &context) const {
10 | BBox bbox;
11 | bbox.minX = point_.x - radius_;
12 | bbox.maxX = point_.x + radius_;
13 | bbox.minY = point_.y - radius_;
14 | bbox.maxY = point_.y + radius_;
15 | bbox.x = point_.x;
16 | bbox.y = point_.y;
17 | return bbox;
18 | }
19 |
--------------------------------------------------------------------------------
/core/graphics/shape/Circle.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SHAPE_CIRCLE_H
2 | #define XG_GRAPHICS_SHAPE_CIRCLE_H
3 |
4 | #include "Shape.h"
5 |
6 | namespace xg {
7 | namespace shape {
8 |
9 | class Circle : public Shape {
10 | public:
11 | Circle(const util::Point ¢er, const float radius) : radius_(radius) {
12 | type_ = "circle";
13 | point_ = center;
14 | }
15 |
16 | Circle(const util::Point ¢er, const float radius, const std::string &fill) : radius_(radius) {
17 | type_ = "circle";
18 | point_ = center;
19 |
20 | SetFillColor(fill);
21 | }
22 |
23 | BBox CalculateBox(canvas::CanvasContext &context) const override;
24 |
25 | protected:
26 | void CreatePath(canvas::CanvasContext &context) const override;
27 |
28 | public:
29 | float radius_;
30 | };
31 |
32 | } // namespace shape
33 | } // namespace xg
34 |
35 | #endif /* XG_GRAPHICS_SHAPE_CIRCLE_H */
36 |
--------------------------------------------------------------------------------
/core/graphics/shape/Line.cpp:
--------------------------------------------------------------------------------
1 | #include "Line.h"
2 |
3 | xg::shape::Line::Line(const Point &pt1, const Point &pt2) {
4 | p1_ = pt1;
5 | p2_ = pt2;
6 | type_ = "line";
7 | }
8 |
9 | xg::shape::Line::Line(const Point &pt1, const Point &pt2, const float lineWidth, const string &strokeColor) : Shape() {
10 | p1_ = pt1;
11 | p2_ = pt2;
12 | lineWidth_ = lineWidth;
13 | strokeStyle_ = canvas::CanvasFillStrokeStyle(strokeColor);
14 | type_ = "line";
15 | }
16 |
17 | void xg::shape::Line::CreatePath(canvas::CanvasContext &context) const {
18 | context.BeginPath();
19 | context.MoveTo(p1_.x + this->point_.x, p1_.y + this->point_.y);
20 | context.LineTo(p2_.x + this->point_.x, p2_.y + this->point_.y);
21 | }
22 |
23 | BBox xg::shape::Line::CalculateBox(canvas::CanvasContext &context) const {
24 | return BBoxUtil::GetBBoxFromLine(p1_.x + this->point_.x, p1_.y + this->point_.y, p2_.x + this->point_.x,
25 | p2_.y + this->point_.y, lineWidth_);
26 | }
27 |
--------------------------------------------------------------------------------
/core/graphics/shape/Line.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SHAPE_LINE_H
2 | #define XG_GRAPHICS_SHAPE_LINE_H
3 |
4 | #include "Shape.h"
5 |
6 | namespace xg {
7 | namespace shape {
8 |
9 | class Line : public Shape {
10 | public:
11 | Line(const util::Point &, const util::Point &);
12 | Line(const util::Point &, const util::Point &, const float lineWidth, const string &strokeColor);
13 |
14 | BBox CalculateBox(canvas::CanvasContext &context) const override;
15 |
16 | protected:
17 | void CreatePath(canvas::CanvasContext &context) const override;
18 |
19 | public:
20 | util::Point p1_, p2_;
21 | };
22 |
23 | } // namespace shape
24 | } // namespace xg
25 |
26 | #endif /* XG_GRAPHICS_SHAPE_LINE_H */
27 |
--------------------------------------------------------------------------------
/core/graphics/shape/Marker.cpp:
--------------------------------------------------------------------------------
1 | #include "Marker.h"
2 |
3 | void xg::shape::Marker::CreatePath(canvas::CanvasContext &context) const {
4 | context.BeginPath();
5 | if(symbol_ == "circle") {
6 | context.Arc(point_.x, point_.y, radius_, 0.0, 2 * M_PI, false);
7 | }
8 | if(symbol_ == "square") {
9 | context.MoveTo(point_.x - radius_, point_.y - radius_);
10 | context.LineTo(point_.x + radius_, point_.y - radius_);
11 | context.LineTo(point_.x + radius_, point_.y + radius_);
12 | context.LineTo(point_.x - radius_, point_.y + radius_);
13 | }
14 | context.ClosePath();
15 | }
16 |
17 | BBox xg::shape::Marker::CalculateBox(canvas::CanvasContext &context) const {
18 | BBox bbox;
19 | bbox.minX = point_.x - radius_;
20 | bbox.maxX = point_.x + radius_;
21 | bbox.minY = point_.y - radius_;
22 | bbox.maxY = point_.y + radius_;
23 | bbox.x = point_.x;
24 | bbox.y = point_.y;
25 | return bbox;
26 | }
27 |
--------------------------------------------------------------------------------
/core/graphics/shape/Marker.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SHAPE_MARKER_H
2 | #define XG_GRAPHICS_SHAPE_MARKER_H
3 |
4 | #include "Shape.h"
5 |
6 | namespace xg {
7 | namespace shape {
8 |
9 | class Marker : public Shape {
10 | public:
11 | Marker(const util::Point ¢er, const float radius, const std::string &fill, const std::string &symbol)
12 | : radius_(radius), symbol_(symbol) {
13 | type_ = "marker";
14 | point_ = center;
15 | SetFillColor(fill);
16 | }
17 |
18 | BBox CalculateBox(canvas::CanvasContext &context) const override;
19 |
20 | protected:
21 | void CreatePath(canvas::CanvasContext &context) const override;
22 |
23 | public:
24 | float radius_;
25 | std::string symbol_ = "circle";
26 | };
27 |
28 | } // namespace shape
29 | } // namespace xg
30 |
31 | #endif /* XG_GRAPHICS_SHAPE_MARKER_H */
32 |
--------------------------------------------------------------------------------
/core/graphics/shape/Polyline.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SHAPE_POLYLINE_H
2 | #define XG_GRAPHICS_SHAPE_POLYLINE_H
3 |
4 | #include "Shape.h"
5 |
6 | using namespace xg::util;
7 |
8 | namespace xg {
9 | namespace shape {
10 |
11 | class Polyline : public Shape {
12 | public:
13 | Polyline(const float lineWidth, const vector &, const bool smooth);
14 |
15 | Polyline(const float lineWidth, const vector &, const std::string &strokeColor, const std::string &fillColor, const bool smooth);
16 |
17 | BBox CalculateBox(canvas::CanvasContext &context) const override;
18 |
19 | void SetDashLine(const std::vector ¶ms) { this->dash_ = params; }
20 |
21 | protected:
22 | void CreatePath(canvas::CanvasContext &context) const override;
23 |
24 | private:
25 | vector points_;
26 | bool smooth_ = false;
27 |
28 | std::vector dash_;
29 | };
30 |
31 | } // namespace shape
32 | } // namespace xg
33 |
34 | #endif /* XG_GRAPHICS_SHAPE_POLYLINE_H */
35 |
--------------------------------------------------------------------------------
/core/graphics/shape/Shape.cpp:
--------------------------------------------------------------------------------
1 | #include "Shape.h"
2 |
3 | xg::shape::Shape::Shape() : Element() { isShape_ = true; }
4 |
5 | void xg::shape::Shape::DrawInner(canvas::CanvasContext &context) const {
6 | float originOpacity = context.GlobalAlpha();
7 | //coregraphics context path和fill必须配对 path和stroke必须配对
8 | //在既有fill又有stroke的case 会浪费一点性能
9 |
10 | // fill case
11 | if(HasFill()) {
12 | CreatePath(context);
13 | if(!std::isnan(fillOpacity_)) {
14 | context.SetGlobalAlpha(fillOpacity_);
15 | context.Fill();
16 | context.SetGlobalAlpha(originOpacity);
17 | } else {
18 | context.Fill();
19 | }
20 | }
21 |
22 | // stroke case
23 | if(HasStroke() && lineWidth_ > 0) {
24 | CreatePath(context);
25 | if(!std::isnan(strokeOpacity_)) {
26 | context.SetGlobalAlpha(strokeOpacity_);
27 | context.Stroke();
28 | context.SetGlobalAlpha(originOpacity);
29 | } else {
30 | context.Stroke();
31 | }
32 | }
33 | }
34 |
35 | const BBox &xg::shape::Shape::GetBBox(canvas::CanvasContext &context) {
36 | if(std::isnan(bbox_.minX)) {
37 | bbox_ = CalculateBox(context);
38 | }
39 | return bbox_;
40 | }
41 |
--------------------------------------------------------------------------------
/core/graphics/shape/Shape.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_SHAPE_SHAPE_H
2 | #define XG_GRAPHICS_SHAPE_SHAPE_H
3 |
4 | #include "Element.h"
5 |
6 | namespace xg {
7 | namespace shape {
8 | class Group;
9 | class Shape : public Element {
10 | friend Group;
11 |
12 | public:
13 | Shape();
14 |
15 | virtual ~Shape() override {}
16 |
17 | /// 获取包围盒,同一个shape只会一算一次
18 | /// @param context 上下文
19 | const BBox &GetBBox(canvas::CanvasContext &context) override;
20 |
21 | /// 包围盒计算,每次都会计算
22 | virtual BBox CalculateBox(canvas::CanvasContext &context) const override { return {0, 0, 0, 0, 0, 0}; }
23 |
24 | // 各元素独立实现,用于更新属性值
25 | virtual void UpdateAttribute(std::string attrName, double val) {}
26 | virtual void UpdateAttribute(std::string attrName, const std::string &val) {}
27 |
28 | protected:
29 | virtual void DrawInner(canvas::CanvasContext &context) const override;
30 |
31 | /// 调用canvas生成绘制指令
32 | /// @param context canvas的context
33 | virtual void CreatePath(canvas::CanvasContext &context) const {};
34 | };
35 |
36 | } // namespace shape
37 | } // namespace xg
38 |
39 | #endif /* XG_GRAPHICS_SHAPE_SHAPE_H */
40 |
--------------------------------------------------------------------------------
/core/graphics/util/Color.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_GRAPHICS_UTIL_COLOR_H
2 | #define XG_GRAPHICS_UTIL_COLOR_H
3 |
4 | #include
5 | #include
6 | #include "../../nlohmann/json.hpp"
7 | #include "../canvas/CanvasFillStrokeStyle.h"
8 | #include "../global.h"
9 |
10 | namespace xg {
11 | namespace util {
12 |
13 | canvas::CanvasFillStrokeStyle ColorParser(const nlohmann::json &color);
14 | canvas::CanvasFillStrokeStyle ColorParser(const nlohmann::json &data, const std::string &key);
15 | float OpacityParserString(const std::string &color);
16 | float OpacityParser(const nlohmann::json &color);
17 | float OpacityParser(const nlohmann::json &data, const std::string &key);
18 |
19 | } // namespace util
20 | } // namespace xg
21 |
22 | #endif // XG_GRAPHICS_UTIL_COLOR_H
23 |
--------------------------------------------------------------------------------
/core/graphics/util/json_data.h:
--------------------------------------------------------------------------------
1 | //
2 | // json_data.h
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | //
7 |
8 | #ifndef XG_GRAPHICS_UTIL_JSON_DATA
9 | #define XG_GRAPHICS_UTIL_JSON_DATA
10 |
11 | #include
12 | #include
13 | #include "Point.h"
14 |
15 | namespace xg {
16 | namespace util {
17 | struct XData final {
18 | nlohmann::json::const_pointer data;
19 | double _x = NAN, _y = NAN;
20 | std::vector _y0;
21 | nlohmann::json _style;
22 | std::string _color, _shape, _adjust;
23 | double _size = NAN;
24 |
25 | //for interval and candle
26 | nlohmann::json _points, _tag, _rect, _line, _state;
27 | bool _beforeMapped = false;
28 |
29 | //for adjust
30 | std::vector adjust;
31 |
32 | //for dodge
33 | //index 0 for xfiled, index 1 for yfield
34 | std::vector dodge;
35 | };
36 |
37 | using XDataArray = std::vector;
38 | using XDataGroup = std::vector>;
39 | }
40 | }
41 |
42 |
43 | #endif /* XG_GRAPHICS_UTIL_JSON_DATA */
44 |
--------------------------------------------------------------------------------
/core/ios/BridgeRailingIOS.h:
--------------------------------------------------------------------------------
1 | //
2 | // F2CommonIOSPlatform.hpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #if defined(__APPLE__)
10 |
11 | #ifndef XG_BRIDGE_RAILINGIOS
12 | #define XG_BRIDGE_RAILINGIOS
13 |
14 | #include "AbstractBridgeRailing.h"
15 |
16 | namespace xg {
17 | namespace bridge {
18 |
19 | class BridgeRailingIOS final : public AbstractBridgeRailing {
20 | public:
21 | ///传入view,在这里是UIView的指针
22 | BridgeRailingIOS(void *view);
23 | ~BridgeRailingIOS();
24 |
25 | void PlayAnimation(const std::string ¶ms) override;
26 |
27 | void Swap() override;
28 |
29 | long GetTimezoneOffset(const std::string &timezoneName) override;
30 |
31 | std::string FormatTime(const std::string &value, const std::string &timezoneName, const std::string ×tampFormatter) override;
32 |
33 | inline void SetCanvasContext(void *context) override { context_ = context; }
34 | inline void *GetCanvasContext() override { return context_; }
35 | private:
36 | void *view_ = nullptr;
37 | void *context_ = nullptr;
38 | void *proxy_ = nullptr;
39 | };
40 | }
41 | }
42 |
43 | #endif /* XG_BRIDGE_RAILINGIOS */
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/core/ios/F2Logger.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_F2_NATIVE_F2LOGGER_H
2 | #define XG_F2_NATIVE_F2LOGGER_H
3 |
4 | #include
5 | #include
6 |
7 | namespace xg {
8 | namespace ios {
9 |
10 | void InnerLog(int level, const std::string &traceId, const char *fmt, ...);
11 |
12 | }
13 | }
14 |
15 | #define F2_LOG_INFO 1
16 | #define F2_LOG_WARN 2
17 | #define F2_LOG_ERROR 3
18 |
19 | #define F2_LOG_I(traceId, ...) ((void)xg::ios::InnerLog(F2_LOG_INFO, traceId, __VA_ARGS__))
20 | #define F2_LOG_W(traceId, ...) ((void)xg::ios::InnerLog(F2_LOG_WARN, traceId, __VA_ARGS__))
21 | #define F2_LOG_E(traceId, ...) ((void)xg::ios::InnerLog(F2_LOG_ERROR, traceId, __VA_ARGS__))
22 |
23 | #endif /* XG_F2_NATIVE_F2LOGGER_H */
24 |
--------------------------------------------------------------------------------
/core/ios/F2Logger.mm:
--------------------------------------------------------------------------------
1 | #include "F2Logger.h"
2 | #include "../utils/xtime.h"
3 | #if defined(PRODUCT_WALLET)
4 | #include
5 | #endif
6 |
7 | namespace xg {
8 | namespace ios {
9 |
10 | void InnerLog(int level, const std::string &traceId, const char *fmt, ...) {
11 | std::string _tag = "F2Native|" + traceId;
12 |
13 | char msg[2048] = {0};
14 | va_list args;
15 | va_start(args, fmt);
16 | vsnprintf(msg, 2048, fmt, args);
17 | va_end(args);
18 |
19 | #if defined(PRODUCT_WALLET)
20 |
21 | #if defined(DEBUG)
22 | printf("%s %.0lf %s\n", _tag.c_str(), CFAbsoluteTimeGetCurrent() * 1000, msg);
23 | #else
24 | NSString *tagStr = [NSString stringWithUTF8String:_tag.c_str()];
25 | NSString *msgStr = [NSString stringWithUTF8String:msg];
26 | APLogInfo(tagStr, @"%@", msgStr);
27 | #endif
28 |
29 | #else
30 | printf("%s %.0lld %s\n", _tag.c_str(), xg::CurrentTimestampAtMM(), msg);
31 | #endif
32 | }
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/core/utils/StringUtil.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #ifndef XG_UTILS_STRING_H
7 | #define XG_UTILS_STRING_H
8 |
9 | class StringUtil final {
10 | public:
11 | static void Split(const std::string &s, std::vector &sv, const char delim = ' ') {
12 | sv.clear();
13 | std::istringstream iss(s);
14 | std::string temp;
15 |
16 | while(std::getline(iss, temp, delim)) {
17 | sv.emplace_back(std::move(temp));
18 | }
19 | return;
20 | }
21 |
22 | static std::vector ParseFields(const std::string &field) {
23 | if(field.find('*') != field.npos) {
24 | std::vector v;
25 | StringUtil::Split(field, v, '*');
26 | return v;
27 | } else {
28 | return {field};
29 | }
30 | }
31 | };
32 |
33 | #endif /* XG_UTILS_STRING_H */
34 |
--------------------------------------------------------------------------------
/core/utils/Tracer.cpp:
--------------------------------------------------------------------------------
1 | #include "Tracer.h"
2 | #include
3 |
4 | #if defined(__APPLE__)
5 | #include
6 | #endif
7 |
8 | void utils::Tracer::trace(const char *fmt, ...) {
9 | char buffer[4096] = {0};
10 |
11 | va_list args;
12 | va_start(args, fmt);
13 | vsnprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer) - 1, fmt, args);
14 | va_end(args);
15 |
16 | #ifdef ANDROID
17 | F2_LOG_I(this->name_.data(), "%s", buffer);
18 | #elif defined(TARGET_OS_IPHONE)
19 | F2_LOG_I(this->name_.data(), "%s", buffer);
20 | #else
21 | printf("%s %s\n", this->name_.data(), buffer);
22 | #endif
23 | }
24 |
--------------------------------------------------------------------------------
/core/utils/Tracer.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #if defined(ANDROID)
4 | #include "android/F2NativeJNI.h"
5 | #endif
6 |
7 | #if defined(__APPLE__)
8 | #include "../ios/F2Logger.h"
9 | #endif
10 |
11 | #ifndef X_CHART_UTILS_TRACER_H
12 | #define X_CHART_UTILS_TRACER_H
13 | namespace utils {
14 | class Tracer {
15 | public:
16 | Tracer(const std::string &name) : name_(name) {}
17 |
18 | void trace(const char *fmt, ...);
19 |
20 | private:
21 | std::string name_;
22 | };
23 | } // namespace utils
24 |
25 | #endif // X_CHART_UTILS_TRACER_H
26 |
--------------------------------------------------------------------------------
/core/utils/common.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // common.cpp
3 | // Pods
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | //
7 |
8 | #include "common.h"
9 |
10 | bool xg::IsZero(double val) noexcept { return (fabs(val) < XG_EPS); }
11 | bool xg::IsEqualDeviation (double v1, double v2, double deviation) noexcept { return fabs(v1 - v2) < deviation; }
12 | bool xg::IsEqual(double v1, double v2) noexcept { return IsEqualDeviation(v1, v2, XG_EPS); }
13 |
--------------------------------------------------------------------------------
/core/utils/common.h:
--------------------------------------------------------------------------------
1 | #ifndef XG_UTIL_COMMON
2 | #define XG_UTIL_COMMON
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #ifdef DEBUG
11 | #define XG_ASSERT assert
12 | #else
13 | #define XG_ASSERT
14 | #endif
15 |
16 | #define XG_EPS DBL_EPSILON
17 |
18 | namespace xg {
19 |
20 | template std::unique_ptr make_unique(Args &&... args) {
21 | return std::unique_ptr(new T(std::forward(args)...));
22 | }
23 |
24 | bool IsZero(double val) noexcept;
25 | bool IsEqualDeviation (double v1, double v2, double deviation) noexcept;
26 | bool IsEqual(double v1, double v2) noexcept;
27 | } // namespace xg
28 |
29 | #endif /* XG_UTIL_COMMON */
30 |
--------------------------------------------------------------------------------
/core/webassembly/CanvasImage.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // CanvasImage.cpp
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2022/1/17.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #ifdef __EMSCRIPTEN__
10 |
11 | #include "graphics/canvas/CanvasImage.h"
12 |
13 | using namespace xg;
14 | using namespace xg::canvas;
15 |
16 | CanvasImage::~CanvasImage() {
17 | if(image_) {
18 | image_ = nullptr;
19 | }
20 | }
21 |
22 | void CanvasImage::OnLoad(std::function finished) {
23 | //通过JNI方法调用Java下载
24 | }
25 |
26 | float CanvasImage::GetWidth() { return 0; }
27 |
28 | float CanvasImage::GetHeight() { return 0; }
29 |
30 | #endif
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos-kotlin/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/androidTest/java/com/antgroup/antv/samples/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.samples;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.InstrumentationRegistry;
6 | import androidx.test.runner.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getTargetContext();
24 |
25 | assertEquals("com.antgroup.antv.f2", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_1688.json:
--------------------------------------------------------------------------------
1 | [{
2 | "date": "3.1",
3 | "value": 62
4 | }, {
5 | "date": "3.14",
6 | "value": 62
7 | }, {
8 | "date": "3.19",
9 | "value": 62
10 | }, {
11 | "date": "3.24",
12 | "value": 63
13 | }, {
14 | "date": "3.29",
15 | "value": 62
16 | }, {
17 | "date": "4.03",
18 | "value": 62
19 | }, {
20 | "date": "4.08",
21 | "value": 62
22 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_basePie.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "芳华",
3 | "percent": 0.4,
4 | "a": "1"
5 | }, {
6 | "name": "妖猫传",
7 | "percent": 0.2,
8 | "a": "1"
9 | }, {
10 | "name": "机器之血",
11 | "percent": 0.18,
12 | "a": "1"
13 | }, {
14 | "name": "心理罪",
15 | "percent": 0.15,
16 | "a": "1"
17 | }, {
18 | "name": "寻梦环游记",
19 | "percent": 0.05,
20 | "a": "1"
21 | }, {
22 | "name": "其他",
23 | "percent": 0.12,
24 | "a": "1"
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_multiIntervalsChart.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "London",
3 | "月份": "Jan.",
4 | "月均降雨量": 18.9
5 | }, {
6 | "name": "London",
7 | "月份": "Feb.",
8 | "月均降雨量": 28.8
9 | }, {
10 | "name": "London",
11 | "月份": "Mar.",
12 | "月均降雨量": 39.3
13 | }, {
14 | "name": "London",
15 | "月份": "Apr.",
16 | "月均降雨量": 81.4
17 | }, {
18 | "name": "London",
19 | "月份": "May.",
20 | "月均降雨量": 47
21 | }, {
22 | "name": "London",
23 | "月份": "Jun.",
24 | "月均降雨量": 20.3
25 | }, {
26 | "name": "London",
27 | "月份": "Jul.",
28 | "月均降雨量": 24
29 | }, {
30 | "name": "London",
31 | "月份": "Aug.",
32 | "月均降雨量": 35.6
33 | }, {
34 | "name": "Berlin",
35 | "月份": "Jan.",
36 | "月均降雨量": 12.4
37 | }, {
38 | "name": "Berlin",
39 | "月份": "Feb.",
40 | "月均降雨量": 23.2
41 | }, {
42 | "name": "Berlin",
43 | "月份": "Mar.",
44 | "月均降雨量": 34.5
45 | }, {
46 | "name": "Berlin",
47 | "月份": "Apr.",
48 | "月均降雨量": 99.7
49 | }, {
50 | "name": "Berlin",
51 | "月份": "May.",
52 | "月均降雨量": 52.6
53 | }, {
54 | "name": "Berlin",
55 | "月份": "Jun.",
56 | "月均降雨量": 35.5
57 | }, {
58 | "name": "Berlin",
59 | "月份": "Jul.",
60 | "月均降雨量": 37.4
61 | }, {
62 | "name": "Berlin",
63 | "月份": "Aug.",
64 | "月均降雨量": 42.4
65 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_radarArea.json:
--------------------------------------------------------------------------------
1 | [{
2 | "item": "Design",
3 | "user": "用户 A",
4 | "score": 70
5 | }, {
6 | "item": "Design",
7 | "user": "用户 B",
8 | "score": 30
9 | }, {
10 | "item": "Development",
11 | "user": "用户 A",
12 | "score": 60
13 | }, {
14 | "item": "Development",
15 | "user": "用户 B",
16 | "score": 70
17 | }, {
18 | "item": "Marketing",
19 | "user": "用户 A",
20 | "score": 50
21 | }, {
22 | "item": "Marketing",
23 | "user": "用户 B",
24 | "score": 60
25 | }, {
26 | "item": "Users",
27 | "user": "用户 A",
28 | "score": 40
29 | }, {
30 | "item": "Users",
31 | "user": "用户 B",
32 | "score": 50
33 | }, {
34 | "item": "Test",
35 | "user": "用户 A",
36 | "score": 60
37 | }, {
38 | "item": "Test",
39 | "user": "用户 B",
40 | "score": 70
41 | }, {
42 | "item": "Language",
43 | "user": "用户 A",
44 | "score": 70
45 | }, {
46 | "item": "Language",
47 | "user": "用户 B",
48 | "score": 50
49 | }, {
50 | "item": "Technology",
51 | "user": "用户 A",
52 | "score": 70
53 | }, {
54 | "item": "Technology",
55 | "user": "用户 B",
56 | "score": 40
57 | }, {
58 | "item": "Support",
59 | "user": "用户 A",
60 | "score": 60
61 | }, {
62 | "item": "Support",
63 | "user": "用户 B",
64 | "score": 40
65 | }]
66 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_sectionInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "x": "分类一",
3 | "y": [ 76, 100 ]
4 | }, {
5 | "x": "分类二",
6 | "y": [ 56, 108 ]
7 | }, {
8 | "x": "分类三",
9 | "y": [ 38, 129 ]
10 | }, {
11 | "x": "分类四",
12 | "y": [ 58, 155 ]
13 | }, {
14 | "x": "分类五",
15 | "y": [ 45, 120 ]
16 | }, {
17 | "x": "分类六",
18 | "y": [ 23, 99 ]
19 | }, {
20 | "x": "分类七",
21 | "y": [ 18, 56 ]
22 | }, {
23 | "x": "分类八",
24 | "y": [ 18, 34 ]
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_singleAreaChart.json:
--------------------------------------------------------------------------------
1 | [{
2 | "time": "Jan.",
3 | "tem": 1000
4 | }, {
5 | "time": "Feb.",
6 | "tem": 2200
7 | }, {
8 | "time": "Mar.",
9 | "tem": 2000
10 | }, {
11 | "time": "Apr.",
12 | "tem": 2600
13 | }, {
14 | "time": "May.",
15 | "tem": 2000
16 | }, {
17 | "time": "Jun.",
18 | "tem": 2600
19 | }, {
20 | "time": "Jul.",
21 | "tem": 2800
22 | }, {
23 | "time": "Aug.",
24 | "tem": 2000
25 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_singleAreaChart_2.json:
--------------------------------------------------------------------------------
1 | [{
2 | "month": "Jan.",
3 | "value": 6.06
4 | }, {
5 | "month": "Feb.",
6 | "value": 82.2
7 | }, {
8 | "month": "Mar.",
9 | "value": -22.11
10 | }, {
11 | "month": "Apr.",
12 | "value": 21.53
13 | }, {
14 | "month": "May.",
15 | "value": -21.74
16 | }, {
17 | "month": "Jun.",
18 | "value": 73.61
19 | }, {
20 | "month": "Jul.",
21 | "value": 53.75
22 | }, {
23 | "month": "Aug.",
24 | "value": 60.32
25 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_singleIntervalChart.json:
--------------------------------------------------------------------------------
1 | [{
2 | "year": "1950",
3 | "sales": 29
4 | }, {
5 | "year": "1951",
6 | "sales": 30
7 | }, {
8 | "year": "1952",
9 | "sales": 31
10 | }, {
11 | "year": "1953",
12 | "sales": 32
13 | }, {
14 | "year": "1954",
15 | "sales": 33
16 | }, {
17 | "year": "1955",
18 | "sales": 34
19 | }, {
20 | "year": "1956",
21 | "sales": 35
22 | }, {
23 | "year": "1957",
24 | "sales": 36
25 | }, {
26 | "year": "1958",
27 | "sales": 37
28 | }, {
29 | "year": "1959",
30 | "sales": 38
31 | }, {
32 | "year": "1960",
33 | "sales": 29
34 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_singleIntervalChart_2.json:
--------------------------------------------------------------------------------
1 | [{
2 | "genre": "Sports",
3 | "sold": 275
4 | }, {
5 | "genre": "Strategy",
6 | "sold": 115
7 | }, {
8 | "genre": "Action",
9 | "sold": 120
10 | }, {
11 | "genre": "Shooter",
12 | "sold": 350
13 | }, {
14 | "genre": "Other",
15 | "sold": 150
16 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/mockData_trendChart_flags.json:
--------------------------------------------------------------------------------
1 | [{
2 | "content": "HIT电池",
3 | "position": [1608687000000, 3365.65]
4 | }, {
5 | "content": "煤炭开采",
6 | "position": [1608688920000, 3366.13]
7 | }, {
8 | "content": "白酒",
9 | "position": [1608690420000, 3376.52]
10 | }, {
11 | "content": "光伏",
12 | "position": [1608691680000, 3375.87]
13 | }, {
14 | "content": "证券",
15 | "position": [1608693420000, 3388.95]
16 | }, {
17 | "content": "航空装备",
18 | "position": [1608700080000, 3389.64]
19 | }, {
20 | "content": "白酒",
21 | "position": [1608702720000, 3371.69]
22 | }, {
23 | "content": "黄酒",
24 | "position": [1608706080000, 3378.72]
25 | }]
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/assets/wallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos-kotlin/src/main/assets/wallet.png
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/java/com/antgroup/antv/f2/kotlinsamples/ChartModel.kt:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2.kotlinsamples
2 |
3 | import com.antgroup.antv.f2.F2CanvasView
4 | import java.io.Serializable
5 |
6 | /**
7 | * @author weiqing.tang
8 | * @date 2022-06-20
9 | */
10 | class ChartModel : Serializable {
11 | @JvmField
12 | var title: String
13 | @JvmField
14 | var adapterClass: Class
15 | var horizontal = false
16 |
17 | constructor(title: String, adapterClass: Class) {
18 | this.title = title
19 | this.adapterClass = adapterClass
20 | }
21 |
22 | constructor(
23 | title: String,
24 | adapterClass: Class,
25 | horizontal: Boolean
26 | ) {
27 | this.title = title
28 | this.adapterClass = adapterClass
29 | this.horizontal = horizontal
30 | }
31 | }
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/java/com/antgroup/antv/f2/kotlinsamples/Utils.kt:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2.kotlinsamples
2 |
3 | import android.content.Context
4 | import java.io.ByteArrayOutputStream
5 | import java.io.IOException
6 |
7 | /**
8 | * @author weiqing.tang
9 | * @date 2022-06-20
10 | */
11 | object Utils {
12 | @JvmStatic
13 | fun loadAssetFile(context: Context, assetFile: String?): String? {
14 | try {
15 | val `is` = context.assets.open(assetFile)
16 | val buf = ByteArray(1024 * 500)
17 | val output = ByteArrayOutputStream()
18 | var size = 0
19 | while (`is`.read(buf, 0, buf.size).also { size = it } >= 0) {
20 | output.write(buf, 0, size)
21 | }
22 | return String(output.toByteArray())
23 | } catch (e: IOException) {
24 | }
25 | return null
26 | }
27 | }
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/jniLibs/arm64-v8a/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos-kotlin/src/main/jniLibs/arm64-v8a/libc++_shared.so
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/jniLibs/armeabi-v7a/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos-kotlin/src/main/jniLibs/armeabi-v7a/libc++_shared.so
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos-kotlin/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/layout/activity_sample.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/layout/activity_sample_horizontal.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/layout/activity_stock_time_sharing.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/layout/layout_chart_canvasview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
25 |
26 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/layout/layout_chart_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
17 |
18 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
4 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | F2Native
3 | BridgeActivity
4 | SampleActivity
5 | ChartListActivity
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/demos/android/demos-kotlin/src/test/java/com/antgroup/antv/samples/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.samples
2 |
3 | import org.junit.Assert
4 | import org.junit.Test
5 |
6 | /**
7 | * Example local unit test, which will execute on the development machine (host).
8 | *
9 | * @see [Testing documentation](http://d.android.com/tools/testing)
10 | */
11 | class ExampleUnitTest {
12 | @Test
13 | fun addition_isCorrect() {
14 | Assert.assertEquals(4, (2 + 2).toLong())
15 | }
16 | }
--------------------------------------------------------------------------------
/demos/android/demos/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/demos/android/demos/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/demos/android/demos/src/androidTest/java/com/antgroup/antv/samples/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.samples;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.InstrumentationRegistry;
6 | import androidx.test.runner.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getTargetContext();
24 |
25 | assertEquals("com.antgroup.antv.f2", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_1688.json:
--------------------------------------------------------------------------------
1 | [{
2 | "date": "3.1",
3 | "value": 62
4 | }, {
5 | "date": "3.14",
6 | "value": 62
7 | }, {
8 | "date": "3.19",
9 | "value": 62
10 | }, {
11 | "date": "3.24",
12 | "value": 63
13 | }, {
14 | "date": "3.29",
15 | "value": 62
16 | }, {
17 | "date": "4.03",
18 | "value": 62
19 | }, {
20 | "date": "4.08",
21 | "value": 62
22 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_basePie.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "芳华",
3 | "percent": 0.4,
4 | "a": "1"
5 | }, {
6 | "name": "妖猫传",
7 | "percent": 0.2,
8 | "a": "1"
9 | }, {
10 | "name": "机器之血",
11 | "percent": 0.18,
12 | "a": "1"
13 | }, {
14 | "name": "心理罪",
15 | "percent": 0.15,
16 | "a": "1"
17 | }, {
18 | "name": "寻梦环游记",
19 | "percent": 0.05,
20 | "a": "1"
21 | }, {
22 | "name": "其他",
23 | "percent": 0.12,
24 | "a": "1"
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_multiIntervalsChart.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "London",
3 | "月份": "Jan.",
4 | "月均降雨量": 18.9
5 | }, {
6 | "name": "London",
7 | "月份": "Feb.",
8 | "月均降雨量": 28.8
9 | }, {
10 | "name": "London",
11 | "月份": "Mar.",
12 | "月均降雨量": 39.3
13 | }, {
14 | "name": "London",
15 | "月份": "Apr.",
16 | "月均降雨量": 81.4
17 | }, {
18 | "name": "London",
19 | "月份": "May.",
20 | "月均降雨量": 47
21 | }, {
22 | "name": "London",
23 | "月份": "Jun.",
24 | "月均降雨量": 20.3
25 | }, {
26 | "name": "London",
27 | "月份": "Jul.",
28 | "月均降雨量": 24
29 | }, {
30 | "name": "London",
31 | "月份": "Aug.",
32 | "月均降雨量": 35.6
33 | }, {
34 | "name": "Berlin",
35 | "月份": "Jan.",
36 | "月均降雨量": 12.4
37 | }, {
38 | "name": "Berlin",
39 | "月份": "Feb.",
40 | "月均降雨量": 23.2
41 | }, {
42 | "name": "Berlin",
43 | "月份": "Mar.",
44 | "月均降雨量": 34.5
45 | }, {
46 | "name": "Berlin",
47 | "月份": "Apr.",
48 | "月均降雨量": 99.7
49 | }, {
50 | "name": "Berlin",
51 | "月份": "May.",
52 | "月均降雨量": 52.6
53 | }, {
54 | "name": "Berlin",
55 | "月份": "Jun.",
56 | "月均降雨量": 35.5
57 | }, {
58 | "name": "Berlin",
59 | "月份": "Jul.",
60 | "月均降雨量": 37.4
61 | }, {
62 | "name": "Berlin",
63 | "月份": "Aug.",
64 | "月均降雨量": 42.4
65 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_radarArea.json:
--------------------------------------------------------------------------------
1 | [{
2 | "item": "Design",
3 | "user": "用户 A",
4 | "score": 70
5 | }, {
6 | "item": "Design",
7 | "user": "用户 B",
8 | "score": 30
9 | }, {
10 | "item": "Development",
11 | "user": "用户 A",
12 | "score": 60
13 | }, {
14 | "item": "Development",
15 | "user": "用户 B",
16 | "score": 70
17 | }, {
18 | "item": "Marketing",
19 | "user": "用户 A",
20 | "score": 50
21 | }, {
22 | "item": "Marketing",
23 | "user": "用户 B",
24 | "score": 60
25 | }, {
26 | "item": "Users",
27 | "user": "用户 A",
28 | "score": 40
29 | }, {
30 | "item": "Users",
31 | "user": "用户 B",
32 | "score": 50
33 | }, {
34 | "item": "Test",
35 | "user": "用户 A",
36 | "score": 60
37 | }, {
38 | "item": "Test",
39 | "user": "用户 B",
40 | "score": 70
41 | }, {
42 | "item": "Language",
43 | "user": "用户 A",
44 | "score": 70
45 | }, {
46 | "item": "Language",
47 | "user": "用户 B",
48 | "score": 50
49 | }, {
50 | "item": "Technology",
51 | "user": "用户 A",
52 | "score": 70
53 | }, {
54 | "item": "Technology",
55 | "user": "用户 B",
56 | "score": 40
57 | }, {
58 | "item": "Support",
59 | "user": "用户 A",
60 | "score": 60
61 | }, {
62 | "item": "Support",
63 | "user": "用户 B",
64 | "score": 40
65 | }]
66 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_sectionInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "x": "分类一",
3 | "y": [ 76, 100 ]
4 | }, {
5 | "x": "分类二",
6 | "y": [ 56, 108 ]
7 | }, {
8 | "x": "分类三",
9 | "y": [ 38, 129 ]
10 | }, {
11 | "x": "分类四",
12 | "y": [ 58, 155 ]
13 | }, {
14 | "x": "分类五",
15 | "y": [ 45, 120 ]
16 | }, {
17 | "x": "分类六",
18 | "y": [ 23, 99 ]
19 | }, {
20 | "x": "分类七",
21 | "y": [ 18, 56 ]
22 | }, {
23 | "x": "分类八",
24 | "y": [ 18, 34 ]
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_singleAreaChart.json:
--------------------------------------------------------------------------------
1 | [{
2 | "time": "Jan.",
3 | "tem": 1000
4 | }, {
5 | "time": "Feb.",
6 | "tem": 2200
7 | }, {
8 | "time": "Mar.",
9 | "tem": 2000
10 | }, {
11 | "time": "Apr.",
12 | "tem": 2600
13 | }, {
14 | "time": "May.",
15 | "tem": 2000
16 | }, {
17 | "time": "Jun.",
18 | "tem": 2600
19 | }, {
20 | "time": "Jul.",
21 | "tem": 2800
22 | }, {
23 | "time": "Aug.",
24 | "tem": 2000
25 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_singleAreaChart_2.json:
--------------------------------------------------------------------------------
1 | [{
2 | "month": "Jan.",
3 | "value": 6.06
4 | }, {
5 | "month": "Feb.",
6 | "value": 82.2
7 | }, {
8 | "month": "Mar.",
9 | "value": -22.11
10 | }, {
11 | "month": "Apr.",
12 | "value": 21.53
13 | }, {
14 | "month": "May.",
15 | "value": -21.74
16 | }, {
17 | "month": "Jun.",
18 | "value": 73.61
19 | }, {
20 | "month": "Jul.",
21 | "value": 53.75
22 | }, {
23 | "month": "Aug.",
24 | "value": 60.32
25 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_singleIntervalChart.json:
--------------------------------------------------------------------------------
1 | [{
2 | "year": "1950",
3 | "sales": 29
4 | }, {
5 | "year": "1951",
6 | "sales": 30
7 | }, {
8 | "year": "1952",
9 | "sales": 31
10 | }, {
11 | "year": "1953",
12 | "sales": 32
13 | }, {
14 | "year": "1954",
15 | "sales": 33
16 | }, {
17 | "year": "1955",
18 | "sales": 34
19 | }, {
20 | "year": "1956",
21 | "sales": 35
22 | }, {
23 | "year": "1957",
24 | "sales": 36
25 | }, {
26 | "year": "1958",
27 | "sales": 37
28 | }, {
29 | "year": "1959",
30 | "sales": 38
31 | }, {
32 | "year": "1960",
33 | "sales": 29
34 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_singleIntervalChart_2.json:
--------------------------------------------------------------------------------
1 | [{
2 | "genre": "Sports",
3 | "sold": 275
4 | }, {
5 | "genre": "Strategy",
6 | "sold": 115
7 | }, {
8 | "genre": "Action",
9 | "sold": 120
10 | }, {
11 | "genre": "Shooter",
12 | "sold": 350
13 | }, {
14 | "genre": "Other",
15 | "sold": 150
16 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/mockData_trendChart_flags.json:
--------------------------------------------------------------------------------
1 | [{
2 | "content": "HIT电池",
3 | "position": [1608687000000, 3365.65]
4 | }, {
5 | "content": "煤炭开采",
6 | "position": [1608688920000, 3366.13]
7 | }, {
8 | "content": "白酒",
9 | "position": [1608690420000, 3376.52]
10 | }, {
11 | "content": "光伏",
12 | "position": [1608691680000, 3375.87]
13 | }, {
14 | "content": "证券",
15 | "position": [1608693420000, 3388.95]
16 | }, {
17 | "content": "航空装备",
18 | "position": [1608700080000, 3389.64]
19 | }, {
20 | "content": "白酒",
21 | "position": [1608702720000, 3371.69]
22 | }, {
23 | "content": "黄酒",
24 | "position": [1608706080000, 3378.72]
25 | }]
--------------------------------------------------------------------------------
/demos/android/demos/src/main/assets/wallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos/src/main/assets/wallet.png
--------------------------------------------------------------------------------
/demos/android/demos/src/main/java/com/antgroup/antv/f2/samples/ChartModel.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2.samples;
2 |
3 | import com.antgroup.antv.f2.F2CanvasView;
4 |
5 | import java.io.Serializable;
6 |
7 | /**
8 | * @author qingyuan.yl
9 | * @version 10.1.1
10 | * @date 2020-09-25
11 | */
12 | public class ChartModel implements Serializable {
13 | public String title;
14 |
15 | public Class extends F2CanvasView.Adapter> adapterClass;
16 |
17 | public boolean horizontal = false;
18 |
19 | public ChartModel(String title, Class extends F2CanvasView.Adapter> adapterClass) {
20 | this.title = title;
21 | this.adapterClass = adapterClass;
22 | }
23 |
24 | public ChartModel(String title, Class extends F2CanvasView.Adapter> adapterClass, boolean horizontal) {
25 | this.title = title;
26 | this.adapterClass = adapterClass;
27 | this.horizontal = horizontal;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/java/com/antgroup/antv/f2/samples/Utils.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2.samples;
2 |
3 | import android.content.Context;
4 |
5 | import java.io.ByteArrayOutputStream;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 |
9 | /**
10 | * @author qingyuan.yl
11 | * @date 2020-09-24
12 | */
13 | public class Utils {
14 |
15 | public static String loadAssetFile(Context context, String assetFile) {
16 | try {
17 | InputStream is = context.getAssets().open(assetFile);
18 |
19 | byte[] buf = new byte[1024 * 500];
20 |
21 | ByteArrayOutputStream output = new ByteArrayOutputStream();
22 | int size = 0;
23 | while ((size = is.read(buf, 0, buf.length)) >= 0) {
24 | output.write(buf, 0, size);
25 | }
26 |
27 | return new String(output.toByteArray());
28 | } catch (IOException e) {
29 | }
30 | return null;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/java/com/antgroup/antv/f2/samples/charts/MultiIntervalChart.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.f2.samples.charts;
2 |
3 | import com.antgroup.antv.f2.F2CanvasView;
4 | import com.antgroup.antv.f2.F2Chart;
5 | import com.antgroup.antv.f2.samples.Utils;
6 |
7 | /**
8 | * 分组柱状图
9 | * @author qingyuan.yl
10 | * @date 2020-09-27
11 | */
12 | public class MultiIntervalChart implements F2CanvasView.Adapter {
13 | private F2Chart mChart;
14 |
15 | @Override
16 | public void onCanvasDraw(F2CanvasView canvasView) {
17 | if (mChart == null) {
18 | mChart = F2Chart.create(canvasView.getContext(), "MultiIntervalChart", canvasView.getWidth(), canvasView.getHeight());
19 | }
20 |
21 | mChart.setCanvas(canvasView);
22 | mChart.padding(10, 0, 0, 0);
23 | mChart.source(Utils.loadAssetFile(canvasView.getContext(), "mockData_multiIntervalsChart.json"));
24 | mChart.interval().position("月份*月均降雨量").color("name").adjust("dodge");
25 | mChart.setScale("月份", new F2Chart.ScaleConfigBuilder().range(new double[]{0.065, 0.935}));
26 | mChart.render();
27 | }
28 |
29 | @Override
30 | public void onDestroy() {
31 | if (mChart != null) {
32 | mChart.destroy();
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/jniLibs/arm64-v8a/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos/src/main/jniLibs/arm64-v8a/libc++_shared.so
--------------------------------------------------------------------------------
/demos/android/demos/src/main/jniLibs/armeabi-v7a/libc++_shared.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos/src/main/jniLibs/armeabi-v7a/libc++_shared.so
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/android/demos/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/layout/activity_sample.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/layout/activity_sample_horizontal.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/layout/activity_stock_time_sharing.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/layout/layout_chart_canvasview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
25 |
26 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/layout/layout_chart_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
17 |
18 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
4 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | F2Native
3 | BridgeActivity
4 | SampleActivity
5 | ChartListActivity
6 |
7 |
8 |
--------------------------------------------------------------------------------
/demos/android/demos/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/demos/android/demos/src/test/java/com/antgroup/antv/samples/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.antgroup.antv.samples;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Demos-Swift
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 | var window: UIWindow?
14 |
15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | // Override point for customization after application launch.
17 | self.window = UIWindow.init(frame: UIScreen.main.bounds)
18 | let viewController = ViewController.init();
19 | self.window!.rootViewController = UINavigationController.init(rootViewController: viewController)
20 | self.window!.makeKeyAndVisible()
21 | return true
22 | }
23 |
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/128x128.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/16x16.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/180x180 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/180x180 1.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/180x180.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/256x256.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/32x32.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/512x512.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/AppIcon.appiconset/64x64.png
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_baseArea.json:
--------------------------------------------------------------------------------
1 | [{
2 | "time": "Jan.",
3 | "tem": 1000
4 | }, {
5 | "time": "Feb.",
6 | "tem": 2200
7 | }, {
8 | "time": "Mar.",
9 | "tem": 2000
10 | }, {
11 | "time": "Apr.",
12 | "tem": 2600
13 | }, {
14 | "time": "May.",
15 | "tem": 2000
16 | }, {
17 | "time": "Jun.",
18 | "tem": 2600
19 | }, {
20 | "time": "Jul.",
21 | "tem": 2800
22 | }, {
23 | "time": "Aug.",
24 | "tem": 2000
25 | }]
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_baseInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "year": "1951 年\n第一季度",
3 | "sales": 38
4 | }, {
5 | "year": "1952 年\n第一季度",
6 | "sales": 52
7 | }, {
8 | "year": "1956 年\n第一季度",
9 | "sales": 61
10 | }, {
11 | "year": "1957 年\n第一季度",
12 | "sales": 145
13 | }, {
14 | "year": "1958 年\n第一季度",
15 | "sales": 48
16 | }, {
17 | "year": "1959 年\n第一季度",
18 | "sales": 38
19 | }, {
20 | "year": "1960 年\n第一季度",
21 | "sales": 38
22 | }, {
23 | "year": "1962 年\n第一季度",
24 | "sales": 38
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_baseInterval2.json:
--------------------------------------------------------------------------------
1 | [{
2 | "genre": "Sports",
3 | "sold": 275
4 | }, {
5 | "genre": "Strategy",
6 | "sold": 115
7 | }, {
8 | "genre": "Action",
9 | "sold": 120
10 | }, {
11 | "genre": "Shooter",
12 | "sold": 350
13 | }, {
14 | "genre": "Other",
15 | "sold": 150
16 | }]
17 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_basePie.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "芳华",
3 | "percent": 0.4,
4 | "a": "1"
5 | }, {
6 | "name": "妖猫传",
7 | "percent": 0.2,
8 | "a": "1"
9 | }, {
10 | "name": "机器之血",
11 | "percent": 0.18,
12 | "a": "1"
13 | }, {
14 | "name": "心理罪",
15 | "percent": 0.15,
16 | "a": "1"
17 | }, {
18 | "name": "寻梦环游记",
19 | "percent": 0.05,
20 | "a": "1"
21 | }, {
22 | "name": "其他",
23 | "percent": 0.12,
24 | "a": "1"
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_multiInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "London",
3 | "month": "Jan.",
4 | "value": 18.9
5 | }, {
6 | "name": "London",
7 | "month": "Feb.",
8 | "value": 28.8
9 | }, {
10 | "name": "London",
11 | "month": "Mar.",
12 | "value": 39.3
13 | }, {
14 | "name": "London",
15 | "month": "Apr.",
16 | "value": 81.4
17 | }, {
18 | "name": "London",
19 | "month": "May.",
20 | "value": 47
21 | }, {
22 | "name": "London",
23 | "month": "Jun.",
24 | "value": 20.3
25 | }, {
26 | "name": "London",
27 | "month": "Jul.",
28 | "value": 24
29 | }, {
30 | "name": "London",
31 | "month": "Aug.",
32 | "value": 35.6
33 | }, {
34 | "name": "Berlin",
35 | "month": "Jan.",
36 | "value": 12.4
37 | }, {
38 | "name": "Berlin",
39 | "month": "Feb.",
40 | "value": 23.2
41 | }, {
42 | "name": "Berlin",
43 | "month": "Mar.",
44 | "value": 34.5
45 | }, {
46 | "name": "Berlin",
47 | "month": "Apr.",
48 | "value": 99.7
49 | }, {
50 | "name": "Berlin",
51 | "month": "May.",
52 | "value": 52.6
53 | }, {
54 | "name": "Berlin",
55 | "month": "Jun.",
56 | "value": 35.5
57 | }, {
58 | "name": "Berlin",
59 | "month": "Jul.",
60 | "value": 37.4
61 | }, {
62 | "name": "Berlin",
63 | "month": "Aug.",
64 | "value": 42.4
65 | }]
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_radarArea.json:
--------------------------------------------------------------------------------
1 | [{
2 | "item": "Design",
3 | "user": "用户 A",
4 | "score": 70
5 | }, {
6 | "item": "Design",
7 | "user": "用户 B",
8 | "score": 30
9 | }, {
10 | "item": "Development",
11 | "user": "用户 A",
12 | "score": 60
13 | }, {
14 | "item": "Development",
15 | "user": "用户 B",
16 | "score": 70
17 | }, {
18 | "item": "Marketing",
19 | "user": "用户 A",
20 | "score": 50
21 | }, {
22 | "item": "Marketing",
23 | "user": "用户 B",
24 | "score": 60
25 | }, {
26 | "item": "Users",
27 | "user": "用户 A",
28 | "score": 40
29 | }, {
30 | "item": "Users",
31 | "user": "用户 B",
32 | "score": 50
33 | }, {
34 | "item": "Test",
35 | "user": "用户 A",
36 | "score": 60
37 | }, {
38 | "item": "Test",
39 | "user": "用户 B",
40 | "score": 70
41 | }, {
42 | "item": "Language",
43 | "user": "用户 A",
44 | "score": 70
45 | }, {
46 | "item": "Language",
47 | "user": "用户 B",
48 | "score": 50
49 | }, {
50 | "item": "Technology",
51 | "user": "用户 A",
52 | "score": 70
53 | }, {
54 | "item": "Technology",
55 | "user": "用户 B",
56 | "score": 40
57 | }, {
58 | "item": "Support",
59 | "user": "用户 A",
60 | "score": 60
61 | }, {
62 | "item": "Support",
63 | "user": "用户 B",
64 | "score": 40
65 | }]
66 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_setionInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "x": "分类一",
3 | "y": [ 76, 100 ]
4 | }, {
5 | "x": "分类二",
6 | "y": [ 56, 108 ]
7 | }, {
8 | "x": "分类三",
9 | "y": [ 38, 129 ]
10 | }, {
11 | "x": "分类四",
12 | "y": [ 58, 155 ]
13 | }, {
14 | "x": "分类五",
15 | "y": [ 45, 120 ]
16 | }, {
17 | "x": "分类六",
18 | "y": [ 23, 99 ]
19 | }, {
20 | "x": "分类七",
21 | "y": [ 18, 56 ]
22 | }, {
23 | "x": "分类八",
24 | "y": [ 18, 34 ]
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_singleAreaChart_2.json:
--------------------------------------------------------------------------------
1 | [{"month":"Jan.","value":6.06},{"month":"Feb.","value":82.2},{"month":"Mar.","value":-22.11},{"month":"Apr.","value":21.53},{"month":"May.","value":-21.74},{"month":"Jun.","value":73.61},{"month":"Jul.","value":53.75},{"month":"Aug.","value":60.32}]
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Res/mockData_singleIntervalChart_under_zero.json:
--------------------------------------------------------------------------------
1 | [{"time":"周一","tem":6.9,"city":"tokyo"},{"time":"周二","tem":9.5,"city":"tokyo"},{"time":"周三","tem":14.5,"city":"tokyo"},{"time":"周四","tem":18.2,"city":"tokyo"},{"time":"周五","tem":21.5,"city":"tokyo"},{"time":"周六","tem":25.2,"city":"tokyo"},{"time":"周日","tem":26.5,"city":"tokyo"},{"time":"周一","tem":-10.8,"city":"newYork"},{"time":"周二","tem":-5.7,"city":"newYork"},{"time":"周三","tem":-11.3,"city":"newYork"},{"time":"周四","tem":-17,"city":"newYork"},{"time":"周五","tem":-22,"city":"newYork"},{"time":"周六","tem":-24.8,"city":"newYork"},{"time":"周日","tem":-24.1,"city":"newYork"},{"time":"周一","tem":2.6,"city":"berlin"},{"time":"周二","tem":3.5,"city":"berlin"},{"time":"周三","tem":8.4,"city":"berlin"},{"time":"周四","tem":13.5,"city":"berlin"},{"time":"周五","tem":17,"city":"berlin"},{"time":"周六","tem":-18.6,"city":"berlin"},{"time":"周日","tem":17.9,"city":"berlin"}]
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/BaseAreaChart2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAreaChart2.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class BaseAreaChart2: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_singleAreaChart_2", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0).source()(jsonData)
22 | chart.axis()("tem", ["grid": ["stroke": "#000"]])
23 | chart.line()().position()("month*value")
24 | chart.area()().position()("month*value").fixedColor()("#1890FF0F")
25 | chart.scale()("value", ["nice": true])
26 | chart.animate()(true)
27 | chart.render()()
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/BaseAreaChart3.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAreaChart3.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class BaseAreaChart3: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_singleAreaChart_2", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0).source()(jsonData)
22 | chart.axis()("tem", ["grid": ["stroke": "#000"]])
23 | chart.line()().position()("month*value")
24 | chart.area()().position()("month*value").fixedColor()("#1890FF0F")
25 | chart.scale()("value", ["nice": true])
26 | chart.animate()(true)
27 | chart.render()()
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/BaseBarChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseInterval2UIView.swift
3 | // Demos-Swift
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | //
7 |
8 | import Foundation
9 | import F2
10 |
11 | class BaseBarChart: BaseLineChart {
12 |
13 | override func chartRender() {
14 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_baseInterval", ofType: "json"),
15 | let jsonDataString = try? String(contentsOfFile: jsonPath),
16 | let canvasView = self.canvasView,
17 | let chart = self.chart else {
18 | return
19 | }
20 | let jsonData = F2Utils.toJsonArray(jsonDataString)
21 | chart.clear()
22 | chart.canvas()(canvasView).padding()(20, 10, 20, 10)
23 | chart.source()(jsonData)
24 | chart.axis()("year", ["grid": false])
25 | chart.axis()("sales", ["grid": ["type": "dash", "lineWidth": 2, "lineDash": [6, 2]]])
26 | chart.scale()("year", ["range": [0.1, 0.9]])
27 | chart.scale()("sales", ["nice": true])
28 | chart.interval()().position()("year*sales").style()([
29 | "rounding": [10, 10, 0, 0] // [tl, tr, bl, br]
30 | ])
31 | chart.tooltip()([:])
32 | chart.animate()(true)
33 | chart.render()()
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/BaseBarChart2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseBarChart2.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class BaseBarChart2: BaseLineChart {
11 |
12 | override func chartRender() {
13 | let jsonPath = Bundle.main.path(forResource: "Res/mockData_baseInterval2", ofType: "json")
14 | guard let jsonString = try? String.init(contentsOfFile: jsonPath!) else {
15 | return
16 | }
17 | let jsonData = F2Utils.toJsonArray(jsonString)
18 | self.chart!.clear()
19 | self.chart!.canvas()(self.canvasView!)
20 | self.chart!.padding()(10, 20, 10, 0)
21 | self.chart!.source()(jsonData)
22 | self.chart!.interval()().position()("genre*sold").color()("genre", [])
23 | self.chart!.scale()("sold", ["min":0])
24 | self.chart!.scale()("genre", ["range": [0.1, 0.9]])
25 | self.chart!.animate()(true)
26 | self.chart!.render()();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/BasePieChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BasePieChart.swift
3 | // F2Native
4 | //
5 | // Created by weiqing.twq on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class BasePieChart: BaseLineChart {
11 |
12 | override func chartRender() {
13 | let jsonPath = Bundle.main.path(forResource: "Res/mockData_basePie", ofType: "json")
14 | guard let jsonString = try? String.init(contentsOfFile: jsonPath!) else {
15 | return
16 | }
17 | guard let chart = self.chart else {
18 | return
19 | }
20 |
21 | guard let canvasView = self.canvasView else {
22 | return
23 | }
24 |
25 | let jsonData = F2Utils.toJsonArray(jsonString)
26 | chart.clear()
27 | chart.canvas()(canvasView)
28 | chart.source()(jsonData)
29 | chart.padding()(10, 20, 10, 0)
30 | chart.axis()("percent", ["line": false, "label": false, "grid": false])
31 | chart.axis()("a", ["line": false, "label": false, "grid": false])
32 | chart.coord()(["type": "polar", "transposed": true])
33 | chart.interval()().position()("a*percent").color()("name", []).adjust()("stack").fixedSize()(1).style()(["lineWidth": 1, "stroke": "#ffffff"])
34 | chart.animate()(true)
35 | chart.render()()
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/BasePointChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BasePointChart.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class BasePointChart: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_singlePointChart", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0)
22 | chart.source()(jsonData)
23 | chart.point()().position()("x*y").size()("z", [3, 10]).fixedShape()("circle")
24 | chart.animate()(true)
25 | chart.render()()
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/ContrastLineChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContrastLineChart.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import Foundation
9 | import F2
10 |
11 | class ContrastLineChart: BaseLineChart {
12 |
13 | override func chartRender() {
14 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_multiLines", ofType: "json"),
15 | let jsonDataString = try? String(contentsOfFile: jsonPath),
16 | let canvasView = self.canvasView,
17 | let chart = self.chart else {
18 | return
19 | }
20 | let jsonData = F2Utils.toJsonArray(jsonDataString)
21 | chart.clear()
22 | chart.canvas()(canvasView).padding()(20, 10, 20, 0)
23 | chart.source()(jsonData)
24 | chart.scale()("value", ["nice": true])
25 | chart.scale()("date", ["tickCount": 5])
26 | chart.axis()("date", ["label": ["textAlign": "center"]])
27 | chart.line()().position()("date*value").color()("type", []).fixedSize()(2).fixedShape()("smooth")
28 | chart.legend()("type", ["radius": 3, "symbol": "square"])
29 | chart.tooltip()([:])
30 | chart.animate()(true)
31 | chart.render()()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/GroupBarChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GroupBarChart.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class GroupBarChart: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_multiInterval", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(15, 15, 15, 15)
22 | chart.source()(jsonData)
23 | chart.axis()("month", ["grid": false])
24 | chart.scale()("month", ["range": [0.1, 0.9]])
25 | chart.scale()("value", ["nice": true])
26 | chart.interval()().adjust()("dodge").position()("month*value").color()("name", [])
27 | chart.tooltip()([:])
28 | chart.legend()("name", ["position": "bottom", "align": "center"])
29 | chart.animate()(true)
30 | chart.render()()
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/GroupBarChart2.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GroupBarChart2.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class GroupBarChart2: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_singleIntervalChart_under_zero", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0)
22 | chart.source()(jsonData)
23 | chart.axis()("tem", ["grid": ["stroke": "#000"]])
24 | chart.interval()().position()("time*tem").color()("city", []).adjust()("dodge")
25 | chart.scale()("time", ["range": [0.1, 0.9]])
26 | chart.scale()("tem", ["nice": true])
27 | chart.tooltip()([:])
28 | chart.animate()(true)
29 | chart.render()()
30 | }
31 | }
32 |
33 |
34 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/GroupStackBarChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GroupStackBarChart.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class GroupStackBarChart: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_multiInterval", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0)
22 | chart.source()(jsonData)
23 | chart.axis()("month", ["grid": false])
24 | chart.scale()("month", ["range": [0.1, 0.9]])
25 | chart.scale()("value", ["nice": true])
26 | chart.interval()().adjust()("stack").position()("month*value").color()("name", [])
27 | chart.animate()(true)
28 | chart.render()()
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/HistogramBarChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HistogramBarChart.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class HistogramBarChart: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_setionInterval", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0)
22 | chart.source()(jsonData)
23 | chart.axis()("x", ["grid": false])
24 | chart.axis()("y", ["grid": ["type": "dash", "lineWidth": 2, "lineDash": [6, 2]]])
25 | chart.scale()("x", ["range": [0.1, 0.9]])
26 | chart.scale()("y", ["nice": true])
27 | chart.interval()().position()("x*y")
28 | chart.animate()(true)
29 | chart.render()()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Demos-Swift/Views/StackedAreaChart.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StackedAreaChart.swift
3 | // F2Native
4 | //
5 | // Created by Westin on 2024-06-09.
6 | //
7 |
8 | import F2
9 |
10 | class StackedAreaChart: BaseLineChart {
11 |
12 | override func chartRender() {
13 | guard let jsonPath = Bundle.main.path(forResource: "Res/mockData_multiArea", ofType: "json"),
14 | let jsonDataString = try? String(contentsOfFile: jsonPath),
15 | let canvasView = self.canvasView,
16 | let chart = self.chart else {
17 | return
18 | }
19 | let jsonData = F2Utils.toJsonArray(jsonDataString)
20 | chart.clear()
21 | chart.canvas()(canvasView).padding()(20, 10, 20, 0)
22 | chart.source()(jsonData)
23 | chart.scale()("date", ["tickCount": 5])
24 | chart.scale()("value", ["min": 0])
25 | chart.axis()("date", ["grid": false, "label": ["textAlign": "start"]])
26 | chart.line()().adjust()("stack").position()("date*value").color()("city", []).fixedSize()(2)
27 | chart.area()().adjust()("stack").position()("date*value").color()("city", []).fixedSize()(2)
28 | chart.tooltip()([:])
29 | chart.animate()(true)
30 | chart.render()()
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/demos/ios/Demos-Swift/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '13.0'
2 |
3 | target "Demos-Swift" do
4 | pod 'F2'
5 | end
6 |
7 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface AppDelegate : UIResponder
4 |
5 | @property (nonatomic, strong) UIWindow *window;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 | #import "ViewController.h"
3 |
4 | @interface AppDelegate ()
5 |
6 | @end
7 |
8 | @implementation AppDelegate
9 |
10 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
11 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
12 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[ViewController new]];
13 | self.window.rootViewController = nav;
14 | [self.window makeKeyAndVisible];
15 | return YES;
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/128x128.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/16x16.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/180x180.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/256x256.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/32x32.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/512x512.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/ios/Demos/Demos/Assets.xcassets/AppIcon.appiconset/64x64.png
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/BugFixViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // BugFixViewController.h
3 | // F2Native
4 | //
5 | // Created by ruize on 2022/2/7.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface BugFixViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/ChartListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ChartListViewController.h
3 | // F2Native
4 | //
5 | // Created by 青原 on 2021/5/13.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ChartListViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/DemoViewController.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | @interface DemoViewController : UIViewController
7 |
8 | -(instancetype)initWithInfo:(NSDictionary *)info;
9 |
10 | @end
11 |
12 | NS_ASSUME_NONNULL_END
13 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_baseArea.json:
--------------------------------------------------------------------------------
1 | [{
2 | "time": "Jan.",
3 | "tem": 1000
4 | }, {
5 | "time": "Feb.",
6 | "tem": 2200
7 | }, {
8 | "time": "Mar.",
9 | "tem": 2000
10 | }, {
11 | "time": "Apr.",
12 | "tem": 2600
13 | }, {
14 | "time": "May.",
15 | "tem": 2000
16 | }, {
17 | "time": "Jun.",
18 | "tem": 2600
19 | }, {
20 | "time": "Jul.",
21 | "tem": 2800
22 | }, {
23 | "time": "Aug.",
24 | "tem": 2000
25 | }]
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_baseInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "year": "1951 年\n第一季度",
3 | "sales": 38
4 | }, {
5 | "year": "1952 年\n第一季度",
6 | "sales": 52
7 | }, {
8 | "year": "1956 年\n第一季度",
9 | "sales": 61
10 | }, {
11 | "year": "1957 年\n第一季度",
12 | "sales": 145
13 | }, {
14 | "year": "1958 年\n第一季度",
15 | "sales": 48
16 | }, {
17 | "year": "1959 年\n第一季度",
18 | "sales": 38
19 | }, {
20 | "year": "1960 年\n第一季度",
21 | "sales": 38
22 | }, {
23 | "year": "1962 年\n第一季度",
24 | "sales": 38
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_basePie.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "芳华",
3 | "percent": 0.4,
4 | "a": "1"
5 | }, {
6 | "name": "妖猫传",
7 | "percent": 0.2,
8 | "a": "1"
9 | }, {
10 | "name": "机器之血",
11 | "percent": 0.18,
12 | "a": "1"
13 | }, {
14 | "name": "心理罪",
15 | "percent": 0.15,
16 | "a": "1"
17 | }, {
18 | "name": "寻梦环游记",
19 | "percent": 0.05,
20 | "a": "1"
21 | }, {
22 | "name": "其他",
23 | "percent": 0.12,
24 | "a": "1"
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_multiInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "London",
3 | "month": "Jan.",
4 | "value": 18.9
5 | }, {
6 | "name": "London",
7 | "month": "Feb.",
8 | "value": 28.8
9 | }, {
10 | "name": "London",
11 | "month": "Mar.",
12 | "value": 39.3
13 | }, {
14 | "name": "London",
15 | "month": "Apr.",
16 | "value": 81.4
17 | }, {
18 | "name": "London",
19 | "month": "May.",
20 | "value": 47
21 | }, {
22 | "name": "London",
23 | "month": "Jun.",
24 | "value": 20.3
25 | }, {
26 | "name": "London",
27 | "month": "Jul.",
28 | "value": 24
29 | }, {
30 | "name": "London",
31 | "month": "Aug.",
32 | "value": 35.6
33 | }, {
34 | "name": "Berlin",
35 | "month": "Jan.",
36 | "value": 12.4
37 | }, {
38 | "name": "Berlin",
39 | "month": "Feb.",
40 | "value": 23.2
41 | }, {
42 | "name": "Berlin",
43 | "month": "Mar.",
44 | "value": 34.5
45 | }, {
46 | "name": "Berlin",
47 | "month": "Apr.",
48 | "value": 99.7
49 | }, {
50 | "name": "Berlin",
51 | "month": "May.",
52 | "value": 52.6
53 | }, {
54 | "name": "Berlin",
55 | "month": "Jun.",
56 | "value": 35.5
57 | }, {
58 | "name": "Berlin",
59 | "month": "Jul.",
60 | "value": 37.4
61 | }, {
62 | "name": "Berlin",
63 | "month": "Aug.",
64 | "value": 42.4
65 | }]
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_radarArea.json:
--------------------------------------------------------------------------------
1 | [{
2 | "item": "Design",
3 | "user": "用户 A",
4 | "score": 70
5 | }, {
6 | "item": "Design",
7 | "user": "用户 B",
8 | "score": 30
9 | }, {
10 | "item": "Development",
11 | "user": "用户 A",
12 | "score": 60
13 | }, {
14 | "item": "Development",
15 | "user": "用户 B",
16 | "score": 70
17 | }, {
18 | "item": "Marketing",
19 | "user": "用户 A",
20 | "score": 50
21 | }, {
22 | "item": "Marketing",
23 | "user": "用户 B",
24 | "score": 60
25 | }, {
26 | "item": "Users",
27 | "user": "用户 A",
28 | "score": 40
29 | }, {
30 | "item": "Users",
31 | "user": "用户 B",
32 | "score": 50
33 | }, {
34 | "item": "Test",
35 | "user": "用户 A",
36 | "score": 60
37 | }, {
38 | "item": "Test",
39 | "user": "用户 B",
40 | "score": 70
41 | }, {
42 | "item": "Language",
43 | "user": "用户 A",
44 | "score": 70
45 | }, {
46 | "item": "Language",
47 | "user": "用户 B",
48 | "score": 50
49 | }, {
50 | "item": "Technology",
51 | "user": "用户 A",
52 | "score": 70
53 | }, {
54 | "item": "Technology",
55 | "user": "用户 B",
56 | "score": 40
57 | }, {
58 | "item": "Support",
59 | "user": "用户 A",
60 | "score": 60
61 | }, {
62 | "item": "Support",
63 | "user": "用户 B",
64 | "score": 40
65 | }]
66 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_setionInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "x": "分类一",
3 | "y": [ 76, 100 ]
4 | }, {
5 | "x": "分类二",
6 | "y": [ 56, 108 ]
7 | }, {
8 | "x": "分类三",
9 | "y": [ 38, 129 ]
10 | }, {
11 | "x": "分类四",
12 | "y": [ 58, 155 ]
13 | }, {
14 | "x": "分类五",
15 | "y": [ 45, 120 ]
16 | }, {
17 | "x": "分类六",
18 | "y": [ 23, 99 ]
19 | }, {
20 | "x": "分类七",
21 | "y": [ 18, 56 ]
22 | }, {
23 | "x": "分类八",
24 | "y": [ 18, 34 ]
25 | }]
26 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_singleAreaChart_2.json:
--------------------------------------------------------------------------------
1 | [{"month":"Jan.","value":6.06},{"month":"Feb.","value":82.2},{"month":"Mar.","value":-22.11},{"month":"Apr.","value":21.53},{"month":"May.","value":-21.74},{"month":"Jun.","value":73.61},{"month":"Jul.","value":53.75},{"month":"Aug.","value":60.32}]
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/Res/mockData_singleIntervalChart_under_zero.json:
--------------------------------------------------------------------------------
1 | [{"time":"周一","tem":6.9,"city":"tokyo"},{"time":"周二","tem":9.5,"city":"tokyo"},{"time":"周三","tem":14.5,"city":"tokyo"},{"time":"周四","tem":18.2,"city":"tokyo"},{"time":"周五","tem":21.5,"city":"tokyo"},{"time":"周六","tem":25.2,"city":"tokyo"},{"time":"周日","tem":26.5,"city":"tokyo"},{"time":"周一","tem":-10.8,"city":"newYork"},{"time":"周二","tem":-5.7,"city":"newYork"},{"time":"周三","tem":-11.3,"city":"newYork"},{"time":"周四","tem":-17,"city":"newYork"},{"time":"周五","tem":-22,"city":"newYork"},{"time":"周六","tem":-24.8,"city":"newYork"},{"time":"周日","tem":-24.1,"city":"newYork"},{"time":"周一","tem":2.6,"city":"berlin"},{"time":"周二","tem":3.5,"city":"berlin"},{"time":"周三","tem":8.4,"city":"berlin"},{"time":"周四","tem":13.5,"city":"berlin"},{"time":"周五","tem":17,"city":"berlin"},{"time":"周六","tem":-18.6,"city":"berlin"},{"time":"周日","tem":17.9,"city":"berlin"}]
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/ViewController.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface ViewController : UIViewController
4 |
5 | + (NSArray *)demoInfo;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | Demos
4 |
5 | Created by weiqing.twq on 2022/6/1.
6 | Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | */
8 | "ChartList" = "ChartList";
9 | "BaseLineChart" = "BaseLineChart";
10 | "BaseLineChart2" = "BaseLineChart(Dual Y-axis)";
11 | "ContrastLineChart" = "ContrastLineChart";
12 | "BaseAreaChart" = "BaseAreaChart";
13 | "BaseAreaChart2" = "BaseAreaChart2(with negative value)";
14 | "BaseAreaChart3" = "BaseAreaChart3(x baseline is not 0)";
15 | "StackedAreaChart" = "StackedAreaChart";
16 | "BaseBarChart" = "BaseBarChart";
17 | "BaseBarChart2" = "BaseBarChart2";
18 | "GroupBarChart" = "GroupBarChart";
19 | "GroupBarChart2" = "GroupBarChart2(with negative value)";
20 | "GroupStackBarChart"="GroupStackBarChart";
21 | "HistogramBarChart" = "HistogramBarChart";
22 | "BasePointChart" = "BasePointChart";
23 | "StripChart" = "StripChart";
24 | "BasePieChart" = "BasePieChart";
25 | "CyclicPieChart" = "CyclicPieChart";
26 | "RadarAreaChart" = "RadarAreaChart";
27 | "CandleChart" = "CandleChart";
28 | "TimeSharingChart" = "TimeSharingChart";
29 | "MarketMovingChart" = "MarketMovingChart";
30 | "BaseGuideChart" = "BaseGuideChart";
31 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/main.m:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 | #import
3 |
4 | int main(int argc, char *argv[]) {
5 | NSString *appDelegateClassName;
6 | @autoreleasepool {
7 | // Setup code that might create autoreleased objects goes here.
8 | appDelegateClassName = NSStringFromClass([AppDelegate class]);
9 | }
10 | return UIApplicationMain(argc, argv, nil, appDelegateClassName);
11 | }
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseAreaChart.h:
--------------------------------------------------------------------------------
1 |
2 | #import "BaseLineChart.h"
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | @interface BaseAreaChart : BaseLineChart
7 |
8 | @end
9 |
10 | NS_ASSUME_NONNULL_END
11 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseAreaChart2.h:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAreaUIView2.h
3 | // F2Native
4 | //
5 | // Created by 青原 on 2020/12/23.
6 | // Copyright © 2020 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseLineChart.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface BaseAreaChart2 : BaseLineChart
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseAreaChart2.m:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAreaUIView2.m
3 | // F2Native
4 | //
5 | // Created by 青原 on 2020/12/23.
6 | // Copyright © 2020 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseAreaChart2.h"
10 |
11 | @implementation BaseAreaChart2
12 |
13 | - (void)chartRender {
14 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_singleAreaChart_2" ofType:@"json"];
15 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
16 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0).source(jsonData);
17 | self.chart.axis(@"tem", @{@"grid": @{@"stroke": @"#000"}});
18 |
19 | self.chart.line().position(@"month*value");
20 | self.chart.area().position(@"month*value").fixedColor(@"#1890FF0F");
21 |
22 | self.chart.scale(@"value", @{@"nice": @(YES)});
23 | self.chart.animate(@YES);
24 | self.chart.render();
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseAreaChart3.h:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAreaUIView3.h
3 | // F2Native
4 | //
5 | // Created by weiqing.twq on 2021/4/27.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseLineChart.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface BaseAreaChart3 : BaseLineChart
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseAreaChart3.m:
--------------------------------------------------------------------------------
1 | //
2 | // BaseAreaUIView3.m
3 | // F2Native
4 | //
5 | // Created by weiqing.twq on 2021/4/27.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseAreaChart3.h"
10 |
11 | @implementation BaseAreaChart3
12 |
13 | - (void)chartRender {
14 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_singleAreaChart_2" ofType:@"json"];
15 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
16 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0).source(jsonData);
17 | self.chart.axis(@"tem", @{@"grid": @{@"stroke": @"#000"}});
18 |
19 | self.chart.line().position(@"month*value");
20 | self.chart.area().position(@"month*value").fixedColor(@"#1890FF0F").style(@{@"startOnZero":@(NO)});
21 |
22 | self.chart.scale(@"value", @{@"nice": @(YES)});
23 | self.chart.render();
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseBarChart.h:
--------------------------------------------------------------------------------
1 | #import "BaseLineChart.h"
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface BaseBarChart : BaseLineChart
6 |
7 | @end
8 |
9 | NS_ASSUME_NONNULL_END
10 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseBarChart.m:
--------------------------------------------------------------------------------
1 | #import "BaseBarChart.h"
2 |
3 | @implementation BaseBarChart
4 |
5 | - (void)chartRender {
6 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_baseInterval" ofType:@"json"];
7 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
8 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 10.f);
9 | self.chart.source([F2Utils toJsonArray:jsonData]);
10 | self.chart.axis(@"year", @{@"grid": @(NO)});
11 | self.chart.axis(@"sales", @{@"grid": @{@"type": @"dash", @"lineWidth": @(2), @"lineDash": @[@(6), @(2)]}});
12 | self.chart.scale(@"year", @{@"range": @[@(0.1), @(0.9)]});
13 | self.chart.scale(@"sales", @{@"nice": @(YES)});
14 | self.chart.interval().position(@"year*sales").style(@{
15 | @"rounding": @[@(10), @(10), @(0), @(0)] // [tl, tr, bl, br]
16 | });
17 | self.chart.tooltip(@{});
18 | self.chart.animate(@(YES));
19 | self.chart.render();
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseBarChart2.h:
--------------------------------------------------------------------------------
1 | #import "BaseLineChart.h"
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface BaseBarChart2 : BaseLineChart
6 |
7 | @end
8 |
9 | NS_ASSUME_NONNULL_END
10 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseBarChart2.m:
--------------------------------------------------------------------------------
1 | //
2 | // BaseInterval2UIView.m
3 | // Demos
4 | //
5 | // Created by XiaLuo on 2020/11/5.
6 | // Copyright © 2020 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseBarChart2.h"
10 |
11 | @implementation BaseBarChart2
12 |
13 | - (NSString *)jsonData {
14 | return @"[{\"genre\":\"Sports\",\"sold\":275},{\"genre\":\"Strategy\",\"sold\":115},{\"genre\":\"Action\",\"sold\":120},{"
15 | @"\"genre\":\"Shooter\",\"sold\":350},{\"genre\":\"Other\",\"sold\":150}]";
16 | }
17 |
18 | - (void)chartRender {
19 | self.chart.canvas(self.canvasView);
20 | self.chart.padding(10, 20, 10, 0.f);
21 | self.chart.source([F2Utils toJsonArray:[self jsonData]]);
22 | self.chart.interval().position(@"genre*sold").color(@"genre", @[]);
23 | self.chart.tooltip(@{});
24 | self.chart.render();
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseGuideChart.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 | #import "BaseLineChart.h"
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface BaseGuideChart : BaseLineChart
8 | @end
9 |
10 | NS_ASSUME_NONNULL_END
11 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseLineChart.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 | #import
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface BaseLineChart : UIView
8 |
9 | @property (nonatomic, strong, readonly) F2CanvasView *canvasView;
10 | @property (nonatomic, strong, readonly) F2Chart *chart;
11 |
12 | @end
13 |
14 | NS_ASSUME_NONNULL_END
15 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseLineChart2.h:
--------------------------------------------------------------------------------
1 |
2 | #import "BaseLineChart.h"
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | @interface BaseLineChart2 : BaseLineChart
7 |
8 | @end
9 |
10 | NS_ASSUME_NONNULL_END
11 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BaseLineChart2.m:
--------------------------------------------------------------------------------
1 |
2 | #import "BaseLineChart2.h"
3 |
4 | @implementation BaseLineChart2
5 |
6 | - (void)chartRender {
7 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_multiAxiesLine" ofType:@"json"];
8 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
9 | self.chart.syncYScale(NO);
10 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f).source(jsonData);
11 | self.chart.scale(@"date", @{@"tickCount": @(5)});
12 | self.chart.scale(@"value", @{@"nice": @(YES)});
13 | self.chart.scale(@"offset", @{@"nice": @(YES)});
14 | self.chart.axis(@"value", @{@"grid": @{@"type": @"dash", @"dash": @[@(15), @(15), @(5), @(5)]}});
15 | self.chart.axis(@"offset", @{@"label": @{@"labelOffset": @(10), @"textAlign": @"start"}});
16 | self.chart.axis(@"date", @{
17 | @"label": @{
18 | @"labelOffset": @(5),
19 | }
20 | });
21 | self.chart.line().position(@"date*value").fixedSize(2).fixedColor(@"#1890FF");
22 | self.chart.line().position(@"date*offset").fixedSize(2).fixedColor(@"#2FC25B");
23 | self.chart.tooltip(@{});
24 | self.chart.render();
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BasePieChart.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import "BaseLineChart.h"
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface BasePieChart : BaseLineChart
8 |
9 | @end
10 |
11 | NS_ASSUME_NONNULL_END
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BasePieChart.m:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import "BasePieChart.h"
4 |
5 | @implementation BasePieChart
6 |
7 | - (void)chartRender {
8 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_basePie" ofType:@"json"];
9 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
10 | self.chart.canvas(self.canvasView).padding(0, 0, 0, 0.f);
11 | self.chart.source([F2Utils toJsonArray:jsonData]);
12 | self.chart.axis(@"percent", @{@"line": @(NO), @"label": @(NO), @"grid": @(NO)});
13 | self.chart.axis(@"a", @{@"line": @(NO), @"label": @(NO) , @"grid": @(NO)});
14 | self.chart.coord(@{@"type": @"polar", @"transposed": @(YES)});
15 | self.chart.interval().position(@"a*percent").color(@"name", @[]).adjust(@"stack").fixedSize(1).style(@{@"lineWidth": @(1),@"stroke": @"#ffffff"});
16 | self.chart.animate(@YES);
17 | self.chart.render();
18 | }
19 | @end
20 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BasePointChart.h:
--------------------------------------------------------------------------------
1 | //
2 | // BasePointUIView.h
3 | // F2Native
4 | //
5 | // Created by 青原 on 2021/1/4.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseLineChart.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface BasePointChart : BaseLineChart
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/BasePointChart.m:
--------------------------------------------------------------------------------
1 | //
2 | // BasePointUIView.m
3 | // F2Native
4 | //
5 | // Created by 青原 on 2021/1/4.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BasePointChart.h"
10 |
11 | @implementation BasePointChart
12 |
13 | - (void)chartRender {
14 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_singlePointChart" ofType:@"json"];
15 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
16 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f).source(jsonData);
17 | self.chart.point().position(@"x*y").size(@"z", @[@(3), @(10)]).fixedShape(@"circle");
18 | self.chart.animate(@YES);
19 | self.chart.render();
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/CandleChart.h:
--------------------------------------------------------------------------------
1 | //
2 | // KLineUIView.h
3 | // F2Native
4 | //
5 | // Created by XiaLuo on 2021/1/14.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseLineChart.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface CandleChart : BaseLineChart
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/ContrastLineChart.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import "BaseLineChart.h"
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface ContrastLineChart : BaseLineChart
8 |
9 | @end
10 |
11 | NS_ASSUME_NONNULL_END
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/ContrastLineChart.m:
--------------------------------------------------------------------------------
1 |
2 | #import "ContrastLineChart.h"
3 |
4 | @implementation ContrastLineChart
5 |
6 | - (void)chartRender {
7 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_multiLines" ofType:@"json"];
8 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
9 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f);
10 | self.chart.source([F2Utils toJsonArray:jsonData]);
11 | self.chart.scale(@"value", @{@"nice": @(YES)});
12 | self.chart.scale(@"date", @{@"tickCount": @(5)});
13 | self.chart.axis(@"date", @{@"label": @{@"textAlign": @"center"}});
14 | self.chart.line().position(@"date*value").color(@"type", @[]).fixedSize(2).fixedShape(@"smooth");
15 | self.chart.legend(@"type", @{@"radius": @(3), @"symbol": @"square"});
16 | self.chart.tooltip(@{});
17 | self.chart.render();
18 | }
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/CyclicPieChart.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import "BaseLineChart.h"
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface CyclicPieChart : BaseLineChart
8 |
9 | @end
10 |
11 | NS_ASSUME_NONNULL_END
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/CyclicPieChart.m:
--------------------------------------------------------------------------------
1 |
2 | #import "CyclicPieChart.h"
3 |
4 | @implementation CyclicPieChart
5 |
6 | - (void)chartRender {
7 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_basePie" ofType:@"json"];
8 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
9 | self.chart.canvas(self.canvasView).padding(0, 0, 0, 0.f).source(jsonData);
10 | self.chart.axis(@"percent", @{@"line": @(NO), @"label": @(NO), @"grid": @(NO)});
11 | self.chart.axis(@"a", @{@"line": @(NO), @"label": @(NO), @"grid": @(NO)});
12 | self.chart.coord(@{@"type": @"polar"});
13 | self.chart.interval().style(@{@"lineWidth": @(0)}).position(@"a*percent").color(@"name", @[]).adjust(@"stack");
14 | self.chart.animate(@YES);
15 | self.chart.render();
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/GroupBarChart.h:
--------------------------------------------------------------------------------
1 | #import "BaseLineChart.h"
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface GroupBarChart : BaseLineChart
6 |
7 | @end
8 |
9 | NS_ASSUME_NONNULL_END
10 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/GroupBarChart.m:
--------------------------------------------------------------------------------
1 | #import "GroupBarChart.h"
2 |
3 | @implementation GroupBarChart
4 |
5 | - (void)chartRender {
6 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_multiInterval" ofType:@"json"];
7 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
8 | self.chart.canvas(self.canvasView).padding(15, 15, 15, 15.f);
9 | self.chart.source([F2Utils toJsonArray:jsonData]);
10 | self.chart.axis(@"month", @{@"grid": @(NO)});
11 | self.chart.scale(@"month", @{@"range": @[@(0.1), @(0.9)]});
12 | self.chart.scale(@"value", @{@"nice": @(YES)});
13 | self.chart.interval().adjust(@"dodge").position(@"month*value").color(@"name", @[]);
14 | self.chart.tooltip(@{});
15 | self.chart.legend(@"name", @{@"position": @"bottom", @"align": @"center"});
16 | self.chart.render();
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/GroupBarChart2.h:
--------------------------------------------------------------------------------
1 | //
2 | // MultiIntervalUIView2.h
3 | // F2Native
4 | //
5 | // Created by 青原 on 2020/12/22.
6 | // Copyright © 2020 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseLineChart.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface GroupBarChart2 : BaseLineChart
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/GroupBarChart2.m:
--------------------------------------------------------------------------------
1 | //
2 | // MultiIntervalUIView2.m
3 | // F2Native
4 | //
5 | // Created by 青原 on 2020/12/22.
6 | // Copyright © 2020 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "GroupBarChart2.h"
10 |
11 | @implementation GroupBarChart2
12 |
13 | - (void)chartRender {
14 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_singleIntervalChart_under_zero" ofType:@"json"];
15 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
16 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0);
17 | self.chart.source([F2Utils toJsonArray:jsonData]);
18 | self.chart.axis(@"tem", @{@"grid": @{@"stroke": @"#000"}});
19 | self.chart.interval().position(@"time*tem").color(@"city", @[]).adjust(@"dodge");
20 | self.chart.scale(@"time", @{@"range": @[@(0.1), @(0.9)]});
21 | self.chart.scale(@"tem", @{@"nice": @(YES)});
22 | self.chart.tooltip(@{});
23 | self.chart.render();
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/GroupStackBarChart.h:
--------------------------------------------------------------------------------
1 | #import "BaseLineChart.h"
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface GroupStackBarChart : BaseLineChart
6 |
7 | @end
8 |
9 | NS_ASSUME_NONNULL_END
10 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/GroupStackBarChart.m:
--------------------------------------------------------------------------------
1 | #import "GroupStackBarChart.h"
2 |
3 | @implementation GroupStackBarChart
4 |
5 | - (void)chartRender {
6 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_multiInterval" ofType:@"json"];
7 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
8 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f).source(jsonData);
9 | self.chart.axis(@"month", @{@"grid": @(NO)});
10 | self.chart.scale(@"month", @{@"range": @[@(0.1), @(0.9)]});
11 | self.chart.scale(@"value", @{@"nice": @(YES)});
12 | self.chart.interval().adjust(@"stack").position(@"month*value").color(@"name", @[]);
13 | self.chart.render();
14 | }
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/HistogramBarChart.h:
--------------------------------------------------------------------------------
1 | #import "BaseLineChart.h"
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface HistogramBarChart : BaseLineChart
6 |
7 | @end
8 |
9 | NS_ASSUME_NONNULL_END
10 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/HistogramBarChart.m:
--------------------------------------------------------------------------------
1 |
2 | #import "HistogramBarChart.h"
3 |
4 | @implementation HistogramBarChart
5 |
6 | - (void)chartRender {
7 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_setionInterval" ofType:@"json"];
8 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
9 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f).source(jsonData);
10 | self.chart.axis(@"x", @{@"grid": @(NO)});
11 | self.chart.axis(@"y", @{@"grid": @{@"type": @"dash", @"lineWidth": @(2), @"lineDash": @[@(6), @(2)]}});
12 | self.chart.scale(@"x", @{@"range": @[@(0.1), @(0.9)]});
13 | self.chart.scale(@"y", @{@"nice": @(YES)});
14 | self.chart.interval().position(@"x*y");
15 | self.chart.render();
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/MarketMovingChart.h:
--------------------------------------------------------------------------------
1 | #import "BaseLineChart.h"
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface MarketMovingChart : BaseLineChart
6 |
7 | @end
8 |
9 | NS_ASSUME_NONNULL_END
10 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/RadarAreaChart.h:
--------------------------------------------------------------------------------
1 | //
2 | // RadarAreaUIView.h
3 | // F2Native
4 | //
5 | // Created by weiqing.twq on 2021/9/16.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "BaseLineChart.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface RadarAreaChart : BaseLineChart
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/StackedAreaChart.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #import "BaseLineChart.h"
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | @interface StackedAreaChart : BaseLineChart
8 |
9 | @end
10 |
11 | NS_ASSUME_NONNULL_END
12 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/StackedAreaChart.m:
--------------------------------------------------------------------------------
1 | #import "StackedAreaChart.h"
2 |
3 | @implementation StackedAreaChart
4 |
5 | - (void)chartRender {
6 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_multiArea" ofType:@"json"];
7 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
8 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f);
9 | self.chart.source([F2Utils toJsonArray:jsonData]);
10 | self.chart.scale(@"date", @{@"tickCount": @(5)});
11 | self.chart.scale(@"value", @{@"min": @(0)});
12 | self.chart.axis(@"date", @{@"grid": @(NO), @"label": @{@"textAlign": @"start"}});
13 | self.chart.line().adjust(@"stack").position(@"date*value").color(@"city", @[]).fixedSize(2);
14 | self.chart.area().adjust(@"stack").position(@"date*value").color(@"city", @[]).fixedSize(2);
15 | self.chart.tooltip(@{});
16 | self.chart.render();
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/StripChart.h:
--------------------------------------------------------------------------------
1 |
2 | #import "BaseLineChart.h"
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | @interface StripChart : BaseLineChart
7 |
8 | @end
9 |
10 | NS_ASSUME_NONNULL_END
11 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/StripChart.m:
--------------------------------------------------------------------------------
1 |
2 | #import "StripChart.h"
3 |
4 | @implementation StripChart
5 |
6 | - (void)chartRender {
7 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/mockData_baseInterval" ofType:@"json"];
8 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
9 | self.chart.canvas(self.canvasView).padding(20, 10, 20, 0.f).source(jsonData);
10 | self.chart.coord(@{@"transposed": @(YES)});
11 | self.chart.scale(@"sales", @{@"min": @(0)});
12 | self.chart.scale(@"year", @{@"range": @[@(0.1), @(0.9)]});
13 | self.chart.interval().position(@"year*sales");
14 | self.chart.render();
15 | }
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/TimeSharingChart.h:
--------------------------------------------------------------------------------
1 |
2 | #import "BaseLineChart.h"
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | @interface TimeSharingChart : BaseLineChart
7 |
8 | @end
9 |
10 | NS_ASSUME_NONNULL_END
11 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/bugfix/KLineTrendBugFix1.h:
--------------------------------------------------------------------------------
1 | /**
2 | 解决大盘异动旗子的布局问题
3 | */
4 |
5 | #import "BaseLineChart.h"
6 |
7 | NS_ASSUME_NONNULL_BEGIN
8 |
9 | @interface KLineTrendBugFix1 : BaseLineChart
10 |
11 | @end
12 |
13 | NS_ASSUME_NONNULL_END
14 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/bugfix/KLineTrendBugFix1.m:
--------------------------------------------------------------------------------
1 | //
2 | // MarketMovingBugFix1.m
3 | // F2Native
4 | //
5 | // Created by weiqing.twq on 2022/2/23.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "KLineTrendBugFix1.h"
10 |
11 | @implementation KLineTrendBugFix1
12 |
13 | -(instancetype)initWithFrame:(CGRect)frame {
14 | CGRect chartFrame = CGRectMake(0, 0, frame.size.width, 280);
15 | if (self = [super initWithFrame:chartFrame]) {}
16 | return self;
17 | }
18 |
19 | - (void)chartRender {
20 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/bugfix/kline_trend" ofType:@"json"];
21 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
22 | NSDictionary *jsonDict = [F2Utils toJsonObject:jsonData];
23 | FunctionItemCallback callback = ^NSDictionary *_Nonnull(NSString *_Nonnull functionId, NSDictionary *_Nonnull param) {
24 | return param;
25 | };
26 | self.chart.canvas(self.canvasView).padding(15, 10, 15, 0.f).callback(callback);
27 | self.chart.config(jsonDict);
28 | self.chart.render();
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/bugfix/MarketMovingBugFix1.h:
--------------------------------------------------------------------------------
1 | /**
2 | 解决大盘异动旗子的布局问题
3 | */
4 |
5 | #import "BaseLineChart.h"
6 |
7 | NS_ASSUME_NONNULL_BEGIN
8 |
9 | @interface MarketMovingBugFix1 : BaseLineChart
10 |
11 | @end
12 |
13 | NS_ASSUME_NONNULL_END
14 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/bugfix/MarketMovingBugFix1.m:
--------------------------------------------------------------------------------
1 | //
2 | // MarketMovingBugFix1.m
3 | // F2Native
4 | //
5 | // Created by weiqing.twq on 2022/2/23.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "MarketMovingBugFix1.h"
10 |
11 | @implementation MarketMovingBugFix1
12 |
13 | - (void)chartRender {
14 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Res/bugfix/market_trend" ofType:@"json"];
15 | NSString *jsonData = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
16 | NSDictionary *jsonDict = [F2Utils toJsonObject:jsonData];
17 | FunctionItemCallback callback = ^NSDictionary *_Nonnull(NSString *_Nonnull functionId, NSDictionary *_Nonnull param) {
18 | return param;
19 | };
20 | self.chart.canvas(self.canvasView).padding(15, 10, 15, 0.f).callback(callback);
21 | NSTimeInterval start = [[NSDate date] timeIntervalSince1970] * 1000;
22 | self.chart.config(jsonDict);
23 | NSTimeInterval end = [[NSDate date] timeIntervalSince1970] * 1000;
24 | NSLog(@"config parse cost %fms", (end - start));
25 | self.chart.render();
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/views/bugfix/TimeSharingBugFix1.h:
--------------------------------------------------------------------------------
1 | /**
2 | 折线太贴近顶端导致折线部分被裁,业务在chart加top padding临时解决下,引擎侧后续看下这个问题
3 | */
4 |
5 | #import "BaseLineChart.h"
6 |
7 | NS_ASSUME_NONNULL_BEGIN
8 |
9 | @interface TimeSharingBugFix1 : BaseLineChart
10 |
11 | @end
12 |
13 | NS_ASSUME_NONNULL_END
14 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/zh-HK.lproj/LaunchScreen.strings:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/zh-Hans.lproj/LaunchScreen.strings:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Demos/zh-Hans.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | Demos
4 |
5 | Created by weiqing.twq on 2022/6/1.
6 | Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | */
8 | "ChartList" = "多图列表";
9 | "BaseLineChart" = "基础折线图";
10 | "BaseLineChart2" = "基础折线图(双Y轴)";
11 | "ContrastLineChart" = "对比折线图";
12 | "BaseAreaChart" = "基础面积图";
13 | "BaseAreaChart2" = "基础面积图2(带负值)";
14 | "BaseAreaChart3" = "基础面积图2(x基线不为0)";
15 | "StackedAreaChart" = "层叠面积图";
16 | "BaseBarChart" = "基础柱状图";
17 | "BaseBarChart2" = "基础柱状图2";
18 | "GroupBarChart" = "分组柱状图";
19 | "GroupBarChart2" = "分组柱状图2(带负值)";
20 | "GroupStackBarChart"="分组层叠柱状图";
21 | "HistogramBarChart" = "区间柱状图";
22 | "BasePointChart" = "散点图";
23 | "StripChart" = "条状图";
24 | "BasePieChart" = "饼图";
25 | "CyclicPieChart" = "环形饼图";
26 | "RadarAreaChart" = "雷达面积图";
27 | "CandleChart" = "蜡烛图(日K)";
28 | "TimeSharingChart" = "股票分时图";
29 | "MarketMovingChart" = "大盘异动";
30 | "BaseGuideChart" = "辅助组件";
31 |
--------------------------------------------------------------------------------
/demos/ios/Demos/F2Native.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/demos/ios/Demos/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '13.0'
2 |
3 | target "F2Native" do
4 | pod 'F2'
5 | end
6 |
7 |
--------------------------------------------------------------------------------
/demos/videos/ios_demo.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/videos/ios_demo.mp4
--------------------------------------------------------------------------------
/demos/webassembly/f2wasm.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/demos/webassembly/f2wasm.wasm
--------------------------------------------------------------------------------
/demos/webassembly/run.sh:
--------------------------------------------------------------------------------
1 | python3 -m http.server 8083
2 |
--------------------------------------------------------------------------------
/docs/api/F2Area.en.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: F2Area
3 | order: 5
4 | ---
5 |
6 | Graphics area object, used to draw area extents
7 |
8 | ## Create F2Area Instance
9 | #### iOS
10 | ````obj-c
11 | chart.area();
12 | ````
13 |
14 | #### Android
15 | ````java
16 | chart.area();
17 | ````
18 |
19 |
20 | ## Method
21 | ### - Position
22 | draw area location
23 | #### iOS
24 | ````obj-c
25 | chart.area().position(@"date*value");
26 | ````
27 | #### Android
28 | ````java
29 | chart.area().position("date*value");
30 | ````
31 | - parameters
32 |
33 | | **Attribute Name** | **Type** | **Explanation** |
34 | | --- | --- | --- |
35 | | `attr`| String | X*Y: The corresponding name of the drawn area in the source
36 |
37 |
38 |
39 | ### - FixedColor
40 | Set the color of the uniform area fill
41 | #### iOS
42 | ````obj-c
43 | chart.area().fixedColor(@"#108EE9");
44 | ````
45 | #### Android
46 | ````java
47 | chart.area().fixedColor("#108EE9");
48 | ````
49 | - parameters
50 |
51 | | **Attribute Name** | **Type** | **Explanation** |
52 | | --- | --- | --- |
53 | | `attr`| String | Set the color of the area fill (Hex rgba)
--------------------------------------------------------------------------------
/docs/api/F2Area.zh.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: F2Area
3 | order: 5
4 | ---
5 |
6 | 图形区域对象,用于绘制区域范围
7 |
8 | ## 创建 F2Area 实例
9 |
10 | ```
11 | chart.area();
12 | ```
13 |
14 |
15 | ## 方法
16 | ### - position
17 | ```
18 | chart.area().position("date*value");
19 | ```
20 | - 参数
21 |
22 | | **属性名** | **类型** | **解释** |
23 | | --- | --- | --- |
24 | | `attr`| String | X*Y:绘制的区域在source中对应的名称
25 |
26 |
27 |
28 | ### - fixedColor
29 | 设置统一的区域填充的颜色
30 | ```
31 | chart.area().fixedColor("#108EE9");
32 | ```
33 | - 参数
34 |
35 | | **属性名** | **类型** | **解释** |
36 | | --- | --- | --- |
37 | | `attr`| String | 设置区域填充的颜色 (Hex rgba)
38 |
--------------------------------------------------------------------------------
/docs/tutorial/manual/coordinate.zh.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 坐标系
3 | order: 6
4 | ---
5 |
6 | 坐标系是将两种位置标度结合在一起组成的 2 维定位系统,描述了数据是如何映射到图形所在的平面。
7 |
8 | F2Native 提供了直角坐标系和极坐标两种类型,目前所有的坐标系均是 2 维的。
9 |
10 | ## 如何设置坐标系
11 |
12 | F2Native 默认提供的坐标系类型为笛卡尔坐标系,当需要切换坐标系时,可以通过调用下面的语法声明需要使用的坐标系:
13 |
14 | ``` obj-c
15 | chart.coord(@{@"type": @"polar", @"transposed": @(YES)});
16 | ```
17 |
18 | | **坐标系类型** | **说明** |
19 | | --- | --- |
20 | | `rect` | 直角坐标系,目前仅支持二维,由 x, y 两个互相垂直的坐标轴构成。 |
21 | | `polar` | 极坐标系,由角度和半径 2 个维度构成。 |
22 |
23 |
24 | ## 坐标系类型及配置
25 |
26 | 坐标系可以分为笛卡尔坐标系和非笛卡尔坐标系,非笛卡尔坐标系即极坐标,由角度和半径这两个维度来确定位置。
27 |
28 | 利用极坐标可生成饼图、玫瑰图和雷达图等,较适用于周期性数据的可视化场景,比如时间和方向数据。
29 |
30 | 坐标系类型的变换会改变几何标记的形状,比如在极坐标系中,矩形将变为圆环的一部分。
31 |
32 |
33 | ### 坐标系配置
34 |
35 | #### 直角坐标系
36 |
37 | ```
38 | // 声明直角坐标系
39 | // 直角坐标系转置
40 | chart.coord(@{@"type": @"rect", @"transposed": @(YES)});
41 | ```
42 |
43 | #### 极坐标
44 |
45 | ```
46 | chart.coord(@{
47 | @"type": @"polar", // 声明极坐标系
48 | @"transposed": @(YES) // 转置
49 | });
50 | ```
51 |
52 | 这里需要说明的是,F2Native 极坐标默认的起始角度和结束角度如下图所示:
53 |
54 | 
55 |
--------------------------------------------------------------------------------
/docs/tutorial/manual/data.zh.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 数据
3 | order: 2
4 | ---
5 |
6 | 数据是绘制一张图表最基本的部分。F2Native 支持的数据格式为 jsonString:
7 |
8 | ``` json
9 | [{"genre":"Sports", "sold":275},
10 | {"genre":"Strategy","sold":115},
11 | {"genre":"Action","sold":120},
12 | {"genre":"Shooter","sold":350},
13 | {"genre":"Other","sold":150}]
14 | ```
15 |
16 | ## 如何装载数据
17 |
18 | 当 chart 实例创建完毕之后,通过调用以下接口装载数据:
19 |
20 | ```
21 | chart.source(data);
22 | ```
23 |
24 | ## 如何更新数据
25 |
26 |
27 | 1. 更新图表数据。
28 |
29 | ```
30 | chart.source(data);
31 | ```
32 |
33 | 2.在需要更新图表的时机调用重绘方法。
34 |
35 | ```
36 | chart.source(newData); // 更新数据源
37 |
38 | // do something
39 |
40 | chart.repaint(); // 更新图表!
41 | ```
42 |
43 | 3. 更新数据时还可以重新定义图形语法,改变图表类型和各种配置。
44 |
45 | ```
46 | chart.source(newData); // 加载新数据
47 | chart.interval().position('x*y').color('z'); // 重新定义图形语法组合
48 | chart.repaint();
49 | ```
50 |
51 | ## 特殊图表的数据说明
52 |
53 | ### 饼图
54 |
55 | 绘制饼图时,数据集中的每一条记录中**必须包含一个常量字段(并且必须是字符串类型)**,如下所示:
56 |
57 | ```json
58 | [
59 | { "name": "芳华", "percent": 0.4, "a": "1" },
60 | { "name": "妖猫传", "percent": 0.2, "a": "1" },
61 | { "name": "机器之血", "percent": 0.18, "a": "1"},
62 | { "name": "心理罪", "percent": 0.15, "a": "1" },
63 | { "name": "寻梦环游记", "percent": 0.05, "a": "1" },
64 | { "name": "其他", "percent": 0.02, "a": "1" }
65 | ]
66 | ```
67 |
68 | 详见饼图[示例](/zh/examples/pie/basic)。
69 |
--------------------------------------------------------------------------------
/docs/tutorial/manual/grammar.zh.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 图形语法
3 | order: 0
4 | ---
5 |
6 | F2Native 同 G2 一样,基于《The Grammar of Graphics》(Leland Wilkinson 著)一书所提的图形理论。该理论是一套用来描述所有统计图形深层特性的语法规则,该语法回答了『什么是统计图形』这一问题,以自底向上的方式组织最基本的元素形成更高级的元素。
7 |
8 | 所以对于 F2Native 来说,**没有具体的图表类型的概念,所有的图表都是通过组合不同的图形语法元素形成的**,这些图形语法元素包括:
9 |
10 | - 最基础的部分是你想要可视化的[数据](./data)以及一系列将数据中的变量对应到[图形属性](./attribute)的映射;
11 |
12 | - [几何标记](./geometry),可以理解为你在图表中实际看到的图形元素,如点、线、多边形等,每个几何标记对象含有多个图形属性,F2Native 图形语法的核心就是建立数据中的一系列变量到图形属性的映射;
13 |
14 | - [度量](./scale),作为数据空间到图形属性空间的转换桥梁,每一个图形属性都对应着一个或者多个度量;
15 |
16 | - [坐标系](./coordinate),描述了数据是如何映射到图形所在的平面的,一个几何标记在不同坐标系下会有不同的表现。目前 F2Native 提供了笛卡尔坐标系、极坐标系两种坐标系;
17 |
18 | - 辅助元素是为了增强图表的可读性和可理解性,F2Native 中的辅助元素包含坐标轴 Axis、图例 Legend、提示信息 Tooltip、静态辅助标记 Guide。
19 |
20 |
21 | 所以,在 F2Native 中,我们通常这么描述一张图表:一张图表就是从数据到几何标记对象的图形属性的一个映射,此外图形中还可能包含数据的统计变换,最后绘制在某个特定的坐标系中。
22 |
23 | 更多内容请阅读以下篇章:
24 |
25 | - [图表组成](./understanding)
26 |
27 | - [数据](./data)
28 |
29 | - [度量](./scale)
30 |
31 | - [几何标记](./geometry)
32 |
33 | - [图形属性](./attribute)
34 |
35 | - [坐标系](./coordinate)
36 |
37 |
38 |
--------------------------------------------------------------------------------
/docs/tutorial/manual/understanding.zh.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 图表组成
3 | order: 1
4 | ---
5 |
6 | 为了更好得使用 F2Native 进行数据可视化,我们需要了解 F2Native 图表的组成以及相关术语。
7 |
8 | ## 图表部件
9 |
10 | 一般情况下,F2Native 的图表包含坐标轴(Axis)、几何标记(Geometry)、提示信息(Tooltip)、图例(Legend)等,另外还可以包括辅助标记(Guide)、数据标签(dataLabels)等。
11 |
12 | F2Native 基本组成部分如下图所示:
13 |
14 |  
15 |
16 | ## 术语
17 | | **术语** | **英文** | **描述** |
18 | | --- | --- | --- |
19 | | 坐标轴 | Axis | 每个图表通常包含两个坐标轴,在直角坐标系(笛卡尔坐标系)下,分别为 x 轴和 y 轴,在极坐标轴下,则分别由角度和半径 2 个维度构成。每个坐标轴由坐标轴线(line)、刻度线(tickLine)、刻度文本(label)以及网格线(grid)组成。 |
20 | | 图例 | Legend | 图例作为图表的辅助元素,用于标定不同的数据类型以及数据的范围,用于辅助阅读图表以及帮助用户在图表中进行数据的筛选过滤。 |
21 | | 几何标记 | Geometry | 即我们所说的点、线、面这些几何图形,在图形语法 中几何标记的类型决定了生成图表的类型。也就是数据被可视化后的实际表现,不同的几何标记都包含对应的图形属性。 |
22 | | 图形属性 | Attribute | 图形属性对应视觉编码中的视觉通道,是图形语法元素非常重要和灵活的一部分,不同的几何标记拥有自己的图形属性,F2Native 提供了位置(position)、颜色(color)、大小(size)、形状(shape)这四种图形属性。 |
23 | | 坐标系 | Coordinate | 坐标系是将两种位置标度结合在一起组成的 2 维定位系统,描述了数据是如何映射到图形所在的平面。 |
24 | | 提示信息 | Tooltip | 当鼠标悬停在某个点上时,会以提示框的形式显示当前点对应的数据的信息,比如该点的值,数据单位等,帮助用户从图表中获取具体的数据信息。 |
25 | | 辅助标记 | Guide | 当需要在图表上绘制一些辅助线、辅助框或者文本时,比如增加预警线、最高值线或者标示明显的范围区域时,辅助标记 Guide 是非常有用的工具。 |
26 |
27 |
--------------------------------------------------------------------------------
/externals.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.less';
2 |
--------------------------------------------------------------------------------
/gatsby-browser.js:
--------------------------------------------------------------------------------
1 | window.react = require('react');
2 | window.reactDom = require('react-dom');
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jan 27 10:21:44 CST 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/ios/F2/F2-Prefix.pch:
--------------------------------------------------------------------------------
1 |
2 | #define TARGET_STANDALONE 1
3 |
4 | #define JSON_NOEXCEPTION 1
5 |
--------------------------------------------------------------------------------
/ios/F2/F2.h:
--------------------------------------------------------------------------------
1 | #ifndef F2_H
2 | #define F2_H
3 |
4 | //objc headers
5 | #import
6 | #import
7 | #import
8 | #import
9 | #import
10 | #import
11 |
12 | #endif /* F2_H */
13 |
--------------------------------------------------------------------------------
/ios/F2/F2Callback.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 | NS_ASSUME_NONNULL_BEGIN
4 | typedef NSDictionary *_Nonnull(^ItemCallback)(NSDictionary *_Nonnull param);
5 |
6 | typedef NSDictionary *_Nonnull(^FunctionItemCallback)(NSString *_Nonnull functionId, NSDictionary *_Nonnull param);
7 |
8 | @interface F2Callback : NSObject
9 |
10 | @property (nonatomic, copy, readonly) NSString *functionId;
11 |
12 | + (instancetype)callback:(ItemCallback)block;
13 |
14 | - (NSDictionary *)execute:(NSDictionary *)param;
15 |
16 | @end
17 |
18 | @interface F2RequestAnimationFrameHandle : F2Callback
19 |
20 | + (instancetype)initWithF2Chart:(id)chart canvas:(id)canvasView;
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/ios/F2/F2CanvasContext.h:
--------------------------------------------------------------------------------
1 | //
2 | // F2CoreGraphicsCanvasContext.h
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2021/12/8.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface F2CanvasContext : NSObject
15 |
16 | /// 创建渲染的canvas, 内部会创建CGContextRef
17 | /// @param size canvas的size
18 | - (instancetype)initWithSize:(CGSize)size;
19 |
20 | /// 如果画布的大小与之前的不同,则更新画布的大小
21 | /// @param size 画布的大小
22 | - (void)changeSize:(CGSize)size;
23 |
24 | ///获取C++的context对象
25 | ///@return CGContextRef 渲染的上下文
26 | - (CGContextRef)context2d;
27 |
28 | /// 画布
29 | /// @return CGImageRef bitmap
30 | - (CGImageRef)bitmap;
31 |
32 | /// 返回画布的密度
33 | - (CGFloat)nativeScale;
34 |
35 | @end
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/ios/F2/F2Coordinate.h:
--------------------------------------------------------------------------------
1 | //
2 | // F2Coordinate.h
3 | // F2
4 | //
5 | // Created by weiqing.twq on 2021/11/13.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | //笛卡尔坐标系
15 | /*
16 | |----------------------end
17 | | |
18 | | |
19 | | |
20 | | |
21 | start---------------------
22 | */
23 |
24 | //极坐标系
25 | /*
26 | |--------------end
27 | | |
28 | | |
29 | | center |
30 | | |
31 | | |
32 | start--------------
33 |
34 | */
35 |
36 | @interface F2Coordinate : NSObject
37 |
38 | - (instancetype)initWithCoordinate:(void *)coord;
39 |
40 | //获取极坐标系的中心点
41 | - (CGPoint (^)(void))getCenter;
42 |
43 | //坐标系左下角的点
44 | - (CGPoint (^)(void))getStart;
45 |
46 | //坐标系右上角的点
47 | - (CGPoint (^)(void))getEnd;
48 |
49 | //获取坐标系的宽度
50 | - (CGFloat (^)(void))getWidth;
51 |
52 | //获取坐标系的高度
53 | - (CGFloat (^)(void))getHeight;
54 |
55 | @end
56 |
57 | NS_ASSUME_NONNULL_END
58 |
--------------------------------------------------------------------------------
/ios/F2/F2GestureListener.h:
--------------------------------------------------------------------------------
1 |
2 | #import
3 | #import
4 |
5 | NS_ASSUME_NONNULL_BEGIN
6 |
7 | typedef void (^F2GestureCallback)(NSDictionary *_Nonnull info);
8 |
9 | @interface F2GestureListener : NSObject
10 | @property (nonatomic, strong) UILongPressGestureRecognizer *longGesture;
11 | @property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
12 | @property (nonatomic, strong) UIPinchGestureRecognizer *pinchGesture;
13 | @property (nonatomic, copy) F2GestureCallback longGestureCallback;
14 | @property (nonatomic, copy) F2GestureCallback panGestureCallback;
15 | @property (nonatomic, copy) F2GestureCallback pinchGestureCallback;
16 |
17 | - (instancetype)initWithView:(UIView *)view;
18 |
19 | - (void)addLongPressGesture:(F2GestureCallback)callback;
20 | - (void)addPinchGesture:(F2GestureCallback)callback;
21 | - (void)addPanGesture:(F2GestureCallback)callback;
22 |
23 | - (void)removeLongPressGesture;
24 | - (void)removePinchGesture;
25 | - (void)removePanGesture;
26 |
27 | - (void)removeAllGestures;
28 |
29 | @end
30 |
31 | NS_ASSUME_NONNULL_END
32 |
--------------------------------------------------------------------------------
/ios/F2/F2Guide.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | NS_ASSUME_NONNULL_BEGIN
4 |
5 | @interface F2Guide : NSObject
6 |
7 | - (instancetype)initWithGuide:(void *)guide;
8 |
9 | /// 创建旗子,config格式如下
10 | /// @{ @"position": @[@(x轴的值), @(y轴的值)], @"content": @"内容",@"padding": @(2) }
11 | - (F2Guide * (^)(NSDictionary *config))flag;
12 |
13 | /// 创建文字,config格式如下
14 | /// @{ @"position": @[@"min", @"max"], @"content": @"内容", @"color": @"#808080", @"margin": @[@(-5), @(-13)]
15 | - (F2Guide * (^)(NSDictionary *config))text;
16 |
17 | /// 创建线,config格式如下
18 | /// @{ @"position": @[@"min", @"max"], @"orientation": @"horizontal", @"color": @"#808080", @"lineWdith": @(1), @"dash": @[...]
19 | - (F2Guide * (^)(NSDictionary *config))line;
20 |
21 | ///创建背景,config格式如下
22 | ///@{@"color":@"#FF00001D",@"leftBottom":@[@"min", @"min"], @"rightTop":@[@"max", @(80)]}
23 | - (F2Guide * (^)(NSDictionary *config))background;
24 |
25 | ///创建图片
26 | ///@{@"position":@[@"median", @"median"], @"margin":@[top, right])}
27 | - (F2Guide * (^)(NSDictionary *config))image;
28 |
29 | /// 创建圆
30 | /// @{@"position": @[@"min", @"max"], @"fill":@"#A46FFE", @"size":@(2), @"offsetX": @(10), @"offsetY":@(10)} size为半径
31 | - (F2Guide * (^)(NSDictionary *config))point;
32 |
33 | @end
34 |
35 | NS_ASSUME_NONNULL_END
36 |
--------------------------------------------------------------------------------
/ios/F2/F2Utils.h:
--------------------------------------------------------------------------------
1 | #import "F2Chart.h"
2 | #import
3 |
4 | NS_ASSUME_NONNULL_BEGIN
5 |
6 | #define F2SafeString(str) (str.length > 0 ? str : @"")
7 | #define F2SafeJson(json) (json.length > 0 ? json : @"[]")
8 |
9 | #define F2WeakSelf __weak __typeof(self) weakSelf = self;
10 | #define F2StrongSelf __strong __typeof(weakSelf) strongSelf = weakSelf;
11 | #define F2SafeBlockRun(block, ...) if(block != nil) block(__VA_ARGS__)
12 |
13 | #define F2NativeScale UIScreen.mainScreen.nativeScale
14 |
15 | @interface F2Utils : NSObject
16 |
17 | /// jsonDict可能是NSDictionary or NSArray
18 | + (NSString *)toJsonString:(id)jsonDict;
19 |
20 |
21 | /// 解析成NSArray或者NSDictionary, 如果解析失败返回nil
22 | /// @param jsonString json格式
23 | + (id)toJsonObject:(NSString *)jsonString;
24 |
25 | /// 解析成NSArray或者NSDictionary, 如果解析失败返回空字典
26 | /// @param jsonString json格式
27 | + (NSDictionary *)toJsonDictionary:(NSString *)jsonString;
28 |
29 | /// 解析成NSArray或者NSDictionary, 如果解析失败返回空数组
30 | /// @param jsonString json格式
31 | + (NSArray *)toJsonArray:(NSString *)jsonString;
32 |
33 | + (NSDictionary *)resetCallbacksFromOld:(NSDictionary *)config host:(F2Chart *)chart;
34 |
35 | @end
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/ios/F2Tests/F2TestUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // F2TestUtil.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface F2TestUtil : NSObject
15 |
16 | + (BOOL)saveImage:(UIImage *)image name:(NSString *)name;
17 |
18 | + (UIImage *)readImage:(NSString *)imageName;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/ios/F2Tests/F2TestUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // F2TestUtil.m
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2022/6/1.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import "F2TestUtil.h"
10 |
11 | @implementation F2TestUtil
12 |
13 | + (BOOL)saveImage:(UIImage *)image name:(NSString *)name {
14 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
15 | NSString *filePath = [[paths objectAtIndex:0]stringByAppendingPathComponent:name]; // 保存文件的名称
16 | NSLog(@"saveImage: %@", filePath);
17 | BOOL result =[UIImageJPEGRepresentation(image, 1) writeToFile:filePath atomically:YES]; // 保存成功会返回YES
18 | NSCAssert(result, @"saveImage failure");
19 | return result;
20 | }
21 |
22 | + (UIImage *)readImage:(NSString *)imageName {
23 | NSBundle *bundle = [NSBundle bundleForClass:[self class]];
24 | NSString *jsonPath = [bundle pathForResource:imageName ofType:nil];
25 | return [[UIImage alloc] initWithContentsOfFile:jsonPath];
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/ios/F2Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ios/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDisplayName
6 | App Name
7 | CFBundleIdentifier
8 | $(PRODUCT_BUNDLE_IDENTIFIER)
9 | CFBundleName
10 | $(PRODUCT_NAME)
11 | CFBundleShortVersionString
12 | 1.0
13 | CFBundleVersion
14 | 1
15 | UILaunchStoryboardName
16 | Main
17 | UIMainStoryboardFile
18 | Main
19 | UIRequiredDeviceCapabilities
20 |
21 | armv7
22 |
23 | UISupportedInterfaceOrientations
24 |
25 | UIInterfaceOrientationPortrait
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | UISupportedInterfaceOrientations~ipad
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationPortraitUpsideDown
33 | UIInterfaceOrientationLandscapeLeft
34 | UIInterfaceOrientationLandscapeRight
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':android:sample', ':android:f2native', ':android:sample-kotlin'
2 |
3 | project(':android:sample').dir = new File('demos/android/demos')
4 | project(':android:f2native').dir = new File('android/f2native/')
5 | project(':android:sample-kotlin').dir = new File('demos/android/demos-kotlin')
--------------------------------------------------------------------------------
/site/pages/index.en.tsx:
--------------------------------------------------------------------------------
1 | import Index from './index.zh';
2 |
3 | export default Index;
4 |
--------------------------------------------------------------------------------
/tests/e2e/BaseInterval.h:
--------------------------------------------------------------------------------
1 | //
2 | // BaseInterval.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2022/1/18.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include "../../core/graphics/XChart.h"
12 |
13 | using namespace xg;
14 |
15 | namespace e2e {
16 |
17 | class BaseInterval {
18 | public:
19 |
20 | //基础的线图
21 | static bool Case1(float width, float height,float ratio, const std::string &path, void *context) {
22 | XChart chart("Baseline#Test", width, height, ratio);
23 | std::ifstream jsonFile(path);
24 | std::string jsonData((std::istreambuf_iterator(jsonFile)), std::istreambuf_iterator());
25 | chart.Source(jsonData);
26 | chart.SetCanvasContext(context).Padding(20, 10, 20, 0);
27 | chart.ScaleObject("date", {{"tickCount", 3} , {"range", {0, 1}}});
28 | chart.ScaleObject("value", {{"nice", true}});
29 | chart.Interval().Position("date*value");
30 | chart.Render();
31 | return true;
32 | }
33 | };
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/tests/e2e/Baseline.h:
--------------------------------------------------------------------------------
1 | //
2 | // Baseline.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2022/1/18.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include "../../core/graphics/XChart.h"
12 |
13 | using namespace xg;
14 |
15 | namespace e2e {
16 |
17 | class Baseline {
18 | public:
19 |
20 | //基础的线图
21 | static bool Case1(float width, float height,float ratio, const std::string &path, void *context) {
22 | XChart chart("Baseline#Test", width, height, ratio);
23 | std::ifstream jsonFile(path);
24 | std::string jsonData((std::istreambuf_iterator(jsonFile)), std::istreambuf_iterator());
25 | chart.Source(jsonData);
26 | chart.SetCanvasContext(context).Padding(20, 10, 20, 0);
27 | chart.Scale("date", "{\"tickCount\": 3}");
28 | chart.Scale("value", "{\"nice\": true}");
29 | chart.Line().Position("date*value");
30 | chart.Render();
31 | return true;
32 | }
33 | };
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/tests/e2e/F2PixelMatch.h:
--------------------------------------------------------------------------------
1 | //
2 | // PixelMatch.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2022/1/13.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface F2PixelMatch : NSObject
14 |
15 | +(bool)match:(UIImage *)image1 image2:(UIImage *)image2 outImage:(UIImage **)outImage;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/tests/e2e/MarketMoving.h:
--------------------------------------------------------------------------------
1 | //
2 | // BaseInterval.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2022/1/18.
6 | // Copyright © 2022 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include "../../core/graphics/XChart.h"
12 |
13 | using namespace xg;
14 |
15 | namespace e2e {
16 |
17 | class MarketMoving {
18 | public:
19 |
20 | //基础的线图
21 | static bool Case1(float width, float height,float ratio, const std::string &path, void *context) {
22 | XChart chart("Baseline#Test", width, height, ratio);
23 | std::ifstream jsonFile(path);
24 | std::string jsonData((std::istreambuf_iterator(jsonFile)), std::istreambuf_iterator());
25 | chart.SetCanvasContext(context).Padding(20, 10, 20, 0);
26 | chart.Parse(jsonData);
27 | chart.Render();
28 | return true;
29 | }
30 | };
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/tests/res/badcase.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/badcase.jpg
--------------------------------------------------------------------------------
/tests/res/black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/black.png
--------------------------------------------------------------------------------
/tests/res/e2e/baseInterval.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/e2e/baseInterval.jpeg
--------------------------------------------------------------------------------
/tests/res/e2e/baseLine.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/e2e/baseLine.jpeg
--------------------------------------------------------------------------------
/tests/res/e2e/chartBridge.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/e2e/chartBridge.jpeg
--------------------------------------------------------------------------------
/tests/res/e2e/marketMoving.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/e2e/marketMoving.jpeg
--------------------------------------------------------------------------------
/tests/res/mockData_baseInterval.json:
--------------------------------------------------------------------------------
1 | [{
2 | "year": "1951 年\n第一季度",
3 | "sales": 38
4 | }, {
5 | "year": "1952 年\n第一季度",
6 | "sales": 52
7 | }, {
8 | "year": "1956 年\n第一季度",
9 | "sales": 61
10 | }, {
11 | "year": "1957 年\n第一季度",
12 | "sales": 145
13 | }, {
14 | "year": "1958 年\n第一季度",
15 | "sales": 48
16 | }, {
17 | "year": "1959 年\n第一季度",
18 | "sales": 38
19 | }, {
20 | "year": "1960 年\n第一季度",
21 | "sales": 38
22 | }, {
23 | "year": "1962 年\n第一季度",
24 | "sales": 38
25 | }]
26 |
--------------------------------------------------------------------------------
/tests/res/red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/red.png
--------------------------------------------------------------------------------
/tests/res/transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/transparent.png
--------------------------------------------------------------------------------
/tests/res/white&black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/white&black.png
--------------------------------------------------------------------------------
/tests/res/white&red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/white&red.png
--------------------------------------------------------------------------------
/tests/res/white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antvis/F2Native/b1f3f4e81721f68cd13d4a872ecf48e2bc99e88b/tests/res/white.png
--------------------------------------------------------------------------------
/tests/run.sh:
--------------------------------------------------------------------------------
1 | rm -rf build
2 | mkdir build && cd build
3 | cmake ..
4 | make
5 |
--------------------------------------------------------------------------------
/tests/unit/utils/Point.h:
--------------------------------------------------------------------------------
1 | //
2 | // Point.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2021/11/18.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 | #include "../../../core/graphics/util/Point.h"
10 |
11 | using namespace xg;
12 | using namespace std;
13 |
14 | namespace unit {
15 |
16 | class PointTest {
17 | public:
18 | static bool Reset() {
19 | auto point = util::Point(0, 0);
20 | point.Reset(1, 2);
21 | return point.x == 1 && point.y == 2;
22 | }
23 |
24 | static bool Max() {
25 | return true;
26 | }
27 |
28 | static bool Min() {
29 | return true;
30 | }
31 |
32 | static bool Add() {
33 | return true;
34 | }
35 |
36 | static bool Sub() {
37 | return true;
38 | }
39 |
40 | static bool Scale() {
41 | return true;
42 | }
43 |
44 | static bool Distance() {
45 | return true;
46 | }
47 |
48 | };
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/tests/unit/utils/StringUtils.h:
--------------------------------------------------------------------------------
1 | #include "../../../core/utils/StringUtil.h"
2 |
3 | namespace unit {
4 |
5 | class StringUtils {
6 | public:
7 | static bool SplitFields1() {
8 | std::vector rst;
9 | StringUtil::Split("x*y", rst, '*');
10 | return (2 == rst.size()) && ("x" == rst[0]) && ("y"== rst[1]);
11 | }
12 |
13 | static bool SplitFields2() {
14 | std::vector rst;
15 | StringUtil::Split("color", rst, '*');
16 | return (1 == rst.size()) && ("color"== rst[0]);
17 | };
18 |
19 | static bool SplitDay() {
20 | std::vector rst;
21 | StringUtil::Split("kline-day", rst, '-');
22 | return (2 == rst.size()) && ("kline" == rst[0]) && ("day"== rst[1]);
23 | };
24 |
25 | static bool SplitMinutes() {
26 | std::vector rst;
27 | StringUtil::Split("kline-minutes-5", rst, '-');
28 | int minutes = std::stoi(rst[2]);
29 | return (3 == rst.size()) && ("kline" == rst[0]) && ("minutes" == rst[1]) && (5 == minutes);
30 | };
31 |
32 | };
33 |
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/tests/unit/utils/Vector2d.h:
--------------------------------------------------------------------------------
1 | //
2 | // Vector2d.h
3 | // F2Tests
4 | //
5 | // Created by weiqing.twq on 2021/11/18.
6 | // Copyright © 2021 com.alipay.xgraph. All rights reserved.
7 | //
8 |
9 |
--------------------------------------------------------------------------------