diff --git a/src/ChartJs-Core-Tests/Chart1dDataTest.class.st b/src/ChartJs-Core-Tests/Chart1dDataTest.class.st deleted file mode 100644 index 73f0fe1..0000000 --- a/src/ChartJs-Core-Tests/Chart1dDataTest.class.st +++ /dev/null @@ -1,30 +0,0 @@ -" -A Chart1dDataTest is a test class for testing the behavior of Chart1dData -" -Class { - #name : #Chart1dDataTest, - #superclass : #ChartDataAbstractTest, - #category : #'ChartJs-Core-Tests' -} - -{ #category : #helpers } -Chart1dDataTest >> actualClass [ - ^ Chart1dData -] - -{ #category : #tests } -Chart1dDataTest >> testHasData [ - | datas | - datas := self actualClass - values: - {('Eating' -> 80). - ('Drinking' -> 100). - ('Sleeping' -> 70). - ('Designing' -> 50). - ('Coding' -> 40). - ('Cycling' -> 10). - ('Running' -> 25)}. - self assert: datas hasData. - datas := self actualClass values: {}. - self deny: datas hasData -] diff --git a/src/ChartJs-Core-Tests/Chart2dDataTest.class.st b/src/ChartJs-Core-Tests/ChartDataTest.class.st similarity index 83% rename from src/ChartJs-Core-Tests/Chart2dDataTest.class.st rename to src/ChartJs-Core-Tests/ChartDataTest.class.st index 9133e2a..67032aa 100644 --- a/src/ChartJs-Core-Tests/Chart2dDataTest.class.st +++ b/src/ChartJs-Core-Tests/ChartDataTest.class.st @@ -2,18 +2,18 @@ A Chart2dDataTest is a test class for testing the behavior of Chart2dData " Class { - #name : #Chart2dDataTest, + #name : #ChartDataTest, #superclass : #ChartDataAbstractTest, #category : #'ChartJs-Core-Tests' } { #category : #helpers } -Chart2dDataTest >> actualClass [ - ^ Chart2dData +ChartDataTest >> actualClass [ + ^ ChartData ] { #category : #tests } -Chart2dDataTest >> testHasData [ +ChartDataTest >> testHasData [ | datas | datas := self actualClass xObjects: {'Eating' . 'Drinking' . 'Sleeping' . 'Designing' . 'Coding' . 'Cycling' . 'Running'} diff --git a/src/ChartJs-Core-Tests/ChartTypeTest.class.st b/src/ChartJs-Core-Tests/ChartTypeTest.class.st new file mode 100644 index 0000000..741540a --- /dev/null +++ b/src/ChartJs-Core-Tests/ChartTypeTest.class.st @@ -0,0 +1,40 @@ +Class { + #name : #ChartTypeTest, + #superclass : #TestCase, + #category : #'ChartJs-Core-Tests' +} + +{ #category : #tests } +ChartTypeTest >> testNeoJsonOnData [ + | json chart stream colorConst | + chart := ChartData + xObjects: {'Eating' . 'Drinking'} + multiYObjects: {('Cyril' -> #(28 48))}. + chart dataSets + do: [ :ds | + ds styleSheet pointHoverBackgroundColor: Color red. + ds styleSheet pointBackgroundColor: Color red. + ds styleSheet fillColor: Color red. + ds styleSheet borderColor: Color red. + ds styleSheet pointHoverBorderColor: Color red. + ds styleSheet pointBorderColor: Color red. + ds styleSheet backgroundColor: Color red ]. + stream := '' writeStream. + json := (NeoJSONWriter on: stream) nextPut: chart. + colorConst := '"fill":false,"pointBackgroundColor":"rgba(255,0,0,1.0)","pointBorderColor":"rgba(255,0,0,1.0)","borderColor":"rgba(255,0,0,1.0)","pointHoverBorderColor":"rgba(255,0,0,1.0)","backgroundColor":"rgba(255,0,0,1.0)"'. + self + assert: stream contents + equals: + '{"labels":["Eating","Drinking"],"datasets":[{' , colorConst + , ',"label":"Cyril","data":[28,48]}]}' +] + +{ #category : #tests } +ChartTypeTest >> testNeoJsonOnOnlyType [ + | json chart stream | + chart := ChartBar new. + stream := '' writeStream. + json := (NeoJSONWriter on: stream) nextPut: chart. + + self assert: stream contents equals: '{"type":"bar"}' +] diff --git a/src/ChartJs-Core/Boolean.extension.st b/src/ChartJs-Core/Boolean.extension.st new file mode 100644 index 0000000..2f6fc7b --- /dev/null +++ b/src/ChartJs-Core/Boolean.extension.st @@ -0,0 +1,6 @@ +Extension { #name : #Boolean } + +{ #category : #'*ChartJs-Core' } +Boolean >> forChartJs [ + +] diff --git a/src/ChartJs-Core/Chart1dData.class.st b/src/ChartJs-Core/Chart1dData.class.st deleted file mode 100644 index 94b289f..0000000 --- a/src/ChartJs-Core/Chart1dData.class.st +++ /dev/null @@ -1,86 +0,0 @@ -" -I am a one dimension representation of data for graph like Pie, Donut and Polar that present values with label. -" -Class { - #name : #Chart1dData, - #superclass : #ChartDataAbstract, - #instVars : [ - 'datas' - ], - #category : #'ChartJs-Core-Model' -} - -{ #category : #'instance-creation' } -Chart1dData class >> dictionary: aDictionary [ - ^ self values: aDictionary associations -] - -{ #category : #'instance-creation' } -Chart1dData class >> dictionary: aDictionary valueDisplayBlock: aBlockOrSymbol [ - ^ (self dictionary: aDictionary) - valueDisplayBlock: aBlockOrSymbol; - yourself -] - -{ #category : #'instance-creation' } -Chart1dData class >> values: aCollectionOfAssociations [ - ^ self new - datas: (aCollectionOfAssociations collect: [ :asso | ChartDataValue value: asso value name: asso key ]); - yourself -] - -{ #category : #'instance-creation' } -Chart1dData class >> values: aCollectionOfAssociations valueDisplayBlock: aBlockOrSymbol [ - ^ (self values: aCollectionOfAssociations) - valueDisplayBlock: aBlockOrSymbol; - yourself -] - -{ #category : #callback } -Chart1dData >> at: anInteger ifPresent: aBlockClosure [ - ^ aBlockClosure value: (self datas at: anInteger) name -> (self datas at: anInteger) value -] - -{ #category : #chartType } -Chart1dData >> chartType: aChartType [ - self assert: aChartType isFor1DValues description: 'Chart accepted: Donut, Pie and Polar'. - super chartType: aChartType -] - -{ #category : #accessing } -Chart1dData >> datas [ - ^ datas -] - -{ #category : #accessing } -Chart1dData >> datas: anObject [ - datas := anObject asArray -] - -{ #category : #testing } -Chart1dData >> hasData [ - ^ self datas isNotEmpty -] - -{ #category : #testing } -Chart1dData >> hasLegend [ - ^ true -] - -{ #category : #initialization } -Chart1dData >> initialize [ - super initialize. - self chartType: ChartPie -] - -{ #category : #ChartJs } -Chart1dData >> neoJsonOn: writer [ - writer writeListStreamingDo: [ :jsonListWriter | - self datas do: [ :each | each forChartJS: writer displayBlock: self valueDisplayBlock] separatedBy: [ writer listElementSeparator ] ] -] - -{ #category : #accessing } -Chart1dData >> title [ - - ^ title isBlock ifTrue: [ title value: self datas ] ifFalse: [ title ] -] diff --git a/src/ChartJs-Core/Chart2dData.class.st b/src/ChartJs-Core/Chart2dData.class.st deleted file mode 100644 index 85cf950..0000000 --- a/src/ChartJs-Core/Chart2dData.class.st +++ /dev/null @@ -1,154 +0,0 @@ -" -I am a chartData that you can provide to any graph. I have a list of xPoints to present and a collection of CharDataSets that defines positions for this xPoints. - -I will be used for line, bar, radar and boxplot graph -" -Class { - #name : #Chart2dData, - #superclass : #ChartDataAbstract, - #instVars : [ - 'xObjects', - 'dataSets', - 'keyDisplayBlock' - ], - #category : #'ChartJs-Core-Model' -} - -{ #category : #'instance-creation' } -Chart2dData class >> xObjects: aCollectionOfObjects function: aBlock [ - ^ self new - xObjects: aCollectionOfObjects; - dataSets: {(ChartDataSetFunction function: aBlock)}; - yourself -] - -{ #category : #'instance creation' } -Chart2dData class >> xObjects: aCollectionOfObjects function: aBlockClosure color: aColor [ - ^ self new - xObjects: aCollectionOfObjects; - dataSets: {(ChartDataSetFunction function: aBlockClosure color: aColor)}; - yourself -] - -{ #category : #'instance-creation' } -Chart2dData class >> xObjects: aCollectionOfObjects multiYObjects: aCollectionOfSequenceableCollectionOfObjectsToMap [ - ^ self new - xObjects: aCollectionOfObjects; - dataSets: - (aCollectionOfSequenceableCollectionOfObjectsToMap - collect: [ :anAssociation | ChartDataSetSequence name: anAssociation key sequence: anAssociation value ]); - yourself -] - -{ #category : #'instance-creation' } -Chart2dData class >> xObjects: aCollectionOfObjects yObjects: aSequenceableCollectionOfObjectsToMap [ - ^ self new - xObjects: aCollectionOfObjects; - dataSets: {(ChartDataSetSequence sequence: aSequenceableCollectionOfObjectsToMap)}; - yourself -] - -{ #category : #'as yet unclassified' } -Chart2dData >> addFunction: aFunctionBlock color: aColor [ - self dataSets addLast: (ChartDataSetFunction function: aFunctionBlock color: aColor) -] - -{ #category : #callback } -Chart2dData >> at: anIndex ifPresent: aBlockClosure [ - ^ aBlockClosure - value: (self xObjects at: anIndex) -> (self dataSets first atIndex: anIndex forValue: (self xObjects at: anIndex)) -] - -{ #category : #exchange } -Chart2dData >> callBackValues [ - ^ self dataSets first sequence -] - -{ #category : #chartType } -Chart2dData >> chartType: aChartType [ - self assert: aChartType isMultiDataSet description: 'Chart accepted: Bar, Line, BoxPlot and Radar'. - super chartType: aChartType -] - -{ #category : #accessing } -Chart2dData >> dataSets [ - ^ dataSets -] - -{ #category : #accessing } -Chart2dData >> dataSets: anObject [ - dataSets := anObject asOrderedCollection -] - -{ #category : #colors } -Chart2dData >> dataSetsColors: aCollectionOfColors [ - self - assert: aCollectionOfColors size = self dataSets size - description: 'The provided collection of colors must have one color per dataset'. - self dataSets doWithIndex: [ :aDataSet :anIndex | aDataSet color: (aCollectionOfColors at: anIndex) ] -] - -{ #category : #presentation } -Chart2dData >> displayKeysAsPercent [ - self keyDisplayBlock: [ :percent | (percent * 100) rounded asString, '%' ] -] - -{ #category : #testing } -Chart2dData >> hasData [ - ^ self xObjects isNotEmpty -] - -{ #category : #testing } -Chart2dData >> hasLegend [ - ^ self dataSets anySatisfy: #hasName -] - -{ #category : #initialization } -Chart2dData >> initialize [ - super initialize. - self chartType: ChartLine -] - -{ #category : #accessing } -Chart2dData >> keyDisplayBlock [ - ^ keyDisplayBlock ifNil: [ #yourself ] -] - -{ #category : #accessing } -Chart2dData >> keyDisplayBlock: anObject [ - keyDisplayBlock := anObject -] - -{ #category : #presentation } -Chart2dData >> labelFor: aString [ - ^ (self keyDisplayBlock value: aString) -] - -{ #category : #exchange } -Chart2dData >> neoJsonOn: writer [ - writer - writeMapStreamingDo: [ :jsonMapWriter | - jsonMapWriter writeKey: #labels value: (xObjects collect: [ :aXObject | self labelFor: aXObject ]). - self chartType isMultiDataSet - ifTrue: [ - jsonMapWriter - writeKey: #datasets - value: (self dataSets collect: [ :aDataSet | aDataSet neoJsonObjectFor: self xObjects block: self valueDisplayBlock ]) ] - ifFalse: [ self error: 'Not supported graph type' ] ] -] - -{ #category : #accessing } -Chart2dData >> title [ - - ^ title isBlock ifTrue: [ title value: self dataSets ] ifFalse: [ title ] -] - -{ #category : #accessing } -Chart2dData >> xObjects [ - ^ xObjects -] - -{ #category : #accessing } -Chart2dData >> xObjects: anObject [ - xObjects := anObject -] diff --git a/src/ChartJs-Core/ChartBar.class.st b/src/ChartJs-Core/ChartBar.class.st index fda7d81..bf5ce9b 100644 --- a/src/ChartJs-Core/ChartBar.class.st +++ b/src/ChartJs-Core/ChartBar.class.st @@ -12,14 +12,9 @@ ChartBar class >> dataFunction [ ^ 'bars' ] -{ #category : #ChartJs } -ChartBar class >> eventsCode [ - ^ 'getBarsAtEvent(evt)' -] - { #category : #ChartJs } ChartBar class >> forChartJS [ - ^ 'Bar' + ^ 'bar' ] { #category : #testing } diff --git a/src/ChartJs-Core/ChartBoxPlot.class.st b/src/ChartJs-Core/ChartBoxPlot.class.st index 8ca95b6..179acdc 100644 --- a/src/ChartJs-Core/ChartBoxPlot.class.st +++ b/src/ChartJs-Core/ChartBoxPlot.class.st @@ -12,14 +12,9 @@ ChartBoxPlot class >> dataFunction [ ^ 'bars' ] -{ #category : #ChartJs } -ChartBoxPlot class >> eventsCode [ - ^ 'getBarsAtEvent(evt)' -] - { #category : #ChartJs } ChartBoxPlot class >> forChartJS [ - ^ 'BoxPlot' + ^ 'boxplot' ] { #category : #testing } diff --git a/src/ChartJs-Core/ChartData.class.st b/src/ChartJs-Core/ChartData.class.st new file mode 100644 index 0000000..1abd2a1 --- /dev/null +++ b/src/ChartJs-Core/ChartData.class.st @@ -0,0 +1,208 @@ +" +I am the abstract class for chart data; defining the charttype to represent me, title and style +" +Class { + #name : #ChartData, + #superclass : #Object, + #instVars : [ + 'styleSheet', + 'title', + 'valueDisplayBlock', + 'singleValueTooltip', + 'multiValueTooltip', + 'xObjects', + 'dataSets', + 'keyDisplayBlock', + 'colors' + ], + #category : #'ChartJs-Core-Model' +} + +{ #category : #'instance-creation' } +ChartData class >> xObjects: aCollectionOfObjects function: aBlock [ + ^ self new + xObjects: aCollectionOfObjects; + dataSets: {(ChartDataSetFunction function: aBlock)}; + yourself +] + +{ #category : #'instance-creation' } +ChartData class >> xObjects: aCollectionOfObjects function: aBlockClosure color: aColor [ + ^ self new + xObjects: aCollectionOfObjects; + dataSets: {(ChartDataSetFunction function: aBlockClosure color: aColor)}; + yourself +] + +{ #category : #'instance-creation' } +ChartData class >> xObjects: aCollectionOfObjects multiYObjects: aCollectionOfSequenceableCollectionOfObjectsToMap [ + ^ self new + xObjects: aCollectionOfObjects; + dataSets: + (aCollectionOfSequenceableCollectionOfObjectsToMap + collect: [ :anAssociation | ChartDataSetSequence name: anAssociation key sequence: anAssociation value ]); + yourself +] + +{ #category : #'instance-creation' } +ChartData class >> xObjects: aCollectionOfObjects yObjects: aSequenceableCollectionOfObjectsToMap [ + ^ self new + xObjects: aCollectionOfObjects; + dataSets: {(ChartDataSetSequence sequence: aSequenceableCollectionOfObjectsToMap)}; + yourself +] + +{ #category : #tooltip } +ChartData >> adaptToolTip: aToolTipString [ + ^ (Array with: '