Skip to content

Commit 1e13d6a

Browse files
committed
Fix #260 => Add AANull type for marker lineColor null support
Introduces the AANull class to represent JavaScript null values in chart options. Updates AAMarker to allow setting lineColor to AANull, which is converted to null in AAChartView.js. Refactors AAChartView to use a centralized Gson instance for serialization. Adds a new CustomStyleChartComposer2 example demonstrating usage of AANull for marker lineColor. Minor update in MainActivity to use new chart navigation.
1 parent cfdf3cd commit 1e13d6a

File tree

7 files changed

+186
-20
lines changed

7 files changed

+186
-20
lines changed

charts/src/main/assets/AAChartView.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ function loadTheHighChartView (sender,receivedWidth, receivedHeight) {
77
&& value.indexOf('function') != -1) {
88
return eval(value)
99
}
10+
11+
//判断 key 如果是 lineColor , 并且 value 为 "AANull", 则将其转换为 null
12+
if (key === 'lineColor' && value === 'AANull') {
13+
return null;
14+
}
1015
return value;
1116
});
1217

charts/src/main/java/com/github/aachartmodel/aainfographics/aachartcreator/AAChartView.kt

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAPointEvents
5151
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AASeries
5252
import com.github.aachartmodel.aainfographics.aatools.AAColor
5353
import com.github.aachartmodel.aainfographics.aatools.AAJSStringPurer
54+
//import com.github.aachartmodel.aainfographics.aatools.AANull
55+
//import com.github.aachartmodel.aainfographics.aatools.AANullAdapter
56+
//import com.github.aachartmodel.aainfographics.aatools.AANullObjectAdapter
5457
import com.github.aachartmodel.aainfographics.aatools.aa_toJSArray
5558
import com.google.gson.Gson
59+
import com.google.gson.GsonBuilder
5660
import com.google.gson.internal.LinkedTreeMap
5761
import java.util.Locale
5862

@@ -126,6 +130,15 @@ class AAChartView : WebView {
126130

127131
private var optionsJson: String? = null
128132

133+
// Centralized Gson configured to handle AANull and keep null fields
134+
private val aaGson: Gson by lazy {
135+
GsonBuilder()
136+
// .registerTypeAdapter(String::class.java, AANullAdapter())
137+
// .registerTypeAdapter(AANull::class.java, AANullObjectAdapter())
138+
// .serializeNulls()
139+
.create()
140+
}
141+
129142
constructor(
130143
context: Context
131144
) : super(context) {
@@ -213,7 +226,7 @@ class AAChartView : WebView {
213226
seriesElementsArr: Array<AASeriesElement>,
214227
animation: Boolean
215228
) {
216-
val seriesArr = Gson().toJson(seriesElementsArr)
229+
val seriesArr = aaGson.toJson(seriesElementsArr)
217230
val javaScriptStr = "onlyRefreshTheChartDataWithSeries('$seriesArr','$animation')"
218231
safeEvaluateJavaScriptString(javaScriptStr)
219232
}
@@ -225,7 +238,7 @@ class AAChartView : WebView {
225238
val isAAOptionsClass = options is AAOptions
226239
val finalOptionsMapStr: String
227240
if (isAAOptionsClass) {
228-
val aaOptionsMapStr = Gson().toJson(options)
241+
val aaOptionsMapStr = aaGson.toJson(options)
229242
finalOptionsMapStr = aaOptionsMapStr
230243
} else {
231244
var classNameStr = options.javaClass.simpleName
@@ -238,7 +251,7 @@ class AAChartView : WebView {
238251
val finalClassName = lowercaseFirstStr + classNameStr
239252
val finalOptionsMap = HashMap<String, Any>()
240253
finalOptionsMap[finalClassName] = options
241-
val optionsStr = Gson().toJson(finalOptionsMap)
254+
val optionsStr = aaGson.toJson(finalOptionsMap)
242255
finalOptionsMapStr = optionsStr
243256
}
244257
val javaScriptStr = "updateChart('$finalOptionsMapStr','$redraw')"
@@ -275,7 +288,7 @@ class AAChartView : WebView {
275288
) {
276289
options.toString()
277290
} else {
278-
Gson().toJson(options)
291+
aaGson.toJson(options)
279292
}
280293
val javaScriptStr = "addPointToChartSeries('$elementIndex','$optionsStr','$redraw','$shift','$animation')"
281294
safeEvaluateJavaScriptString(javaScriptStr)
@@ -292,7 +305,7 @@ class AAChartView : WebView {
292305
}
293306

294307
fun aa_addElementToChartSeries(aaSeriesElement: AASeriesElement) {
295-
val pureElementJsonStr = Gson().toJson(aaSeriesElement)
308+
val pureElementJsonStr = aaGson.toJson(aaSeriesElement)
296309
val javaScriptStr = "addElementToChartSeriesWithElement('$pureElementJsonStr')"
297310
safeEvaluateJavaScriptString(javaScriptStr)
298311
}
@@ -367,20 +380,21 @@ class AAChartView : WebView {
367380
}
368381

369382
private fun configureChartOptionsAndDrawChart(aaOptions: AAOptions) {
370-
if (isClearBackgroundColor == true) {
371-
aaOptions.chart?.backgroundColor(AAColor.Clear)
372-
}
383+
if (isClearBackgroundColor == true) {
384+
aaOptions.chart?.backgroundColor(AAColor.Clear)
385+
}
373386

374-
val isAnyEventEnabled = aaOptions.clickEventEnabled == true || aaOptions.touchEventEnabled == true
387+
val isAnyEventEnabled = aaOptions.clickEventEnabled == true || aaOptions.touchEventEnabled == true
375388

376-
if (isAnyEventEnabled) {
377-
configurePlotOptionsSeriesPointEvents(aaOptions)
378-
}
389+
if (isAnyEventEnabled) {
390+
configurePlotOptionsSeriesPointEvents(aaOptions)
391+
}
379392

380-
optionsJson = Gson().toJson(aaOptions)
381-
val javaScriptStr = "loadTheHighChartView('$optionsJson','$contentWidth','$contentHeight')"
382-
safeEvaluateJavaScriptString(javaScriptStr)
383-
}
393+
// Use centralized Gson for options serialization
394+
optionsJson = aaGson.toJson(aaOptions)
395+
val javaScriptStr = "loadTheHighChartView('$optionsJson','$contentWidth','$contentHeight')"
396+
safeEvaluateJavaScriptString(javaScriptStr)
397+
}
384398

385399
private fun showJavaScriptAlertView() {
386400
webChromeClient = object : WebChromeClient() {
@@ -434,5 +448,3 @@ class AAChartView : WebView {
434448
}
435449
}
436450
}
437-
438-

charts/src/main/java/com/github/aachartmodel/aainfographics/aaoptionsmodel/AAMarker.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99
package com.github.aachartmodel.aainfographics.aaoptionsmodel
1010

11+
import com.github.aachartmodel.aainfographics.aatools.AANull
12+
1113
open class AAMarker {
1214
var enabled: Boolean? = null
1315
var radius: Number? = null
@@ -43,6 +45,12 @@ open class AAMarker {
4345
}
4446

4547
fun lineColor(prop: Any?): AAMarker {
48+
//如果传入的参数是自定义的 AANull 类型, 则将 lineColor 设为 "AANull"
49+
if (prop is AANull) {
50+
lineColor = "AANull"
51+
return this
52+
}
53+
4654
lineColor = prop
4755
return this
4856
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.github.aachartmodel.aainfographics.aatools
2+
3+
import com.google.gson.TypeAdapter
4+
import com.google.gson.annotations.JsonAdapter
5+
import com.google.gson.stream.JsonReader
6+
import com.google.gson.stream.JsonToken
7+
import com.google.gson.stream.JsonWriter
8+
9+
//// 实现 Javascript 中的 null 值的效果
10+
//@JsonAdapter(AANullObjectAdapter::class)
11+
class AANull {
12+
}
13+
//
14+
//// Adapter used for String properties: when the literal string "AANull" is encountered, output real JSON null
15+
//class AANullAdapter : TypeAdapter<String>() {
16+
// override fun write(out: JsonWriter, value: String?) {
17+
// if (value == "AANull") {
18+
// out.nullValue() // 输出真正的 null
19+
// } else {
20+
// out.value(value)
21+
// }
22+
// }
23+
//
24+
// override fun read(reader: JsonReader): String? {
25+
// return if (reader.peek() == JsonToken.NULL) {
26+
// reader.nextNull()
27+
// null
28+
// } else {
29+
// val result = reader.nextString()
30+
// if (result == "AANull") null else result
31+
// }
32+
// }
33+
//}
34+
//
35+
//// Adapter used for AANull object properties: serialize any AANull instance as JSON null
36+
//class AANullObjectAdapter : TypeAdapter<AANull>() {
37+
// override fun write(out: JsonWriter, value: AANull?) {
38+
// out.nullValue()
39+
// }
40+
//
41+
// override fun read(reader: JsonReader): AANull? {
42+
// if (reader.peek() == JsonToken.NULL) {
43+
// reader.nextNull()
44+
// } else {
45+
// // Consume any unexpected token to keep the stream consistent
46+
// reader.skipValue()
47+
// }
48+
// return null
49+
// }
50+
//}

sample/src/main/java/com/github/aachartmodel/aainfographics/demo/basiccontent/CustomStyleChartActivity.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import com.github.aachartmodel.aainfographics.aachartcreator.AAChartModel
3434
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartView
3535
import com.github.aachartmodel.aainfographics.demo.R
3636
import com.github.aachartmodel.aainfographics.demo.chartcomposer.CustomStyleChartComposer
37+
import com.github.aachartmodel.aainfographics.demo.chartcomposer.CustomStyleChartComposer2
3738

3839
class CustomStyleChartActivity : AppCompatActivity() {
3940

@@ -137,6 +138,8 @@ class CustomStyleChartActivity : AppCompatActivity() {
137138
return CustomStyleChartComposer.customAreasplineChartWithColorfulGradientColorZones()
138139

139140

141+
"colorfulMarkerWithZonesChart" ->
142+
return CustomStyleChartComposer2.colorfulMarkerWithZonesChart()
140143
}
141144
return CustomStyleChartComposer.configureColorfulChart()
142145
}

sample/src/main/java/com/github/aachartmodel/aainfographics/demo/basiccontent/MainActivity.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ class MainActivity : AppCompatActivity() {
313313
"connectNullsForSingleAASeriesElement",
314314
"lineChartsWithLargeDifferencesInTheNumberOfDataInDifferentSeriesElement",
315315
"customAreasplineChartWithColorfulGradientColorZones",
316+
317+
"colorfulMarkerWithZonesChart"
316318
), arrayOf( /*使用AAOptions绘制图表*/
317319
"customLegendStyle",
318320
"AAPlotBandsForChart",
@@ -546,8 +548,10 @@ class MainActivity : AppCompatActivity() {
546548
startActivity(intent)
547549
}
548550
3 -> {
549-
val intent = Intent(this, CustomStyleChartListActivity::class.java)
550-
startActivity(intent)
551+
// val intent = Intent(this, CustomStyleChartListActivity::class.java)
552+
// startActivity(intent)
553+
goToCustomStyleChartActivity(chartType)
554+
551555
}
552556
4 -> goToDrawChartWithAAOptionsActivity(chartType)
553557
5 -> goToOnlyRefreshChartDataActivity(chartType)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.github.aachartmodel.aainfographics.demo.chartcomposer
2+
3+
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartLineDashStyleType
4+
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartModel
5+
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartSymbolStyleType
6+
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartSymbolType
7+
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartType
8+
import com.github.aachartmodel.aainfographics.aachartcreator.AASeriesElement
9+
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAMarker
10+
import com.github.aachartmodel.aainfographics.aaoptionsmodel.AAZonesElement
11+
import com.github.aachartmodel.aainfographics.aatools.AANull
12+
import kotlin.math.sin
13+
14+
object CustomStyleChartComposer2 {
15+
fun colorfulMarkerWithZonesChart(): AAChartModel {
16+
// 生成平滑波浪数据
17+
fun generateWaveData(amplitude: Double, phase: Double, step: Double, count: Int, noise: Double = 0.0): Array<Any> {
18+
val data = mutableListOf<Double>()
19+
for (i in 0 until count) {
20+
val y = amplitude * sin((i * step) + phase) + 120
21+
val noisyY = y + (Math.random() - 0.5) * noise
22+
data.add(String.format("%.2f", noisyY).toDouble())
23+
}
24+
return data.toTypedArray()
25+
}
26+
27+
// 色系分区
28+
val zones = arrayOf(
29+
AAZonesElement().apply {
30+
value(80.0)
31+
color("#25547c")
32+
},
33+
AAZonesElement().apply {
34+
value(110.0)
35+
color("#1e90ff")
36+
},
37+
AAZonesElement().apply {
38+
value(140.0)
39+
color("#ffd066")
40+
},
41+
AAZonesElement().apply {
42+
value(170.0)
43+
color("#04d69f")
44+
},
45+
AAZonesElement().apply {
46+
color("#ef476f")
47+
}
48+
)
49+
50+
return AAChartModel().apply {
51+
chartType(AAChartType.Scatter)
52+
title("⚡️高饱和度波浪图 — 实心与空心 Marker 对比")
53+
legendEnabled(true)
54+
tooltipEnabled(true)
55+
series(arrayOf(
56+
AASeriesElement().apply {
57+
name("实心数据")
58+
data(generateWaveData(85.0, 0.0, 0.25, 60, 4.0))
59+
zones(zones)
60+
zoneAxis("y")
61+
marker(AAMarker().apply {
62+
symbol(AAChartSymbolType.Circle.value)
63+
radius(6)
64+
lineWidth(1)
65+
})
66+
},
67+
AASeriesElement().apply {
68+
name("空心数据")
69+
data(generateWaveData(85.0, Math.PI / 2, 0.25, 60, 4.0))
70+
zones(zones)
71+
zoneAxis("y")
72+
marker(AAMarker().apply {
73+
symbol(AAChartSymbolType.Diamond.value)
74+
fillColor("transparent")
75+
lineColor(AANull())
76+
radius(7)
77+
lineWidth(2)
78+
})
79+
dashStyle(AAChartLineDashStyleType.DashDot)
80+
}
81+
))
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)